Index: jpa/eclipselink.jpa.test/build.xml =================================================================== --- jpa/eclipselink.jpa.test/build.xml (revision 7828) +++ jpa/eclipselink.jpa.test/build.xml (working copy) @@ -501,7 +501,7 @@ - + @@ -757,10 +757,10 @@ - + + - @@ -1498,18 +1498,18 @@ - - + + - + - - + + + - + - - - + + + - + - + @@ -1766,7 +1766,7 @@ - + @@ -1778,7 +1778,7 @@ - + @@ -1858,8 +1858,6 @@ - - @@ -1951,7 +1949,9 @@ + + @@ -2088,6 +2088,19 @@ + + + + + + + + + + + + + @@ -2101,6 +2114,19 @@ + + + + + + + + + + + + + @@ -2313,9 +2339,9 @@ - - - + + + @@ -2323,7 +2349,7 @@ - + Index: jpa/eclipselink.jpa.test/resource/eclipselink-advanced-field-access-model/server/persistence.xml =================================================================== --- jpa/eclipselink.jpa.test/resource/eclipselink-advanced-field-access-model/server/persistence.xml (revision 7828) +++ jpa/eclipselink.jpa.test/resource/eclipselink-advanced-field-access-model/server/persistence.xml (working copy) @@ -12,6 +12,7 @@ + Index: jpa/eclipselink.jpa.test/resource/server/persistence.xml =================================================================== --- jpa/eclipselink.jpa.test/resource/server/persistence.xml (revision 7828) +++ jpa/eclipselink.jpa.test/resource/server/persistence.xml (working copy) @@ -8,6 +8,7 @@ + Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/AdvancedServerTestSuite.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/AdvancedServerTestSuite.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/AdvancedServerTestSuite.java (working copy) @@ -13,6 +13,7 @@ package org.eclipse.persistence.testing.tests.jpa.advanced; import org.eclipse.persistence.testing.tests.jpa.advanced.compositepk.AdvancedCompositePKJunitTest; +import org.eclipse.persistence.testing.tests.jpa.advanced.fetchgroup.AdvancedFetchGroupJunitTest; import org.eclipse.persistence.testing.framework.junit.JUnitTestCase; import junit.framework.TestSuite; @@ -40,6 +41,9 @@ suite.addTest(AdvancedJunitTest.suite()); suite.addTest(AdvancedCompositePKJunitTest.suite()); suite.addTest(QueryCastTestSuite.suite()); + if (! JUnitTestCase.isJPA10()) { + suite.addTest(AdvancedFetchGroupJunitTest.suite()); + } return suite; } } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/BaseFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/BaseFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/BaseFetchGroupTests.java (working copy) @@ -72,11 +72,11 @@ /* * Fetch Group tests require weaving. */ - public void runBare() throws Throwable { + /*public void runBare() throws Throwable { if (isWeavingEnabled()) { super.runBare(); } - } + }*/ /** * Any FetchGroups setup in test cases are removed. @@ -447,8 +447,7 @@ } protected QuerySQLTracker getQuerySQLTracker(EntityManager em) { - return QuerySQLTracker.getTracker(JpaHelper.getEntityManager(em) - .getActiveSession()); + return QuerySQLTracker.getTracker(getServerSession()); } ClassDescriptor getDescriptor(String entityName) { Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupAssert.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupAssert.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupAssert.java (working copy) @@ -53,7 +53,7 @@ */ public static boolean isValid(FetchGroup fetchGroup, EntityManagerFactory emf, Class entityClass) { assertNotNull(fetchGroup); - Session session = JpaHelper.getServerSession(emf); + Session session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession(); ClassDescriptor descriptor = session.getDescriptor(entityClass); try { for (Map.Entry entry : fetchGroup.getItems().entrySet()) { @@ -82,7 +82,7 @@ public static void assertFetchedAttribute(EntityManagerFactory emf, Object entity, String... attribute) { assertNotNull("EntityManagerFactory is null", emf); assertNotNull("Entity is null", entity); - Server session = JpaHelper.getServerSession(emf); + Server session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession(); assertNotNull("No Server session found for: " + emf, session); ClassDescriptor desc = session.getClassDescriptor(entity); assertNotNull("No descriptor found for: " + entity, desc); @@ -128,7 +128,7 @@ public static void assertNotFetchedAttribute(EntityManagerFactory emf, Object entity, String... attribute) { assertNotNull("EntityManagerFactory is null", emf); assertNotNull("Entity is null", entity); - Server session = JpaHelper.getServerSession(emf); + Server session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession(); assertNotNull("No Server session found for: " + emf, session); ClassDescriptor desc = session.getClassDescriptor(entity); assertNotNull("No descriptor found for: " + entity, desc); @@ -178,7 +178,7 @@ } assertTrue("FetchGroup on entity does not equal provided", tracker._persistence_getFetchGroup().equals(groupToCompare)); - Server session = JpaHelper.getServerSession(emf); + Server session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession(); assertNotNull(session); ClassDescriptor descriptor = session.getClassDescriptor(entity); assertNotNull(descriptor); @@ -220,7 +220,7 @@ public static void assertDefaultFetched(EntityManagerFactory emf, Object entity) { assertNotNull("Null entity", entity); - ClassDescriptor descriptor = JpaHelper.getServerSession(emf).getClassDescriptor(entity); + ClassDescriptor descriptor = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession().getClassDescriptor(entity); assertNotNull("No descriptor found for: " + entity, descriptor); assertTrue("No FetchGroupManager on: " + descriptor, descriptor.hasFetchGroupManager()); @@ -234,7 +234,7 @@ public static void assertFetched(EntityManagerFactory emf, Object entity, String fetchGroupName) { assertNotNull("Null entity", entity); - ClassDescriptor descriptor = JpaHelper.getServerSession(emf).getClassDescriptor(entity); + ClassDescriptor descriptor = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession().getClassDescriptor(entity); assertNotNull("No descriptor found for: " + entity, descriptor); assertTrue("No FetchGroupManager on: " + descriptor, descriptor.hasFetchGroupManager()); @@ -263,7 +263,7 @@ } public static void assertConfig(EntityManagerFactory emf, String entityName, FetchGroup defaultFetchGroup, int numNamedFetchGroups) { - ClassDescriptor descriptor = JpaHelper.getServerSession(emf).getClassDescriptorForAlias(entityName); + ClassDescriptor descriptor = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession().getClassDescriptorForAlias(entityName); assertNotNull("Not descriptor found for: " + entityName, descriptor); assertConfig(descriptor, defaultFetchGroup, numNamedFetchGroups); } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupMergeWithCacheTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupMergeWithCacheTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupMergeWithCacheTests.java (working copy) @@ -40,8 +40,9 @@ suite.addTest(new FetchGroupMergeWithCacheTests("testSetup")); suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_QueryWithFetchGroup_Simple")); - suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_FindWithFetchGroup_Simple")); - + if (!isJPA10()) { + suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_FindWithFetchGroup_Simple")); + } return suite; } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupsServerTestSuite.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupsServerTestSuite.java (revision 0) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupsServerTestSuite.java (revision 0) @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 1998, 2010 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 + * which accompanies this distribution. + * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Oracle - initial API and implementation from Oracle TopLink + ******************************************************************************/ +package org.eclipse.persistence.testing.tests.jpa.fetchgroups; + +import junit.framework.TestSuite; +import junit.framework.Test; + +/** + *

Purpose: To collect the tests that will run against Application Server only. + */ +public class FetchGroupsServerTestSuite extends TestSuite { + + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.setName("FetchGroups ServerTestSuite"); + suite.addTest(FetchGroupAPITests.suite()); + suite.addTest(FetchGroupMergeWithCacheTests.suite()); + suite.addTest(FetchGroupTrackerWeavingTests.suite()); + suite.addTest(NestedDefaultFetchGroupTests.suite()); + suite.addTest(NestedFetchGroupTests.suite()); + suite.addTest(NestedNamedFetchGroupTests.suite()); + suite.addTest(SimpleDefaultFetchGroupTests.suite()); + suite.addTest(SimpleFetchGroupTests.suite()); + suite.addTest(SimpleNamedFetchGroupTests.suite()); + suite.addTest(SimpleSerializeFetchGroupTests.suite()); + return suite; + } +} Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupTrackerWeavingTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupTrackerWeavingTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupTrackerWeavingTests.java (working copy) @@ -51,15 +51,6 @@ public FetchGroupTrackerWeavingTests(String name) { super(name); } - - /* - * Fetch Group tests require weaving. - */ - public void runBare() throws Throwable { - if (isWeavingEnabled()) { - super.runBare(); - } - } public static junit.framework.Test suite() { TestSuite suite = new TestSuite(); Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedDefaultFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedDefaultFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedDefaultFetchGroupTests.java (working copy) @@ -56,15 +56,16 @@ suite.addTest(new NestedDefaultFetchGroupTests("testSetup")); suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployee")); - suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddress")); - suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadPhones")); - suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhones")); suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhoneUsingFetchGroup")); - suite.addTest(new NestedDefaultFetchGroupTests("allAddress")); - suite.addTest(new NestedDefaultFetchGroupTests("allPhone")); - suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddress")); - suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddressLoad")); - + if (!isJPA10()) { + suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddress")); + suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadPhones")); + suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhones")); + suite.addTest(new NestedDefaultFetchGroupTests("allAddress")); + suite.addTest(new NestedDefaultFetchGroupTests("allPhone")); + suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddress")); + suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddressLoad")); + } return suite; } @@ -117,6 +118,8 @@ void internalFindMinEmployee(boolean loadAddress, boolean loadPhones, boolean useLoadGroup) { EntityManager em = createEntityManager(); + beginTransaction(em); + int minId = minEmployeeIdWithAddressAndPhones(em); assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); @@ -188,6 +191,10 @@ defaultEmployeeFG.setShouldLoad(originalLoad); } } + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } /* void internalFindMinEmployee(boolean loadAddress, boolean loadPhones) { Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedFetchGroupTests.java (working copy) @@ -97,198 +97,222 @@ @Test public void dynamicFetchGroup_EmployeeAddress() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup fg = new FetchGroup(); - fg.addAttribute("id"); - fg.addAttribute("version"); - fg.addAttribute("firstName"); - fg.addAttribute("lastName"); - fg.addAttribute("address.city"); - fg.addAttribute("address.postalCode"); + // Define the fields to be fetched on Employee + FetchGroup fg = new FetchGroup(); + fg.addAttribute("id"); + fg.addAttribute("version"); + fg.addAttribute("firstName"); + fg.addAttribute("lastName"); + fg.addAttribute("address.city"); + fg.addAttribute("address.postalCode"); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, fg); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, fg); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("address")); - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("address")); + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("address")); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("address")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); - assertTrue(phoneTracker._persistence_isAttributeFetched("number")); - assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); + assertTrue(phoneTracker._persistence_isAttributeFetched("number")); + assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void dynamicFetchGroup_Employee_NullAddress() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup empGroup = new FetchGroup(); - empGroup.addAttribute("firstName"); - empGroup.addAttribute("lastName"); - empGroup.addAttribute("address"); + // Define the fields to be fetched on Employee + FetchGroup empGroup = new FetchGroup(); + empGroup.addAttribute("firstName"); + empGroup.addAttribute("lastName"); + empGroup.addAttribute("address"); - // Define the fields to be fetched on Address - FetchGroup addressGroup = new FetchGroup(); - addressGroup.addAttribute("city"); - addressGroup.addAttribute("postalCode"); + // Define the fields to be fetched on Address + FetchGroup addressGroup = new FetchGroup(); + addressGroup.addAttribute("city"); + addressGroup.addAttribute("postalCode"); - empGroup.addAttribute("address"); + empGroup.addAttribute("address"); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, empGroup); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, empGroup); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNull("Address has an unexpected FetchGroup", addrTracker._persistence_getFetchGroup()); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNull("Address has an unexpected FetchGroup", addrTracker._persistence_getFetchGroup()); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); - assertTrue(phoneTracker._persistence_isAttributeFetched("number")); - assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); + assertTrue(phoneTracker._persistence_isAttributeFetched("number")); + assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup empGroup = new FetchGroup(); - empGroup.addAttribute("firstName"); - empGroup.addAttribute("lastName"); - empGroup.addAttribute("address"); - empGroup.addAttribute("address.city"); - empGroup.addAttribute("address.postalCode"); + // Define the fields to be fetched on Employee + FetchGroup empGroup = new FetchGroup(); + empGroup.addAttribute("firstName"); + empGroup.addAttribute("lastName"); + empGroup.addAttribute("address"); + empGroup.addAttribute("address.city"); + empGroup.addAttribute("address.postalCode"); -// empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false); - FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); - // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group - fullPhone.addAttribute("owner.id"); - empGroup.addAttribute("phoneNumbers", fullPhone); + //empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false); + FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); + // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group + fullPhone.addAttribute("owner.id"); + empGroup.addAttribute("phoneNumbers", fullPhone); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, empGroup); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, empGroup); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup()); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup()); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -301,76 +325,84 @@ } void internal_dynamicFetchGroup_EmployeeAddressEmptyPhone(boolean shouldLoad) { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup fg = new FetchGroup(); - fg.addAttribute("firstName"); - fg.addAttribute("lastName"); - fg.addAttribute("address.city"); - fg.addAttribute("address.postalCode"); - // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group - FetchGroup ownerId = new FetchGroup(); - ownerId.addAttribute("owner.id"); - fg.addAttribute("phoneNumbers", ownerId); - - if(shouldLoad) { - fg.setShouldLoad(true); - } + // Define the fields to be fetched on Employee + FetchGroup fg = new FetchGroup(); + fg.addAttribute("firstName"); + fg.addAttribute("lastName"); + fg.addAttribute("address.city"); + fg.addAttribute("address.postalCode"); + // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group + FetchGroup ownerId = new FetchGroup(); + ownerId.addAttribute("owner.id"); + fg.addAttribute("phoneNumbers", ownerId); + + if(shouldLoad) { + fg.setShouldLoad(true); + } - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, fg); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, fg); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1 + (shouldLoad ? 0 : (emps.size() * 2)), getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + assertEquals(1 + (shouldLoad ? 0 : (emps.size() * 2)), getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); - assertFalse(phoneTracker._persistence_isAttributeFetched("number")); - assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); + assertFalse(phoneTracker._persistence_isAttributeFetched("number")); + assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); - phone.getNumber(); + phone.getNumber(); - assertTrue(phoneTracker._persistence_isAttributeFetched("number")); - assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode")); + assertTrue(phoneTracker._persistence_isAttributeFetched("number")); + assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode")); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -421,132 +453,154 @@ void internalDynamicHierarchicalFetchGroup_JOIN_FETCH(boolean useCopy) throws Exception { EntityManager em = createEntityManager(); - - Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.manager WHERE e.lastName LIKE :LNAME AND e.manager.lastName <> e.lastName"); - query.setParameter("LNAME", "%"); + try { + beginTransaction(em); - // Define the fields to be fetched on Employee - FetchGroup fg = new FetchGroup(); - fg.addAttribute("firstName"); - fg.addAttribute("lastName"); - fg.addAttribute("manager.firstName"); - fg.addAttribute("manager.salary"); - fg.addAttribute("manager.manager"); - query.setHint(QueryHints.FETCH_GROUP, fg); - - // applied to the selected Employee who is not a manager of some other selected Employee - FetchGroup employeeFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "lastName", "manager"}); - // applied to the manager of a selected Employee who is not selected as an Employee - FetchGroup managerFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "salary", "manager"}); - // applied to the object which is both selected as an Employee and the manager of another selected Employee - FetchGroup employeeManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(employeeFG, managerFG); - - // used in useCopy case only - FetchGroup employeeManagerManagerFG = null; - if(useCopy) { - employeeManagerManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(new EntityFetchGroup("manager"), employeeDescriptor.getFetchGroupManager().getNonReferenceEntityFetchGroup()); - } - - /* - * These are the first names of Employees involved; --> means "managed by". - * All the employees here are returned by the query except Jill and Sarah-loo (they got no manager). - * - * Sarah ------>Bob -------> John ----> Jim-bob ---> Jill ---> null - * Charles -----^ Marius ----^ - * - * Nancy ------> Sarah-loo ---> null - * - * Sarah, Charles, Nancy should have employeeFG; - * Sarah-loo - managerFG; - * Bob, Marius - employeeManagerFG; - * John, Jim-bob should have a union of three fetch groups: {firstName,lastName,manager}, {firstName,salary,manager}, {manager} - * Jill should have a union of two groups: {firstName,salary,manager}, {manager} - * The result for all three of them is the same: - * in read case (useCopy == false) it should be null (no fetch group), because defaultFetchGroup is null; - * in copy case (useCopy == true) it should be a union of "manager" and all non relational attributes (NonReferenceEntityFetchGroup). - * That's how leaf reference attribute is treated: - * default fetch group for read; - * NonReferenceEntityFetchGroup (see FetchGroupManager) for copy. - * In this test defaultFetchGroup (null) / NonReferenceEntityFetchGroup comes from {manager}, - * in useCopy == true case additional manager comes from another fetch group (they all contain manager). - */ - - List emps = query.getResultList(); - - if(useCopy) { -/* for(Employee emp : emps) { - int idHashCode = System.identityHashCode(emp); - System.out.println(emp.getFirstName() + '\t' + idHashCode); - }*/ - emps = (List)JpaHelper.getEntityManager(em).copy(emps, fg); - } + Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.manager WHERE e.lastName LIKE :LNAME AND e.manager.lastName <> e.lastName"); + query.setParameter("LNAME", "%"); - // Sets of managed Employees keyed by their manager - Map> managedEmployeesByManager = new IdentityHashMap(); - for (Employee emp : emps) { - Employee manager = emp.getManager(); - Set managedEmployees = managedEmployeesByManager.get(manager); - if(managedEmployees == null) { - managedEmployees = new IdentityHashSet(); - managedEmployeesByManager.put(manager, managedEmployees); + // Define the fields to be fetched on Employee + FetchGroup fg = new FetchGroup(); + fg.addAttribute("firstName"); + fg.addAttribute("lastName"); + fg.addAttribute("manager.firstName"); + fg.addAttribute("manager.salary"); + fg.addAttribute("manager.manager"); + query.setHint(QueryHints.FETCH_GROUP, fg); + + // applied to the selected Employee who is not a manager of some other selected Employee + FetchGroup employeeFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "lastName", "manager"}); + // applied to the manager of a selected Employee who is not selected as an Employee + FetchGroup managerFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "salary", "manager"}); + // applied to the object which is both selected as an Employee and the manager of another selected Employee + FetchGroup employeeManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(employeeFG, managerFG); + + // used in useCopy case only + FetchGroup employeeManagerManagerFG = null; + if(useCopy) { + employeeManagerManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(new EntityFetchGroup("manager"), employeeDescriptor.getFetchGroupManager().getNonReferenceEntityFetchGroup()); } - managedEmployees.add(emp); - } + + /* + * These are the first names of Employees involved; --> means "managed by". + * All the employees here are returned by the query except Jill and Sarah-loo (they got no manager). + * + * Sarah ------>Bob -------> John ----> Jim-bob ---> Jill ---> null + * Charles -----^ Marius ----^ + * + * Nancy ------> Sarah-loo ---> null + * + * Sarah, Charles, Nancy should have employeeFG; + * Sarah-loo - managerFG; + * Bob, Marius - employeeManagerFG; + * John, Jim-bob should have a union of three fetch groups: {firstName,lastName,manager}, {firstName,salary,manager}, {manager} + * Jill should have a union of two groups: {firstName,salary,manager}, {manager} + * The result for all three of them is the same: + * in read case (useCopy == false) it should be null (no fetch group), because defaultFetchGroup is null; + * in copy case (useCopy == true) it should be a union of "manager" and all non relational attributes (NonReferenceEntityFetchGroup). + * That's how leaf reference attribute is treated: + * default fetch group for read; + * NonReferenceEntityFetchGroup (see FetchGroupManager) for copy. + * In this test defaultFetchGroup (null) / NonReferenceEntityFetchGroup comes from {manager}, + * in useCopy == true case additional manager comes from another fetch group (they all contain manager). + */ + + List emps = query.getResultList(); + + if(useCopy) { + /*for(Employee emp : emps) { + int idHashCode = System.identityHashCode(emp); + System.out.println(emp.getFirstName() + '\t' + idHashCode); + }*/ + emps = (List)JpaHelper.getEntityManager(em).copy(emps, fg); + } - for (Employee emp : emps) { - Set managedEmployees = managedEmployeesByManager.get(emp); - Employee manager = emp.getManager(); - if(managedEmployees == null) { - // employee is NOT a manager of any of the selected employees: - assertFetched(emp, employeeFG); + // Sets of managed Employees keyed by their manager + Map> managedEmployeesByManager = new IdentityHashMap(); + for (Employee emp : emps) { + Employee manager = emp.getManager(); + Set managedEmployees = managedEmployeesByManager.get(manager); + if(managedEmployees == null) { + managedEmployees = new IdentityHashSet(); + managedEmployeesByManager.put(manager, managedEmployees); + } + managedEmployees.add(emp); + } - Set managedByManagerEmployees = managedEmployeesByManager.get(manager); - // indicates whether one of manager's managed employees is a manager itself - boolean isManagersManager = false; - for(Employee managedEmp : managedByManagerEmployees) { - if(managedEmployeesByManager.containsKey(managedEmp)) { - isManagersManager = true; - break; + for (Employee emp : emps) { + Set managedEmployees = managedEmployeesByManager.get(emp); + Employee manager = emp.getManager(); + if(managedEmployees == null) { + // employee is NOT a manager of any of the selected employees: + assertFetched(emp, employeeFG); + + Set managedByManagerEmployees = managedEmployeesByManager.get(manager); + // indicates whether one of manager's managed employees is a manager itself + boolean isManagersManager = false; + for(Employee managedEmp : managedByManagerEmployees) { + if(managedEmployeesByManager.containsKey(managedEmp)) { + isManagersManager = true; + break; + } } - } - if(isManagersManager) { - if(useCopy) { - // for at least one of the selected employees manager is manager's manager: - // someSelectedEmp.getManager().getManager() == manager - // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, - // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk) - // for another employee it's just a manager - which means it should include "manager": - // employeeManagerManagerFG is the union of these two EntityFetchGroups. - assertFetched(manager, employeeManagerManagerFG); + if(isManagersManager) { + if(useCopy) { + // for at least one of the selected employees manager is manager's manager: + // someSelectedEmp.getManager().getManager() == manager + // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, + // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk) + // for another employee it's just a manager - which means it should include "manager": + // employeeManagerManagerFG is the union of these two EntityFetchGroups. + assertFetched(manager, employeeManagerManagerFG); + } else { + // for at least one of the selected employees manager is manager's manager: + // someSelectedEmp.getManager().getManager() == manager + // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, + // which means no fetch group should be used. + assertNoFetchGroup(manager); + } } else { - // for at least one of the selected employees manager is manager's manager: - // someSelectedEmp.getManager().getManager() == manager - // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, - // which means no fetch group should be used. - assertNoFetchGroup(manager); + // it's not manager's manager + if(emps.contains(manager)) { + // it's a manager of one of the selected Employees, and selected itself. + assertFetched(manager, employeeManagerFG); + } else { + // it's a manager of one of the selected Employees, but not selected itself. + assertFetched(manager, managerFG); + } } } else { - // it's not manager's manager - if(emps.contains(manager)) { - // it's a manager of one of the selected Employees, and selected itself. - assertFetched(manager, employeeManagerFG); + // employee is a manager of at least one of the selected employees + // indicates whether one of emp's managed employees is a manager itself + boolean isManagersManager = false; + for(Employee managedEmp : managedEmployees) { + if(managedEmployeesByManager.containsKey(managedEmp)) { + isManagersManager = true; + break; + } + } + + if(isManagersManager) { + if(useCopy) { + // for at least one of the selected employees manager is manager's manager: + // someSelectedEmp.getManager().getManager() == manager + // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, + // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk) + // for another employee it's just a manager - which means it should include "manager": + // employeeManagerManagerFG is the union of these two EntityFetchGroups. + assertFetched(emp, employeeManagerManagerFG); + } else { + // for at least one of the selected employees emp is manager's manager: + // someSelectedEmp.getManager().getManager() == emp + // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, + // which means no fetch group should be used. + assertNoFetchGroup(emp); + } } else { - // it's a manager of one of the selected Employees, but not selected itself. - assertFetched(manager, managerFG); + // it's selected employee, manager of some selected employee, but not manager's manager + assertFetched(emp, employeeManagerFG); } - } - } else { - // employee is a manager of at least one of the selected employees - // indicates whether one of emp's managed employees is a manager itself - boolean isManagersManager = false; - for(Employee managedEmp : managedEmployees) { - if(managedEmployeesByManager.containsKey(managedEmp)) { - isManagersManager = true; - break; - } - } - - if(isManagersManager) { + if(useCopy) { // for at least one of the selected employees manager is manager's manager: // someSelectedEmp.getManager().getManager() == manager @@ -554,35 +608,21 @@ // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk) // for another employee it's just a manager - which means it should include "manager": // employeeManagerManagerFG is the union of these two EntityFetchGroups. - assertFetched(emp, employeeManagerManagerFG); + assertFetched(manager, employeeManagerManagerFG); } else { - // for at least one of the selected employees emp is manager's manager: - // someSelectedEmp.getManager().getManager() == emp - // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, + // for at least one of the selected employees manager is manager's manager: + // someSelectedEmp.getManager().getManager() == manager + // That means for someSelectedEmp emp.getManager() is defined by {manager.manager} FetchGroup's item, // which means no fetch group should be used. - assertNoFetchGroup(emp); + assertNoFetchGroup(manager); } - } else { - // it's selected employee, manager of some selected employee, but not manager's manager - assertFetched(emp, employeeManagerFG); } - - if(useCopy) { - // for at least one of the selected employees manager is manager's manager: - // someSelectedEmp.getManager().getManager() == manager - // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, - // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk) - // for another employee it's just a manager - which means it should include "manager": - // employeeManagerManagerFG is the union of these two EntityFetchGroups. - assertFetched(manager, employeeManagerManagerFG); - } else { - // for at least one of the selected employees manager is manager's manager: - // someSelectedEmp.getManager().getManager() == manager - // That means for someSelectedEmp emp.getManager() is defined by {manager.manager} FetchGroup's item, - // which means no fetch group should be used. - assertNoFetchGroup(manager); - } - } + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -598,157 +638,173 @@ void managerNestedFetchGroupWithJoinFetch(boolean isDouble) { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager.manager IS NOT NULL"); - FetchGroup managerFG = new FetchGroup(); - if(isDouble) { - // Double - managerFG.addAttribute("manager.manager"); - } else { - // Triple - managerFG.addAttribute("manager.manager.manager"); - } + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager.manager IS NOT NULL"); + FetchGroup managerFG = new FetchGroup(); + if(isDouble) { + // Double + managerFG.addAttribute("manager.manager"); + } else { + // Triple + managerFG.addAttribute("manager.manager.manager"); + } - query.setHint(QueryHints.FETCH_GROUP, managerFG); - query.setHint(QueryHints.LEFT_FETCH, "e.manager"); + query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.LEFT_FETCH, "e.manager"); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - List employees = query.getResultList(); + List employees = query.getResultList(); - int nSql; - if(isDouble) { - // In this case the number of generated sqls is unpredictable. - // Additional sql generated for every object that - // has been first fetched as manager.manager - // and then is selected as an employee - getting its manger - // performed without fetch group therefore triggering reading of the whole object - nSql = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); - } else { - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - nSql = 1; - } - - Employee emp = employees.get(0); - assertFetched(emp, managerFG); - - // manager (if not null) is instantiated by the fetch group, before emp.getManager call. - Employee manager = emp.getManager(); - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(manager, managerFG); - - // instantiates the whole object - emp.getLastName(); - nSql++; - assertNoFetchGroup(emp); - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - assertFetched(manager, managerFG); - // instantiates the whole object - manager.getLastName(); - nSql++; - assertNoFetchGroup(manager); - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int nSql; + if(isDouble) { + // In this case the number of generated sqls is unpredictable. + // Additional sql generated for every object that + // has been first fetched as manager.manager + // and then is selected as an employee - getting its manger + // performed without fetch group therefore triggering reading of the whole object + nSql = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); + } else { + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + nSql = 1; + } + + Employee emp = employees.get(0); + assertFetched(emp, managerFG); + + // manager (if not null) is instantiated by the fetch group, before emp.getManager call. + Employee manager = emp.getManager(); + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(manager, managerFG); + + // instantiates the whole object + emp.getLastName(); + nSql++; + assertNoFetchGroup(emp); + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + assertFetched(manager, managerFG); + // instantiates the whole object + manager.getLastName(); + nSql++; + assertNoFetchGroup(manager); + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - nSql++; - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertFetched(phone, this.defaultPhoneFG); - phone.getAreaCode(); nSql++; - assertNoFetchGroup(phone); - } - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertFetched(phone, this.defaultPhoneFG); + phone.getAreaCode(); + nSql++; + assertNoFetchGroup(phone); + } + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - nSql++; - for (PhoneNumber phone : manager.getPhoneNumbers()) { - assertFetched(phone, this.defaultPhoneFG); - phone.getAreaCode(); nSql++; - assertNoFetchGroup(phone); + for (PhoneNumber phone : manager.getPhoneNumbers()) { + assertFetched(phone, this.defaultPhoneFG); + phone.getAreaCode(); + nSql++; + assertNoFetchGroup(phone); + } + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void allNestedFetchGroupWithJoinFetch() { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - // select employees who are neither managers nor team leaders - Query query = em.createQuery("SELECT e FROM Employee e WHERE NOT EXISTS(SELECT p.id FROM Project p WHERE p.teamLeader = e) AND NOT EXISTS(SELECT e2.id FROM Employee e2 WHERE e2.manager = e)"); - FetchGroup employeeFG = new FetchGroup("employee"); - employeeFG.addAttribute("lastName"); - - employeeFG.addAttribute("address.country"); - employeeFG.addAttribute("address.city"); - query.setHint(QueryHints.LEFT_FETCH, "e.address"); - - employeeFG.addAttribute("phoneNumbers"); - query.setHint(QueryHints.LEFT_FETCH, "e.phoneNumbers"); - - employeeFG.addAttribute("projects.name"); + // select employees who are neither managers nor team leaders + Query query = em.createQuery("SELECT e FROM Employee e WHERE NOT EXISTS(SELECT p.id FROM Project p WHERE p.teamLeader = e) AND NOT EXISTS(SELECT e2.id FROM Employee e2 WHERE e2.manager = e)"); + FetchGroup employeeFG = new FetchGroup("employee"); + employeeFG.addAttribute("lastName"); + + employeeFG.addAttribute("address.country"); + employeeFG.addAttribute("address.city"); + query.setHint(QueryHints.LEFT_FETCH, "e.address"); + + employeeFG.addAttribute("phoneNumbers"); + query.setHint(QueryHints.LEFT_FETCH, "e.phoneNumbers"); + + employeeFG.addAttribute("projects.name"); - employeeFG.addAttribute("projects.teamLeader.firstName"); -// employeeFG.addAttribute("projects.teamLeader.address.street"); -// employeeFG.addAttribute("projects.teamLeader.address.postalCode"); - employeeFG.addAttribute("projects.teamLeader.phoneNumbers.owner"); - employeeFG.addAttribute("projects.teamLeader.phoneNumbers.type"); - employeeFG.addAttribute("projects.teamLeader.phoneNumbers.areaCode"); - query.setHint(QueryHints.LEFT_FETCH, "e.projects.teamLeader.phoneNumbers"); - - employeeFG.addAttribute("manager.firstName"); -// employeeFG.addAttribute("manager.address.street"); -// employeeFG.addAttribute("manager.address.postalCode"); - employeeFG.addAttribute("manager.phoneNumbers.owner"); - employeeFG.addAttribute("manager.phoneNumbers.type"); - employeeFG.addAttribute("manager.phoneNumbers.areaCode"); - query.setHint(QueryHints.LEFT_FETCH, "e.manager.phoneNumbers"); + employeeFG.addAttribute("projects.teamLeader.firstName"); + //employeeFG.addAttribute("projects.teamLeader.address.street"); + //employeeFG.addAttribute("projects.teamLeader.address.postalCode"); + employeeFG.addAttribute("projects.teamLeader.phoneNumbers.owner"); + employeeFG.addAttribute("projects.teamLeader.phoneNumbers.type"); + employeeFG.addAttribute("projects.teamLeader.phoneNumbers.areaCode"); + query.setHint(QueryHints.LEFT_FETCH, "e.projects.teamLeader.phoneNumbers"); + + employeeFG.addAttribute("manager.firstName"); + //employeeFG.addAttribute("manager.address.street"); + //employeeFG.addAttribute("manager.address.postalCode"); + employeeFG.addAttribute("manager.phoneNumbers.owner"); + employeeFG.addAttribute("manager.phoneNumbers.type"); + employeeFG.addAttribute("manager.phoneNumbers.areaCode"); + query.setHint(QueryHints.LEFT_FETCH, "e.manager.phoneNumbers"); - // department attribute defined with JoinFetchType.OUTER - employeeFG.addAttribute("department.name"); - - query.setHint(QueryHints.FETCH_GROUP, employeeFG); + // department attribute defined with JoinFetchType.OUTER + employeeFG.addAttribute("department.name"); + + query.setHint(QueryHints.FETCH_GROUP, employeeFG); - List employees = query.getResultList(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - for(Employee emp :employees) { - assertFetched(emp, employeeFG); + List employees = query.getResultList(); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - Address address = emp.getAddress(); - if(address != null) { - assertFetched(address, employeeFG.getGroup("address")); - } + for(Employee emp :employees) { + assertFetched(emp, employeeFG); + + Address address = emp.getAddress(); + if(address != null) { + assertFetched(address, employeeFG.getGroup("address")); + } - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertFetched(phone, defaultPhoneFG); - } - - for (Project project : emp.getProjects()) { - assertFetched(project, employeeFG.getGroup("projects")); - Employee teamLeader = project.getTeamLeader(); - if(teamLeader != null) { - assertFetched(teamLeader, employeeFG.getGroup("projects.teamLeader")); - for (PhoneNumber phone : teamLeader.getPhoneNumbers()) { - assertFetched(phone, employeeFG.getGroup("projects.teamLeader.phoneNumbers")); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertFetched(phone, defaultPhoneFG); + } + + for (Project project : emp.getProjects()) { + assertFetched(project, employeeFG.getGroup("projects")); + Employee teamLeader = project.getTeamLeader(); + if(teamLeader != null) { + assertFetched(teamLeader, employeeFG.getGroup("projects.teamLeader")); + for (PhoneNumber phone : teamLeader.getPhoneNumbers()) { + assertFetched(phone, employeeFG.getGroup("projects.teamLeader.phoneNumbers")); + } } } - } - - Employee manager = emp.getManager(); - if(manager != null) { - assertFetched(manager, employeeFG.getGroup("manager")); - for (PhoneNumber phone : manager.getPhoneNumbers()) { - assertFetched(phone, employeeFG.getGroup("manager.phoneNumbers")); + + Employee manager = emp.getManager(); + if(manager != null) { + assertFetched(manager, employeeFG.getGroup("manager")); + for (PhoneNumber phone : manager.getPhoneNumbers()) { + assertFetched(phone, employeeFG.getGroup("manager.phoneNumbers")); + } } + + Department department = emp.getDepartment(); + if(department != null) { + assertFetched(department, employeeFG.getGroup("department")); + } } - - Department department = emp.getDepartment(); - if(department != null) { - assertFetched(department, employeeFG.getGroup("department")); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); } + closeEntityManager(em); } - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test @@ -786,114 +842,130 @@ @Test public void simpleNestedFetchGroupWithBatch() { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e"); + Query query = em.createQuery("SELECT e FROM Employee e"); - // Define the fields to be fetched on Employee - FetchGroup employeeFG = new FetchGroup(); - employeeFG.setShouldLoad(true); - employeeFG.addAttribute("firstName"); - employeeFG.addAttribute("lastName"); - employeeFG.addAttribute("address.country"); - employeeFG.addAttribute("address.city"); - - FetchGroup phonesFG = defaultPhoneFG.clone(); - // to preclude PhoneNumber from triggering owner's full read - phonesFG.addAttribute("owner.id"); - employeeFG.addAttribute("phoneNumbers", phonesFG); - - FetchGroup projectsFG = new FetchGroup("projects"); - projectsFG.addAttribute("name"); - projectsFG.addAttribute("name"); - // to preclude Project from triggering full read of the referenced Employee(s) - projectsFG.addAttribute("teamMembers.id"); - projectsFG.addAttribute("teamLeader.id"); - employeeFG.addAttribute("projects", projectsFG); + // Define the fields to be fetched on Employee + FetchGroup employeeFG = new FetchGroup(); + employeeFG.setShouldLoad(true); + employeeFG.addAttribute("firstName"); + employeeFG.addAttribute("lastName"); + employeeFG.addAttribute("address.country"); + employeeFG.addAttribute("address.city"); + + FetchGroup phonesFG = defaultPhoneFG.clone(); + // to preclude PhoneNumber from triggering owner's full read + phonesFG.addAttribute("owner.id"); + employeeFG.addAttribute("phoneNumbers", phonesFG); + + FetchGroup projectsFG = new FetchGroup("projects"); + projectsFG.addAttribute("name"); + projectsFG.addAttribute("name"); + // to preclude Project from triggering full read of the referenced Employee(s) + projectsFG.addAttribute("teamMembers.id"); + projectsFG.addAttribute("teamLeader.id"); + employeeFG.addAttribute("projects", projectsFG); - query.setHint(QueryHints.FETCH_GROUP, employeeFG); - - query.setHint(QueryHints.BATCH, "e.address"); - query.setHint(QueryHints.BATCH, "e.phoneNumbers"); - query.setHint(QueryHints.BATCH, "e.projects"); - - // A single sql will be used to read all Project subclasses. - query.setHint(QueryHints.INHERITANCE_OUTER_JOIN, "true"); + query.setHint(QueryHints.FETCH_GROUP, employeeFG); + + query.setHint(QueryHints.BATCH, "e.address"); + query.setHint(QueryHints.BATCH, "e.phoneNumbers"); + query.setHint(QueryHints.BATCH, "e.projects"); + + // A single sql will be used to read all Project subclasses. + query.setHint(QueryHints.INHERITANCE_OUTER_JOIN, "true"); - List employees = query.getResultList(); + List employees = query.getResultList(); - // Employee, Address, PhoneNumbers, Projects - an sql per class. - // Address, PhoneNumbers and Projects are already loaded because - // employeeFG.shouldLoad is set to true. - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // verify fetch groups - for(Employee emp : employees) { - assertFetched(emp, employeeFG); + // Employee, Address, PhoneNumbers, Projects - an sql per class. + // Address, PhoneNumbers and Projects are already loaded because + // employeeFG.shouldLoad is set to true. + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // verify fetch groups + for(Employee emp : employees) { + assertFetched(emp, employeeFG); - Address address = emp.getAddress(); - if(address != null) { - assertFetched(address, employeeFG.getGroup("address")); - } + Address address = emp.getAddress(); + if(address != null) { + assertFetched(address, employeeFG.getGroup("address")); + } - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertFetched(phone, phonesFG); - } - - for (Project project : emp.getProjects()) { - assertFetched(project, projectsFG); - } - } + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertFetched(phone, phonesFG); + } + + for (Project project : emp.getProjects()) { + assertFetched(project, projectsFG); + } + } - // Now let's access an attribute outside of the fetch group. - // That triggers loading of the whole object. - for(Employee emp : employees) { - emp.getSalary(); - assertNoFetchGroup(emp); + // Now let's access an attribute outside of the fetch group. + // That triggers loading of the whole object. + for(Employee emp : employees) { + emp.getSalary(); + assertNoFetchGroup(emp); - Address address = emp.getAddress(); - if(address != null) { - address.getStreet(); - assertNoFetchGroup(address); - } + Address address = emp.getAddress(); + if(address != null) { + address.getStreet(); + assertNoFetchGroup(address); + } - for (PhoneNumber phone : emp.getPhoneNumbers()) { - phone.getAreaCode(); - assertNoFetchGroup(phone); - } - - for (Project project : emp.getProjects()) { - project.getDescription(); - assertNoFetchGroup(project); - } - } + for (PhoneNumber phone : emp.getPhoneNumbers()) { + phone.getAreaCode(); + assertNoFetchGroup(phone); + } + + for (Project project : emp.getProjects()) { + project.getDescription(); + assertNoFetchGroup(project); + } + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); + } } @Test public void simpleLoadGroup() { EntityManager em = createEntityManager(); - - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Female); - List employees = query.getResultList(); - - LoadGroup group = new LoadGroup(); - group.addAttribute("address"); - group.addAttribute("phoneNumbers"); - group.addAttribute("manager.projects"); - ((AbstractSession)((EntityManagerImpl)em.getDelegate()).getActiveSession()).load(employees, group); + try { + beginTransaction(em); - int numSelectBefore = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); - - // All indirections specified in the plan should have been already triggered. - for(Employee emp : employees) { - emp.getAddress(); - emp.getPhoneNumbers().size(); - if(emp.getManager() != null) { - emp.getManager().getProjects().size(); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Female); + List employees = query.getResultList(); + + LoadGroup group = new LoadGroup(); + group.addAttribute("address"); + group.addAttribute("phoneNumbers"); + group.addAttribute("manager.projects"); + ((AbstractSession)((EntityManagerImpl)em.getDelegate()).getActiveSession()).load(employees, group); + + int numSelectBefore = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); + + // All indirections specified in the plan should have been already triggered. + for(Employee emp : employees) { + emp.getAddress(); + emp.getPhoneNumbers().size(); + if(emp.getManager() != null) { + emp.getManager().getProjects().size(); + } + } + + int numSelectAfter = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); + assertEquals(numSelectBefore, numSelectAfter); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); } + closeEntityManager(em); } - - int numSelectAfter = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); - assertEquals(numSelectBefore, numSelectAfter); } } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedNamedFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedNamedFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedNamedFetchGroupTests.java (working copy) @@ -83,62 +83,70 @@ @Test public void dynamicFetchGroup_EmployeeAddress() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup fg = new FetchGroup(); - fg.addAttribute("firstName"); - fg.addAttribute("lastName"); - fg.addAttribute("address"); - fg.addAttribute("address.city"); - fg.addAttribute("address.postalCode"); + // Define the fields to be fetched on Employee + FetchGroup fg = new FetchGroup(); + fg.addAttribute("firstName"); + fg.addAttribute("lastName"); + fg.addAttribute("address"); + fg.addAttribute("address.city"); + fg.addAttribute("address.postalCode"); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, fg); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, fg); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); - assertTrue(phoneTracker._persistence_isAttributeFetched("number")); - assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); + assertTrue(phoneTracker._persistence_isAttributeFetched("number")); + assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -208,147 +216,163 @@ @Test public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup empGroup = new FetchGroup(); - empGroup.addAttribute("firstName"); - empGroup.addAttribute("lastName"); - empGroup.addAttribute("address"); + // Define the fields to be fetched on Employee + FetchGroup empGroup = new FetchGroup(); + empGroup.addAttribute("firstName"); + empGroup.addAttribute("lastName"); + empGroup.addAttribute("address"); - // Define the fields to be fetched on Address - FetchGroup addressGroup = new FetchGroup(); - addressGroup.addAttribute("city"); - addressGroup.addAttribute("postalCode"); + // Define the fields to be fetched on Address + FetchGroup addressGroup = new FetchGroup(); + addressGroup.addAttribute("city"); + addressGroup.addAttribute("postalCode"); - empGroup.addAttribute("address", addressGroup); + empGroup.addAttribute("address", addressGroup); -// empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false); - FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); - // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group - fullPhone.addAttribute("owner.id"); - empGroup.addAttribute("phoneNumbers", fullPhone); + //empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false); + FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); + // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group + fullPhone.addAttribute("owner.id"); + empGroup.addAttribute("phoneNumbers", fullPhone); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, empGroup); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, empGroup); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup()); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup()); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void dynamicFetchGroup_EmployeeAddressEmptyPhone() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup empGroup = new FetchGroup(); - empGroup.addAttribute("firstName"); - empGroup.addAttribute("lastName"); - empGroup.addAttribute("address"); + // Define the fields to be fetched on Employee + FetchGroup empGroup = new FetchGroup(); + empGroup.addAttribute("firstName"); + empGroup.addAttribute("lastName"); + empGroup.addAttribute("address"); - // Define the fields to be fetched on Address - FetchGroup addressGroup = new FetchGroup(); - addressGroup.addAttribute("city"); - addressGroup.addAttribute("postalCode"); + // Define the fields to be fetched on Address + FetchGroup addressGroup = new FetchGroup(); + addressGroup.addAttribute("city"); + addressGroup.addAttribute("postalCode"); - empGroup.addAttribute("address", addressGroup); - // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group - FetchGroup ownerId = new FetchGroup(); - ownerId.addAttribute("owner.id"); - empGroup.addAttribute("phoneNumbers", ownerId); + empGroup.addAttribute("address", addressGroup); + // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group + FetchGroup ownerId = new FetchGroup(); + ownerId.addAttribute("owner.id"); + empGroup.addAttribute("phoneNumbers", ownerId); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, empGroup); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, empGroup); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); - assertFalse(phoneTracker._persistence_isAttributeFetched("number")); - assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); + assertFalse(phoneTracker._persistence_isAttributeFetched("number")); + assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); - phone.getNumber(); + phone.getNumber(); - assertTrue(phoneTracker._persistence_isAttributeFetched("number")); - assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode")); + assertTrue(phoneTracker._persistence_isAttributeFetched("number")); + assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode")); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleDefaultFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleDefaultFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleDefaultFetchGroupTests.java (working copy) @@ -101,116 +101,136 @@ @Test public void findDefaultFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Employee emp = minimumEmployee(em); + Employee emp = minimumEmployee(em); + assertNotNull(emp); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertDefaultFetched(emp); - assertNotNull(emp); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertDefaultFetched(emp); + assertNotFetchedAttribute(emp, "salary"); + emp.getSalary(); - assertNotFetchedAttribute(emp, "salary"); - emp.getSalary(); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetchedAttribute(emp, "salary"); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetchedAttribute(emp, "salary"); + assertNoFetchGroup(emp.getAddress()); - assertNoFetchGroup(emp.getAddress()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); - } + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - if (emp.getManager() != null) { - assertDefaultFetched(emp.getManager()); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getManager() != null) { + assertDefaultFetched(emp.getManager()); + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void singleResultDefaultFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertNotNull(emp); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertDefaultFetched(emp); + assertDefaultFetched(emp); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetchedAttribute(emp, "salary"); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); - } + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if (emp.getManager() != null) { - assertDefaultFetched(emp.getManager()); - assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getManager() != null) { + assertDefaultFetched(emp.getManager()); + assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - } @Test public void resultListDefaultFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); + List emps = query.getResultList(); - List emps = query.getResultList(); + assertNotNull(emps); + assertEquals(1, emps.size()); - assertNotNull(emps); - assertEquals(1, emps.size()); + Employee emp = emps.get(0); - Employee emp = emps.get(0); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertDefaultFetched(emp); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertDefaultFetched(emp); + emp.getSalary(); - emp.getSalary(); + assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - assertNoFetchGroup(emp.getAddress()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + if (emp.getManager() != null) { + assertDefaultFetched(emp.getManager()); + assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - if (emp.getManager() != null) { - assertDefaultFetched(emp.getManager()); - assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } - } @Test @@ -224,248 +244,296 @@ } void internalResultListWithJoinFetchAddress(boolean addAddressToFetchGroup) { EntityManager em = createEntityManager(); + try { + beginTransaction(em); + Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + FetchGroup fg = null; + if(addAddressToFetchGroup) { + // that returns clone of the default fetch group + fg = employeeDescriptor.getFetchGroupManager().createDefaultFetchGroup(); + fg.addAttribute("address"); + query.setHint(QueryHints.FETCH_GROUP, fg); + } + Employee emp = (Employee)query.getSingleResult(); + int nSql = 2; + if(!addAddressToFetchGroup) { + // An extra sql to read employee's Address - + // because address attribute is not in the fetch group the Address object was not built + // by join fetch - though the db row for address was read in. + // + // yet another extra sql generated when the whole employee object is read when address is set. + nSql = nSql + 2; + } - FetchGroup fg = null; - if(addAddressToFetchGroup) { - // that returns clone of the default fetch group - fg = employeeDescriptor.getFetchGroupManager().createDefaultFetchGroup(); - fg.addAttribute("address"); - query.setHint(QueryHints.FETCH_GROUP, fg); - } - Employee emp = (Employee)query.getSingleResult(); - int nSql = 2; - if(!addAddressToFetchGroup) { - // An extra sql to read employee's Address - - // because address attribute is not in the fetch group the Address object was not built - // by join fetch - though the db row for address was read in. - // - // yet another extra sql generated when the whole employee object is read when address is set. - nSql = nSql + 2; - } + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if(addAddressToFetchGroup) { + assertFetched(emp, fg); + } else { + // the whole object has been instantiated when address has been set + assertNoFetchGroup(emp); + } - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if(addAddressToFetchGroup) { - assertFetched(emp, fg); - } else { - // the whole object has been instantiated when address has been set + // instantiates the whole object - unless already instantiated + emp.getSalary(); + assertNoFetchGroup(emp); - } + if(addAddressToFetchGroup) { + nSql++; + } + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // instantiates the whole object - unless already instantiated - emp.getSalary(); + assertNoFetchGroup(emp.getAddress()); + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); - if(addAddressToFetchGroup) { - nSql++; - } - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } + assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + if (emp.getManager() != null) { + assertDefaultFetched(emp.getManager()); + assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - if (emp.getManager() != null) { - assertDefaultFetched(emp.getManager()); - assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } } @Test public void singleResultNoFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); - assertNull(getFetchGroup(query)); - assertNotNull(employeeDescriptor.getFetchGroupManager().getDefaultFetchGroup()); + assertNull(getFetchGroup(query)); + assertNotNull(employeeDescriptor.getFetchGroupManager().getDefaultFetchGroup()); - query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false"); - assertNull(getFetchGroup(query)); + query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false"); + assertNull(getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertNotNull(emp); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); - assertNoFetchGroup(emp.getAddress()); + assertNotNull(emp); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); + assertNoFetchGroup(emp.getAddress()); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } + + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void resultListNoFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false"); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false"); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1, emps.size()); + assertNotNull(emps); + assertEquals(1, emps.size()); - Employee emp = emps.get(0); + Employee emp = emps.get(0); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp); + assertNoFetchGroup(emp.getAddress()); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void emptyFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - // Use q query since find will only use default fetch group - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup emptyFG = new FetchGroup("empty@" + System.currentTimeMillis()); - query.setHint(QueryHints.FETCH_GROUP, emptyFG); + // Use q query since find will only use default fetch group + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup emptyFG = new FetchGroup("empty@" + System.currentTimeMillis()); + query.setHint(QueryHints.FETCH_GROUP, emptyFG); - assertEquals(emptyFG, getFetchGroup(query)); + assertEquals(emptyFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertFetched(emp, emptyFG); + assertFetched(emp, emptyFG); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); - phone.getAreaCode(); - assertNoFetchGroup(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + phone.getAreaCode(); + assertNoFetchGroup(phone); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void managerFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minimumEmployeeId(em)); - - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + //Use q query since find will only use default fetch group + //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + //query.setParameter("ID", minimumEmployeeId(em)); + + //Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - query.setHint(QueryHints.FETCH_GROUP, managerFG); - query.setHint(QueryHints.LEFT_FETCH, "e.manager"); + query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.LEFT_FETCH, "e.manager"); - assertEquals(managerFG, getFetchGroup(query)); + assertEquals(managerFG, getFetchGroup(query)); - List employees = query.getResultList(); - Employee emp = (Employee)employees.get(0); + List employees = query.getResultList(); + Employee emp = (Employee)employees.get(0); - assertFetched(emp, managerFG); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getManager(); + emp.getManager(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, managerFG); - emp.getLastName(); + emp.getLastName(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - int numPhones = 0; - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + int numPhones = 0; + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); - phone.getAreaCode(); + phone.getAreaCode(); - assertNoFetchGroup(phone); - numPhones++; + assertNoFetchGroup(phone); + numPhones++; + } + // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group + assertEquals(3 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group - assertEquals(3 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void employeeNamesFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - int minId = minimumEmployeeId(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int minId = minimumEmployeeId(em); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Use q query since find will only use default fetch group - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minId); + // Use q query since find will only use default fetch group + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minId); - FetchGroup namesFG = new FetchGroup(); - namesFG.addAttribute("firstName"); - namesFG.addAttribute("lastName"); - query.setHint(QueryHints.FETCH_GROUP, namesFG); + FetchGroup namesFG = new FetchGroup(); + namesFG.addAttribute("firstName"); + namesFG.addAttribute("lastName"); + query.setHint(QueryHints.FETCH_GROUP, namesFG); - assertNotNull(getFetchGroup(query)); - assertSame(namesFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(namesFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getId(); - emp.getFirstName(); - emp.getLastName(); - emp.getVersion(); + emp.getId(); + emp.getFirstName(); + emp.getLastName(); + emp.getVersion(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getGender(); - emp.getSalary(); + emp.getGender(); + emp.getSalary(); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - int numPhones = 0; - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + int numPhones = 0; + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); - phone.getAreaCode(); + phone.getAreaCode(); - assertNoFetchGroup(phone); - numPhones++; - } - // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group - assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(phone); + numPhones++; + } + // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group + assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if(emp.getManager() != null) { - assertEquals(5 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertDefaultFetched(emp.getManager()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if(emp.getManager() != null) { + assertEquals(5 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertDefaultFetched(emp.getManager()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -553,33 +621,41 @@ } void internalJoinFetchEmployeeAddressPhoneWithDynamicFetchGroup(boolean addAddressToFetchGroup) { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.id FROM PhoneNumber p)"); + Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.id FROM PhoneNumber p)"); - FetchGroup fetchGroup = new FetchGroup("names"); - fetchGroup.addAttribute("firstName"); - fetchGroup.addAttribute("lastName"); - if(addAddressToFetchGroup) { - fetchGroup.addAttribute("address"); - } - query.setHint(QueryHints.FETCH_GROUP, fetchGroup); + FetchGroup fetchGroup = new FetchGroup("names"); + fetchGroup.addAttribute("firstName"); + fetchGroup.addAttribute("lastName"); + if(addAddressToFetchGroup) { + fetchGroup.addAttribute("address"); + } + query.setHint(QueryHints.FETCH_GROUP, fetchGroup); - List emps = query.getResultList(); - assertNotNull(emps); + List emps = query.getResultList(); + assertNotNull(emps); - if(addAddressToFetchGroup) { - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - assertEquals(1 + 2*emps.size(), getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } - for (Employee emp : emps) { if(addAddressToFetchGroup) { - assertFetched(emp, fetchGroup); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } else { - // the whole object has been instantiated when address has been set - assertNoFetchGroup(emp); + assertEquals(1 + 2*emps.size(), getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } + for (Employee emp : emps) { + if(addAddressToFetchGroup) { + assertFetched(emp, fetchGroup); + } else { + // the whole object has been instantiated when address has been set + assertNoFetchGroup(emp); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); + } } public static class EmployeeCustomizer implements DescriptorCustomizer { Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleFetchGroupTests.java (working copy) @@ -55,8 +55,6 @@ suite.addTest(new SimpleFetchGroupTests("findNoFetchGroup")); suite.addTest(new SimpleFetchGroupTests("singleResultNoFetchGroup")); suite.addTest(new SimpleFetchGroupTests("resultListNoFetchGroup")); - suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup")); - suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary")); suite.addTest(new SimpleFetchGroupTests("singleResultEmptyFetchGroup")); suite.addTest(new SimpleFetchGroupTests("resultListEmptyFetchGroup")); suite.addTest(new SimpleFetchGroupTests("resultListPeriodFetchGroup")); @@ -65,11 +63,14 @@ suite.addTest(new SimpleFetchGroupTests("employeeNamesFetchGroup")); suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup")); suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup")); - suite.addTest(new SimpleFetchGroupTests("verifyUnfetchedAttributes")); suite.addTest(new SimpleFetchGroupTests("verifyFetchedRelationshipAttributes")); suite.addTest(new SimpleFetchGroupTests("detachedByClosingEntityManagerObjectWithFetchGroup")); - suite.addTest(new SimpleFetchGroupTests("explicitlyDetachedObjectWithFetchGroup")); - + if (!isJPA10()) { + suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup")); + suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary")); + suite.addTest(new SimpleFetchGroupTests("verifyUnfetchedAttributes")); + suite.addTest(new SimpleFetchGroupTests("explicitlyDetachedObjectWithFetchGroup")); + } return suite; } @@ -176,177 +177,203 @@ @Test public void findEmptyFetchGroup() throws Exception { EntityManager em = createEntityManager(); - int minId = minimumEmployeeId(em); + try { + beginTransaction(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int minId = minimumEmployeeId(em); - Map properties = new HashMap(); - FetchGroup emptyFG = new FetchGroup(); - properties.put(QueryHints.FETCH_GROUP, emptyFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - Employee emp = em.find(Employee.class, minId, properties); + Map properties = new HashMap(); + FetchGroup emptyFG = new FetchGroup(); + properties.put(QueryHints.FETCH_GROUP, emptyFG); - assertNotNull(emp); - assertFetched(emp, emptyFG); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + Employee emp = em.find(Employee.class, minId, properties); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + assertNotNull(emp); + assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - emp.getSalary(); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertFetchedAttribute(emp, "salary"); + emp.getSalary(); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertFetchedAttribute(emp, "salary"); - emp.getAddress(); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + emp.getAddress(); - emp.getPhoneNumbers().size(); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - } + emp.getPhoneNumbers().size(); - if (emp.getManager() != null) { - assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + + if (emp.getManager() != null) { + assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + }finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception { EntityManager em = createEntityManager(); - int minId = minimumEmployeeId(em); + try { + beginTransaction(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int minId = minimumEmployeeId(em); - Map properties = new HashMap(); - FetchGroup emptyFG = new FetchGroup(); - properties.put(QueryHints.FETCH_GROUP, emptyFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - Employee emp = em.find(Employee.class, minId, properties); + Map properties = new HashMap(); + FetchGroup emptyFG = new FetchGroup(); + properties.put(QueryHints.FETCH_GROUP, emptyFG); - assertNotNull(emp); - assertFetched(emp, emptyFG); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + Employee emp = em.find(Employee.class, minId, properties); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.setSalary(1); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertFetchedAttribute(emp, "salary"); + emp.setSalary(1); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertFetchedAttribute(emp, "salary"); - emp.getAddress(); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + emp.getAddress(); - emp.getPhoneNumbers().size(); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + emp.getPhoneNumbers().size(); + + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void singleResultEmptyFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup emptyFG = new FetchGroup(); - query.setHint(QueryHints.FETCH_GROUP, emptyFG); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup emptyFG = new FetchGroup(); + query.setHint(QueryHints.FETCH_GROUP, emptyFG); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertNotNull(emp); - assertFetched(emp, emptyFG); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); + assertFetchedAttribute(emp, "salary"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - emp.getAddress(); + emp.getAddress(); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - emp.getPhoneNumbers().size(); + emp.getPhoneNumbers().size(); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -356,59 +383,67 @@ @Test public void resultListEmptyFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup emptyFG = new FetchGroup(); - query.setHint(QueryHints.FETCH_GROUP, emptyFG); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup emptyFG = new FetchGroup(); + query.setHint(QueryHints.FETCH_GROUP, emptyFG); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1, emps.size()); + assertNotNull(emps); + assertEquals(1, emps.size()); - Employee emp = emps.get(0); + Employee emp = emps.get(0); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, emptyFG); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); - assertNoFetchGroup(emp); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetchedAttribute(emp, "salary"); + assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } /** @@ -417,209 +452,241 @@ @Test public void resultListPeriodFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup fg = new FetchGroup(); - fg.addAttribute("period"); - query.setHint(QueryHints.FETCH_GROUP, fg); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup fg = new FetchGroup(); + fg.addAttribute("period"); + query.setHint(QueryHints.FETCH_GROUP, fg); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1, emps.size()); + assertNotNull(emps); + assertEquals(1, emps.size()); - Employee emp = emps.get(0); + Employee emp = emps.get(0); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, fg); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, fg); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); - assertNoFetchGroup(emp); + assertFetchedAttribute(emp, "salary"); + assertNoFetchGroup(emp); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void managerFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minimumEmployeeId(em)); - - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + // Use q query since find will only use default fetch group + //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + //query.setParameter("ID", minimumEmployeeId(em)); + + // Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.FETCH_GROUP, managerFG); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertFetched(emp, managerFG); -// int nSqlBeforeGetManager = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); - // manager hasn't been instantiated yet - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - int nSqlToAdd = 0; - if (emp.getManager() != null) { - assertFetchedAttribute(emp, "manager"); - // additional sql to select the manager - nSqlToAdd++; - } - assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // acuses instantioation of the whole object - emp.getLastName(); + assertFetched(emp, managerFG); + //int nSqlBeforeGetManager = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); + // manager hasn't been instantiated yet + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + int nSqlToAdd = 0; + if (emp.getManager() != null) { + assertFetchedAttribute(emp, "manager"); + // additional sql to select the manager + nSqlToAdd++; + } + assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // acuses instantioation of the whole object + emp.getLastName(); - assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + + assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void managerFetchGroupWithJoinFetch() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); -// int minId = minimumEmployeeId(em); -// assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + //int minId = minimumEmployeeId(em); + //assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minId); + // Use q query since find will only use default fetch group + //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + //query.setParameter("ID", minId); - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + // Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - query.setHint(QueryHints.FETCH_GROUP, managerFG); - query.setHint(QueryHints.LEFT_FETCH, "e.manager"); + query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.LEFT_FETCH, "e.manager"); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertFetched(emp, managerFG); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // manager (if not null) is instantiated by the fetch group, before emp.getManager call. - emp.getManager(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // instantiates the whole object - emp.getLastName(); + assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // manager (if not null) is instantiated by the fetch group, before emp.getManager call. + emp.getManager(); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // instantiates the whole object + emp.getLastName(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void employeeNamesFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - int minId = minimumEmployeeId(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int minId = minimumEmployeeId(em); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Use q query since find will only use default fetch group - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minId); - FetchGroup namesFG = new FetchGroup(); - namesFG.addAttribute("firstName"); - namesFG.addAttribute("lastName"); + // Use q query since find will only use default fetch group + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minId); + FetchGroup namesFG = new FetchGroup(); + namesFG.addAttribute("firstName"); + namesFG.addAttribute("lastName"); - query.setHint(QueryHints.FETCH_GROUP, namesFG); + query.setHint(QueryHints.FETCH_GROUP, namesFG); - assertNotNull(getFetchGroup(query)); - assertSame(namesFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(namesFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getId(); - emp.getFirstName(); - emp.getLastName(); - emp.getVersion(); + emp.getId(); + emp.getFirstName(); + emp.getLastName(); + emp.getVersion(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getGender(); - emp.getSalary(); + emp.getGender(); + emp.getSalary(); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); - } - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if (emp.getManager() != null) { - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getManager()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getManager() != null) { + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getManager()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -658,29 +725,36 @@ @Test public void verifyUnfetchedAttributes() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); + TypedQuery q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class); + FetchGroup fg = new FetchGroup("Employee.empty"); + q.setHint(QueryHints.FETCH_GROUP, fg); + Employee emp = q.getSingleResult(); - TypedQuery q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class); - FetchGroup fg = new FetchGroup("Employee.empty"); - q.setHint(QueryHints.FETCH_GROUP, fg); - Employee emp = q.getSingleResult(); + assertNotNull(emp); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNotNull(emp); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + // This check using the mapping returns a default (empty) IndirectList + /*OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers"); + IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp); + assertNotNull(phones); + assertTrue(phones.isInstantiated()); + assertEquals(0, phones.size()); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/ - // This check using the mapping returns a default (empty) IndirectList -/* OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers"); - IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp); - assertNotNull(phones); - assertTrue(phones.isInstantiated()); - assertEquals(0, phones.size()); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/ + IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers(); + assertFalse(phonesIL.isInstantiated()); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers(); - assertFalse(phonesIL.isInstantiated()); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - assertTrue(emp.getPhoneNumbers().size() > 0); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertTrue(emp.getPhoneNumbers().size() > 0); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); + } } @Test @@ -725,20 +799,27 @@ @Test public void explicitlyDetachedObjectWithFetchGroup() { EntityManager em = createEntityManager(); + try { + beginTransaction(em); + FetchGroup fg = new FetchGroup(); + fg.addAttribute("firstName"); + fg.addAttribute("lastName"); - FetchGroup fg = new FetchGroup(); - fg.addAttribute("firstName"); - fg.addAttribute("lastName"); + Map hints = new HashMap(); + hints.put(QueryHints.FETCH_GROUP, fg); - Map hints = new HashMap(); - hints.put(QueryHints.FETCH_GROUP, fg); - - Employee emp = minimumEmployee(em, hints); - em.detach(emp); - assertFetched(emp, fg); - - // trigger the fetch group - emp.getSalary(); - assertNoFetchGroup(emp); + Employee emp = minimumEmployee(em, hints); + em.detach(emp); + assertFetched(emp, fg); + + // trigger the fetch group + emp.getSalary(); + assertNoFetchGroup(emp); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); + } } } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleNamedFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleNamedFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleNamedFetchGroupTests.java (working copy) @@ -269,48 +269,55 @@ @Test public void managerFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); + // Use q query since find will only use default fetch group + // Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + // query.setParameter("ID", minimumEmployeeId(em)); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minimumEmployeeId(em)); + // Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + query.setHint(QueryHints.FETCH_GROUP, managerFG); - query.setHint(QueryHints.FETCH_GROUP, managerFG); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + Employee emp = (Employee) query.getSingleResult(); - Employee emp = (Employee) query.getSingleResult(); + assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + int nSqlToAdd = 0; + if (emp.getManager() != null) { + assertFetchedAttribute(emp, "manager"); + // additional sql to select the manager + nSqlToAdd++; + } + + assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, managerFG); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - int nSqlToAdd = 0; - if (emp.getManager() != null) { - assertFetchedAttribute(emp, "manager"); - // additional sql to select the manager - nSqlToAdd++; - } - - assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + // instantiates the whole object + emp.getLastName(); - // instantiates the whole object - emp.getLastName(); + assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleSerializeFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleSerializeFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleSerializeFetchGroupTests.java (working copy) @@ -12,6 +12,9 @@ ******************************************************************************/ package org.eclipse.persistence.testing.tests.jpa.fetchgroups; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; @@ -65,8 +68,6 @@ suite.addTest(new SimpleSerializeFetchGroupTests("testSetup")); suite.addTest(new SimpleSerializeFetchGroupTests("verifyWriteReplaceOnFetchGroup")); - suite.addTest(new SimpleSerializeFetchGroupTests("findMinimalFetchGroup")); - suite.addTest(new SimpleSerializeFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary")); suite.addTest(new SimpleSerializeFetchGroupTests("verifyAddAttributeInDetachedEntityFetchGroup")); suite.addTest(new SimpleSerializeFetchGroupTests("singleResultEmptyFetchGroup")); suite.addTest(new SimpleSerializeFetchGroupTests("resultListEmptyFetchGroup")); @@ -76,19 +77,23 @@ suite.addTest(new SimpleSerializeFetchGroupTests("employeeNamesFetchGroup")); suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup")); suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup")); - suite.addTest(new SimpleSerializeFetchGroupTests("verifyUnfetchedAttributes")); suite.addTest(new SimpleSerializeFetchGroupTests("verifyFetchedRelationshipAttributes")); - suite.addTest(new SimpleSerializeFetchGroupTests("simpleSerializeAndMerge")); - suite.addTest(new SimpleSerializeFetchGroupTests("partialMerge")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge2")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPk")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPkUseFullGroup")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPk")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPkUseFullGroup")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyNoCascade")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadePrivateParts")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadeAllParts")); + if (!isJPA10()) { + suite.addTest(new SimpleSerializeFetchGroupTests("findMinimalFetchGroup")); + suite.addTest(new SimpleSerializeFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary")); + suite.addTest(new SimpleSerializeFetchGroupTests("verifyUnfetchedAttributes")); + suite.addTest(new SimpleSerializeFetchGroupTests("simpleSerializeAndMerge")); + suite.addTest(new SimpleSerializeFetchGroupTests("partialMerge")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge2")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPk")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPkUseFullGroup")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPk")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPkUseFullGroup")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyNoCascade")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadePrivateParts")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadeAllParts")); + } return suite; } @@ -96,10 +101,10 @@ @Test public void verifyWriteReplaceOnFetchGroup() throws Exception { EntityFetchGroup fg = new EntityFetchGroup(new String[]{"basic", "a"}); -// fg.addAttribute("basic"); -// fg.addAttribute("a.b"); + //fg.addAttribute("basic"); + //fg.addAttribute("a.b"); -// assertTrue(fg.getClass() == FetchGroup.class); + //assertTrue(fg.getClass() == FetchGroup.class); FetchGroup serFG = serialize(fg); @@ -110,15 +115,15 @@ AttributeItem basicFI = serFG.getItem("basic"); assertNotNull(basicFI); -// assertTrue(basicFI instanceof DetachedFetchItem); + //assertTrue(basicFI instanceof DetachedFetchItem); AttributeItem aFI = serFG.getItem("a"); assertNotNull(aFI); -// assertTrue(aFI instanceof DetachedFetchItem); + //assertTrue(aFI instanceof DetachedFetchItem); // serialized EntityFetchGroup is always flat - doesn't have nested groups. assertNull(aFI.getGroup()); -/* assertNotNull(aFI.getGroup()); + /*assertNotNull(aFI.getGroup()); assertTrue(aFI.getGroup() instanceof EntityFetchGroup); EntityFetchGroup aEFG = (EntityFetchGroup) aFI.getGroup(); assertNull(aEFG.getParent()); @@ -127,7 +132,7 @@ AttributeItem bFI = aEFG.getItem("b"); assertNotNull(bFI); -// assertTrue(bFI instanceof DetachedFetchItem); + //assertTrue(bFI instanceof DetachedFetchItem); assertNull(bFI.getGroup());*/ } @@ -194,57 +199,65 @@ public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception { EntityManager em = createEntityManager(); int minId = minimumEmployeeId(em); + try { + beginTransaction(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - Map properties = new HashMap(); - FetchGroup emptyFG = new FetchGroup(); - properties.put(QueryHints.FETCH_GROUP, emptyFG); + Map properties = new HashMap(); + FetchGroup emptyFG = new FetchGroup(); + properties.put(QueryHints.FETCH_GROUP, emptyFG); - Employee emp = em.find(Employee.class, minId, properties); + Employee emp = em.find(Employee.class, minId, properties); - assertNotNull(emp); - assertFetched(emp, emptyFG); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - emp.setSalary(1); + emp.setSalary(1); - assertFetchedAttribute(emp, "salary"); + assertFetchedAttribute(emp, "salary"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - emp.getAddress(); + emp.getAddress(); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - emp.getPhoneNumbers().size(); + emp.getPhoneNumbers().size(); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -256,96 +269,104 @@ public void verifyAddAttributeInDetachedEntityFetchGroup() { EntityFetchGroup detFG = new EntityFetchGroup(new String[]{"basic", "a"}); -// detFG.addAttribute("basic"); -// detFG.addAttribute("a.b"); + //detFG.addAttribute("basic"); + //detFG.addAttribute("a.b"); -// assertNull(detFG.getParent()); + //assertNull(detFG.getParent()); assertEquals(2, detFG.getItems().size()); AttributeItem basicItem = detFG.getItem("basic"); assertNotNull(basicItem); assertEquals("basic", basicItem.getAttributeName()); -// assertTrue(basicItem instanceof DetachedFetchItem); + //assertTrue(basicItem instanceof DetachedFetchItem); assertNull(basicItem.getGroup()); assertSame(detFG, basicItem.getParent()); -// assertFalse(basicItem.useDefaultFetchGroup()); + //assertFalse(basicItem.useDefaultFetchGroup()); AttributeItem aItem = detFG.getItem("a"); assertNotNull(aItem); assertEquals("a", aItem.getAttributeName()); -// assertTrue(aItem instanceof DetachedFetchItem); + //assertTrue(aItem instanceof DetachedFetchItem); // serialized EntityFetchGroup is always flat - doesn't have nested groups. -//// assertNull(aItem.getGroup()); + //assertNull(aItem.getGroup()); assertNull(aItem.getGroup()); assertSame(detFG, aItem.getParent()); -// assertFalse(aItem.useDefaultFetchGroup()); -// assertTrue(aItem.getGroup() instanceof EntityFetchGroup); + //assertFalse(aItem.useDefaultFetchGroup()); + //assertTrue(aItem.getGroup() instanceof EntityFetchGroup); -// EntityFetchGroup aFG = (EntityFetchGroup) aItem.getGroup(); + //EntityFetchGroup aFG = (EntityFetchGroup) aItem.getGroup(); -// assertEquals(1, aFG.getItems().size()); + //assertEquals(1, aFG.getItems().size()); -// AttributeItem bItem = aFG.getItem("b"); -// assertNotNull(bItem); -// assertEquals("b", bItem.getAttributeName()); -// assertTrue(bItem instanceof DetachedFetchItem); - // assertNull(bItem.getGroup()); -// assertSame(aFG, bItem.getParent()); -// assertFalse(bItem.useDefaultFetchGroup()); + //AttributeItem bItem = aFG.getItem("b"); + //assertNotNull(bItem); + //assertEquals("b", bItem.getAttributeName()); + //assertTrue(bItem instanceof DetachedFetchItem); + //assertNull(bItem.getGroup()); + //assertSame(aFG, bItem.getParent()); + //assertFalse(bItem.useDefaultFetchGroup()); } @Test public void singleResultEmptyFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup emptyFG = new FetchGroup(); - query.setHint(QueryHints.FETCH_GROUP, emptyFG); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup emptyFG = new FetchGroup(); + query.setHint(QueryHints.FETCH_GROUP, emptyFG); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertNotNull(emp); - assertFetched(emp, emptyFG); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); + assertFetchedAttribute(emp, "salary"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - emp.getAddress(); + emp.getAddress(); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - emp.getPhoneNumbers().size(); + emp.getPhoneNumbers().size(); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -355,59 +376,67 @@ @Test public void resultListEmptyFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup emptyFG = new FetchGroup(); - query.setHint(QueryHints.FETCH_GROUP, emptyFG); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup emptyFG = new FetchGroup(); + query.setHint(QueryHints.FETCH_GROUP, emptyFG); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1, emps.size()); + assertNotNull(emps); + assertEquals(1, emps.size()); - Employee emp = emps.get(0); + Employee emp = emps.get(0); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, emptyFG); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); - assertNoFetchGroup(emp); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetchedAttribute(emp, "salary"); + assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } /** @@ -416,209 +445,241 @@ @Test public void resultListPeriodFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup fg = new FetchGroup(); - fg.addAttribute("period"); - query.setHint(QueryHints.FETCH_GROUP, fg); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup fg = new FetchGroup(); + fg.addAttribute("period"); + query.setHint(QueryHints.FETCH_GROUP, fg); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1, emps.size()); + assertNotNull(emps); + assertEquals(1, emps.size()); - Employee emp = emps.get(0); + Employee emp = emps.get(0); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, fg); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, fg); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); - assertNoFetchGroup(emp); + assertFetchedAttribute(emp, "salary"); + assertNoFetchGroup(emp); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void managerFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minimumEmployeeId(em)); + // Use q query since find will only use default fetch group + //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + //query.setParameter("ID", minimumEmployeeId(em)); - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + // Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.FETCH_GROUP, managerFG); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertFetched(emp, managerFG); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // manager (if not null) hasn't been instantiated yet. - int nSqlToAdd = 0; - if (emp.getManager() != null) { - assertFetchedAttribute(emp, "manager"); - // additional sql to select the manager - nSqlToAdd++; - } - - assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // manager (if not null) hasn't been instantiated yet. + int nSqlToAdd = 0; + if (emp.getManager() != null) { + assertFetchedAttribute(emp, "manager"); + // additional sql to select the manager + nSqlToAdd++; + } + + assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getLastName(); + emp.getLastName(); - assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + + assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void managerFetchGroupWithJoinFetch() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); -// int minId = minimumEmployeeId(em); -// assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + //int minId = minimumEmployeeId(em); + //assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minId); + // Use q query since find will only use default fetch group + //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + //query.setParameter("ID", minId); - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + // Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - query.setHint(QueryHints.FETCH_GROUP, managerFG); - query.setHint(QueryHints.LEFT_FETCH, "e.manager"); + query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.LEFT_FETCH, "e.manager"); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertFetched(emp, managerFG); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // manager has been already instantiated by the query. - emp.getManager(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // instantiates the whiole object - emp.getLastName(); + assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // manager has been already instantiated by the query. + emp.getManager(); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // instantiates the whiole object + emp.getLastName(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void employeeNamesFetchGroup() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - int minId = minimumEmployeeId(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int minId = minimumEmployeeId(em); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Use q query since find will only use default fetch group - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minId); - FetchGroup namesFG = new FetchGroup(); - namesFG.addAttribute("firstName"); - namesFG.addAttribute("lastName"); + // Use q query since find will only use default fetch group + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minId); + FetchGroup namesFG = new FetchGroup(); + namesFG.addAttribute("firstName"); + namesFG.addAttribute("lastName"); - query.setHint(QueryHints.FETCH_GROUP, namesFG); + query.setHint(QueryHints.FETCH_GROUP, namesFG); - assertNotNull(getFetchGroup(query)); - assertSame(namesFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(namesFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getId(); - emp.getFirstName(); - emp.getLastName(); - emp.getVersion(); + emp.getId(); + emp.getFirstName(); + emp.getLastName(); + emp.getVersion(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getGender(); - emp.getSalary(); + emp.getGender(); + emp.getSalary(); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); - } - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if (emp.getManager() != null) { - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getManager()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getManager() != null) { + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getManager()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -657,29 +718,37 @@ @Test public void verifyUnfetchedAttributes() throws Exception { EntityManager em = createEntityManager(); + try { + beginTransaction(em); - TypedQuery q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class); - FetchGroup fg = new FetchGroup("Employee.empty"); - q.setHint(QueryHints.FETCH_GROUP, fg); - Employee emp = q.getSingleResult(); + TypedQuery q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class); + FetchGroup fg = new FetchGroup("Employee.empty"); + q.setHint(QueryHints.FETCH_GROUP, fg); + Employee emp = q.getSingleResult(); - assertNotNull(emp); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // This check using the mapping returns a default (empty) IndirectList -/* OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers"); - IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp); - assertNotNull(phones); - assertTrue(phones.isInstantiated()); - assertEquals(0, phones.size()); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/ + // This check using the mapping returns a default (empty) IndirectList + /*OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers"); + IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp); + assertNotNull(phones); + assertTrue(phones.isInstantiated()); + assertEquals(0, phones.size()); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/ - IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers(); - assertFalse(phonesIL.isInstantiated()); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers(); + assertFalse(phonesIL.isInstantiated()); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertTrue(emp.getPhoneNumbers().size() > 0); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertTrue(emp.getPhoneNumbers().size() > 0); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); + } } @Test @@ -807,7 +876,7 @@ em.clear(); HashMap hints = new HashMap(2); hints.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly); -// hints.put(QueryHints.FETCH_GROUP, fetchGroup); + //hints.put(QueryHints.FETCH_GROUP, fetchGroup); Employee empShared = em.find(Employee.class, id, hints); assertEquals("newFirstName", empShared.getFirstName()); assertEquals("newLastName", empShared.getLastName()); @@ -855,7 +924,7 @@ closeEntityManager(em); } } -/* public void simpleSerializeAndMerge() throws Exception { + /*public void simpleSerializeAndMerge() throws Exception { EntityManager em = createEntityManager(); int id = minimumEmployeeId(em); // save the original Employee for clean up @@ -934,120 +1003,133 @@ public void partialMerge() throws Exception { EntityManager em = createEntityManager(); // Search for an Employee with an Address and Phone Numbers - TypedQuery query = em.createQuery("SELECT e FROM Employee e WHERE e.address IS NOT NULL AND e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class); - - // Load only its names and phone Numbers - FetchGroup fetchGroup = new FetchGroup(); - fetchGroup.addAttribute("firstName"); - fetchGroup.addAttribute("lastName"); - FetchGroup phonesFG = phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); - // that ensures the owner is not instantiated - phonesFG.addAttribute("owner.id"); - phonesFG.removeAttribute("status"); - phonesFG.setShouldLoad(true); - fetchGroup.addAttribute("phoneNumbers", phonesFG); - - // Make sure the FetchGroup also forces the relationships to be loaded - fetchGroup.setShouldLoad(true); - query.setHint(QueryHints.FETCH_GROUP, fetchGroup); - - Employee emp = query.getSingleResult(); - - // Detach Employee through Serialization - Employee detachedEmp = (Employee) SerializationHelper.clone(emp); - // Modify the detached Employee inverting the names, adding a phone number, and setting the salary - detachedEmp.setFirstName(emp.getLastName()); - detachedEmp.setLastName(emp.getFirstName()); - detachedEmp.addPhoneNumber(new PhoneNumber("TEST", "999", "999999")); - // NOte that salary was not part of the original FetchGroupdetachedEmp.setSalary(1); - detachedEmp.setSalary(1); - - beginTransaction(em); - // Merge the detached employee - em.merge(detachedEmp); - // Flush the changes to the database - em.flush(); - rollbackTransaction(em); + try { + beginTransaction(em); + TypedQuery query = em.createQuery("SELECT e FROM Employee e WHERE e.address IS NOT NULL AND e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class); + + // Load only its names and phone Numbers + FetchGroup fetchGroup = new FetchGroup(); + fetchGroup.addAttribute("firstName"); + fetchGroup.addAttribute("lastName"); + FetchGroup phonesFG = phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); + // that ensures the owner is not instantiated + phonesFG.addAttribute("owner.id"); + phonesFG.removeAttribute("status"); + phonesFG.setShouldLoad(true); + fetchGroup.addAttribute("phoneNumbers", phonesFG); + + // Make sure the FetchGroup also forces the relationships to be loaded + fetchGroup.setShouldLoad(true); + query.setHint(QueryHints.FETCH_GROUP, fetchGroup); + + Employee emp = query.getSingleResult(); + + // Detach Employee through Serialization + Employee detachedEmp = (Employee)clone(emp); + + // Modify the detached Employee inverting the names, adding a phone number, and setting the salary + detachedEmp.setFirstName(emp.getLastName()); + detachedEmp.setLastName(emp.getFirstName()); + detachedEmp.addPhoneNumber(new PhoneNumber("TEST", "999", "999999")); + // NOte that salary was not part of the original FetchGroupdetachedEmp.setSalary(1); + detachedEmp.setSalary(1); + + // Merge the detached employee + em.merge(detachedEmp); + // Flush the changes to the database + em.flush(); + } finally { + rollbackTransaction(em); + closeEntityManager(em); + } } public void copyGroupMerge() { // Search for an Employee with an Address and Phone Numbers EntityManager em = createEntityManager(); - TypedQuery query = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(ee.id) FROM Employee ee)", Employee.class); - Employee emp = query.getSingleResult(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - System.out.println(">>> Employee retrieved"); - - // Copy only its names and phone Numbers - AttributeGroup group = new CopyGroup(); - group.addAttribute("firstName"); - group.addAttribute("lastName"); - group.addAttribute("address"); - - Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - System.out.println(">>> Employee copied"); - - // Modify the detached Employee inverting the names, adding a phone number, and setting the salary - empCopy.setFirstName(emp.getLastName()); - empCopy.setLastName(emp.getFirstName()); - - // Note that salary was not part of the original FetchGroup - //empCopy.setSalary(1); - - beginTransaction(em); - // Merge the detached employee - em.merge(empCopy); - System.out.println(">>> Sparse merge complete"); - - // Flush the changes to the database - em.flush(); - System.out.println(">>> Flush complete"); - - rollbackTransaction(em); + try { + beginTransaction(em); + TypedQuery query = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(ee.id) FROM Employee ee)", Employee.class); + Employee emp = query.getSingleResult(); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + System.out.println(">>> Employee retrieved"); + + // Copy only its names and phone Numbers + AttributeGroup group = new CopyGroup(); + group.addAttribute("firstName"); + group.addAttribute("lastName"); + group.addAttribute("address"); + + Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + System.out.println(">>> Employee copied"); + + // Modify the detached Employee inverting the names, adding a phone number, and setting the salary + empCopy.setFirstName(emp.getLastName()); + empCopy.setLastName(emp.getFirstName()); + + // Note that salary was not part of the original FetchGroup + //empCopy.setSalary(1); + + // Merge the detached employee + em.merge(empCopy); + System.out.println(">>> Sparse merge complete"); + + // Flush the changes to the database + em.flush(); + System.out.println(">>> Flush complete"); + } finally { + rollbackTransaction(em); + closeEntityManager(em); + } } public void copyGroupMerge2() { // Search for an Employee with an Address and Phone Numbers EntityManager em = createEntityManager(); - TypedQuery query = em.createQuery("SELECT e FROM Employee e", Employee.class); - query.setHint(QueryHints.BATCH, "e.address"); - List employees = query.getResultList(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - System.out.println(">>> Employees retrieved"); - - // Copy only its names and phone Numbers - AttributeGroup group = new CopyGroup(); - group.addAttribute("firstName"); - group.addAttribute("lastName"); - group.addAttribute("address"); - - List employeesCopy = (List) em.unwrap(JpaEntityManager.class).copy(employees, group); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - System.out.println(">>> Employees copied"); - - beginTransaction(em); - for(Employee empCopy : employeesCopy) { - // Modify the detached Employee inverting the names, adding a phone number, and setting the salary - String firstName = empCopy.getFirstName(); - String lastName = empCopy.getLastName(); - empCopy.setFirstName(lastName); - empCopy.setLastName(firstName); - - // Note that salary was not part of the original FetchGroup - //empCopy.setSalary(1); + try { + beginTransaction(em); + TypedQuery query = em.createQuery("SELECT e FROM Employee e", Employee.class); + query.setHint(QueryHints.BATCH, "e.address"); + List employees = query.getResultList(); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + System.out.println(">>> Employees retrieved"); - // Merge the detached employee - em.merge(empCopy); + // Copy only its names and phone Numbers + AttributeGroup group = new CopyGroup(); + group.addAttribute("firstName"); + group.addAttribute("lastName"); + group.addAttribute("address"); + + List employeesCopy = (List) em.unwrap(JpaEntityManager.class).copy(employees, group); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + System.out.println(">>> Employees copied"); + + for(Employee empCopy : employeesCopy) { + // Modify the detached Employee inverting the names, adding a phone number, and setting the salary + String firstName = empCopy.getFirstName(); + String lastName = empCopy.getLastName(); + empCopy.setFirstName(lastName); + empCopy.setLastName(firstName); + + // Note that salary was not part of the original FetchGroup + //empCopy.setSalary(1); + + // Merge the detached employee + em.merge(empCopy); + } + System.out.println(">>> Sparse merge complete"); + + // Flush the changes to the database + em.flush(); + System.out.println(">>> Flush complete"); + + } finally { + rollbackTransaction(em); + closeEntityManager(em); } - System.out.println(">>> Sparse merge complete"); - - // Flush the changes to the database - em.flush(); - System.out.println(">>> Flush complete"); - - rollbackTransaction(em); } + @Test public void copyWithPk() { @@ -1069,7 +1151,7 @@ copyWithOrWithoutPk(true, true); } - void copyWithOrWithoutPk(boolean noPk, boolean useFullGroup) { + void copyWithOrWithoutPk(boolean noPk, boolean useFullGroup) { CopyGroup group = new CopyGroup(); if(noPk) { // setShouldResetPrimaryKey set to true means that: @@ -1140,11 +1222,11 @@ } EntityManager em = createEntityManager(); - Employee emp = minimumEmployee(em); - Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group); - - beginTransaction(em); try { + beginTransaction(em); + Employee emp = minimumEmployee(em); + Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group); + if(noPk) { assertNoFetchGroup(empCopy); assertNoFetchGroup(empCopy.getAddress()); @@ -1235,154 +1317,168 @@ void copyCascade(int cascadeDepth) { EntityManager em = createEntityManager(); - Query query = em.createQuery("SELECT e FROM Employee e"); - List employees = query.getResultList(); + try { + beginTransaction(em); + Query query = em.createQuery("SELECT e FROM Employee e"); + List employees = query.getResultList(); - CopyGroup group = new CopyGroup(); - if(cascadeDepth == CopyGroup.NO_CASCADE) { - group.dontCascade(); - } else if(cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - // default cascade depth setting - group.cascadePrivateParts(); - } else if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) { - group.cascadeAllParts(); - } else { - fail("Invalid cascadeDepth = " + cascadeDepth); - } - group.setShouldResetPrimaryKey(true); - - List employeesCopy; - if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - // In this case the objects should be copied one by one - each one using a new CopyGroup. - // That ensures most referenced object are original ones (not copies) - - // the only exception is privately owned objects in CASCADE_PRIVATE_PARTS case. - employeesCopy = new ArrayList(employees.size()); - for(Employee emp : employees) { - CopyGroup groupClone = group.clone(); - employeesCopy.add((Employee)em.unwrap(JpaEntityManager.class).copy(emp, groupClone)); + CopyGroup group = new CopyGroup(); + if(cascadeDepth == CopyGroup.NO_CASCADE) { + group.dontCascade(); + } else if(cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + // default cascade depth setting + group.cascadePrivateParts(); + } else if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) { + group.cascadeAllParts(); + } else { + fail("Invalid cascadeDepth = " + cascadeDepth); } - } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS - // In this case all objects should be copied using a single CopyGroup. - // That ensures identities of the copies: - // for instance if several employees referenced the same project, - // then all copies of these employees will reference the single copy of the project. - employeesCopy = (List)em.unwrap(JpaEntityManager.class).copy(employees, group); - } - - // IdentityHashSets will be used to verify copy identities - IdentityHashSet originalEmployees = new IdentityHashSet(); - IdentityHashSet copyEmployees = new IdentityHashSet(); - IdentityHashSet originalAddresses = new IdentityHashSet(); - IdentityHashSet copyAddresses = new IdentityHashSet(); - IdentityHashSet originalProjects = new IdentityHashSet(); - IdentityHashSet copyProjects = new IdentityHashSet(); - IdentityHashSet originalPhones = new IdentityHashSet(); - IdentityHashSet copyPhones = new IdentityHashSet(); - - int size = employees.size(); - for(int i=0; i < size; i++) { - Employee emp = employees.get(i); - Employee empCopy = employeesCopy.get(i); - if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) { - originalEmployees.add(emp); - copyEmployees.add(empCopy); + group.setShouldResetPrimaryKey(true); + + List employeesCopy; + if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + // In this case the objects should be copied one by one - each one using a new CopyGroup. + // That ensures most referenced object are original ones (not copies) - + // the only exception is privately owned objects in CASCADE_PRIVATE_PARTS case. + employeesCopy = new ArrayList(employees.size()); + for(Employee emp : employees) { + CopyGroup groupClone = group.clone(); + employeesCopy.add((Employee)em.unwrap(JpaEntityManager.class).copy(emp, groupClone)); + } } else { - // cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS - // In this case all Employees referenced by empCopyes are originals (manager and managed employees). - // Therefore if we add here each emp and empCopy to originalEmployees and copyEmployees respectively - // then copyEmployees will always contain all original managers and managed + plus all copies. - // Therefore in this case originalEmployees and copyEmployees will contain only references (managers and managed employees). + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS + // In this case all objects should be copied using a single CopyGroup. + // That ensures identities of the copies: + // for instance if several employees referenced the same project, + // then all copies of these employees will reference the single copy of the project. + employeesCopy = (List)em.unwrap(JpaEntityManager.class).copy(employees, group); } + + // IdentityHashSets will be used to verify copy identities + IdentityHashSet originalEmployees = new IdentityHashSet(); + IdentityHashSet copyEmployees = new IdentityHashSet(); + IdentityHashSet originalAddresses = new IdentityHashSet(); + IdentityHashSet copyAddresses = new IdentityHashSet(); + IdentityHashSet originalProjects = new IdentityHashSet(); + IdentityHashSet copyProjects = new IdentityHashSet(); + IdentityHashSet originalPhones = new IdentityHashSet(); + IdentityHashSet copyPhones = new IdentityHashSet(); + + int size = employees.size(); + for(int i=0; i < size; i++) { + Employee emp = employees.get(i); + Employee empCopy = employeesCopy.get(i); + if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) { + originalEmployees.add(emp); + copyEmployees.add(empCopy); + } else { + // cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS + // In this case all Employees referenced by empCopyes are originals (manager and managed employees). + // Therefore if we add here each emp and empCopy to originalEmployees and copyEmployees respectively + // then copyEmployees will always contain all original managers and managed + plus all copies. + // Therefore in this case originalEmployees and copyEmployees will contain only references (managers and managed employees). + } - if(emp.getAddress() == null) { - assertTrue("emp.getAddress() == null, but empCopy.getAddress() != null", empCopy.getAddress() == null); - } else { - originalAddresses.add(emp.getAddress()); - copyAddresses.add(empCopy.getAddress()); - if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - assertTrue("address has been copied", emp.getAddress() == empCopy.getAddress()); + if(emp.getAddress() == null) { + assertTrue("emp.getAddress() == null, but empCopy.getAddress() != null", empCopy.getAddress() == null); } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS - assertFalse("address has not been copied", emp.getAddress() == empCopy.getAddress()); + originalAddresses.add(emp.getAddress()); + copyAddresses.add(empCopy.getAddress()); + if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + assertTrue("address has been copied", emp.getAddress() == empCopy.getAddress()); + } else { + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS + assertFalse("address has not been copied", emp.getAddress() == empCopy.getAddress()); + } } - } - boolean same; - for(Project project : emp.getProjects()) { - originalProjects.add(project); - same = false; - for(Project projectCopy : empCopy.getProjects()) { - copyProjects.add(projectCopy); - if(!same && project == projectCopy) { - same = true; + boolean same; + for(Project project : emp.getProjects()) { + originalProjects.add(project); + same = false; + for(Project projectCopy : empCopy.getProjects()) { + copyProjects.add(projectCopy); + if(!same && project == projectCopy) { + same = true; + } } + if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + assertTrue("project has been copied", same); + } else { + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS + assertFalse("project has not been copied", same); + } } - if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - assertTrue("project has been copied", same); - } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS - assertFalse("project has not been copied", same); - } - } - for(Employee managedEmp : emp.getManagedEmployees()) { - originalEmployees.add(managedEmp); - same = false; - for(Employee managedEmpCopy : empCopy.getManagedEmployees()) { - copyEmployees.add(managedEmpCopy); - if(!same && managedEmp == managedEmpCopy) { - same = true; + for(Employee managedEmp : emp.getManagedEmployees()) { + originalEmployees.add(managedEmp); + same = false; + for(Employee managedEmpCopy : empCopy.getManagedEmployees()) { + copyEmployees.add(managedEmpCopy); + if(!same && managedEmp == managedEmpCopy) { + same = true; + } } + if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + assertTrue("managedEmployee has been copied", same); + } else { + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS + assertFalse("managedEmployee has not been copied", same); + } } - if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - assertTrue("managedEmployee has been copied", same); + + if(emp.getManager() == null) { + assertTrue("emp.getManager() == null, but empCopy.getManager() != null", empCopy.getManager() == null); } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS - assertFalse("managedEmployee has not been copied", same); + originalEmployees.add(emp.getManager()); + copyEmployees.add(empCopy.getManager()); + if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + assertTrue("manager has been copied", emp.getManager() == empCopy.getManager()); + } else { + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS + assertFalse("manager has not been copied", emp.getManager() == empCopy.getManager()); + } } - } - - if(emp.getManager() == null) { - assertTrue("emp.getManager() == null, but empCopy.getManager() != null", empCopy.getManager() == null); - } else { - originalEmployees.add(emp.getManager()); - copyEmployees.add(empCopy.getManager()); - if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - assertTrue("manager has been copied", emp.getManager() == empCopy.getManager()); - } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS - assertFalse("manager has not been copied", emp.getManager() == empCopy.getManager()); - } - } - // phoneNumbers is privately owned - for(PhoneNumber phone : emp.getPhoneNumbers()) { - originalPhones.add(phone); - same = false; - for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) { - copyPhones.add(phoneCopy); - if(!same && phone == phoneCopy) { - same = true; + // phoneNumbers is privately owned + for(PhoneNumber phone : emp.getPhoneNumbers()) { + originalPhones.add(phone); + same = false; + for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) { + copyPhones.add(phoneCopy); + if(!same && phone == phoneCopy) { + same = true; + } } + if(cascadeDepth == CopyGroup.NO_CASCADE) { + assertTrue("phone has been copied", same); + } else { + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS + assertFalse("phone has not been copied", same); + } } - if(cascadeDepth == CopyGroup.NO_CASCADE) { - assertTrue("phone has been copied", same); - } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS - assertFalse("phone has not been copied", same); - } } + + assertTrue("copyEmployees.size() == " + copyEmployees.size() + "; was expected " + originalEmployees.size(), originalEmployees.size() == copyEmployees.size()); + assertTrue("copyAddresses.size() == " + copyAddresses.size() + "; was expected " + originalAddresses.size(), originalAddresses.size() == copyAddresses.size()); + assertTrue("copyProjects.size() == " + copyProjects.size() + "; was expected " + originalProjects.size(), originalProjects.size() == copyProjects.size()); + assertTrue("copyPhones.size() == " + copyPhones.size() + "; was expected " + originalPhones.size(), originalPhones.size() == copyPhones.size()); + } finally { + if(isTransactionActive(em)) { + rollbackTransaction(em); + } } - - assertTrue("copyEmployees.size() == " + copyEmployees.size() + "; was expected " + originalEmployees.size(), originalEmployees.size() == copyEmployees.size()); - assertTrue("copyAddresses.size() == " + copyAddresses.size() + "; was expected " + originalAddresses.size(), originalAddresses.size() == copyAddresses.size()); - assertTrue("copyProjects.size() == " + copyProjects.size() + "; was expected " + originalProjects.size(), originalProjects.size() == copyProjects.size()); - assertTrue("copyPhones.size() == " + copyPhones.size() + "; was expected " + originalPhones.size(), originalPhones.size() == copyPhones.size()); } private T serialize(Serializable entity) throws IOException, ClassNotFoundException { byte[] bytes = SerializationHelper.serialize(entity); - return (T) SerializationHelper.deserialize(bytes); + ObjectInputStream inStream = new ObjectInputStream(new ByteArrayInputStream(bytes)); + return (T) inStream.readObject(); } + + private Object clone(Serializable object) throws IOException, ClassNotFoundException { + byte[] bytes = SerializationHelper.serialize(object); + ObjectInputStream inStream = new ObjectInputStream(new ByteArrayInputStream(bytes)); + return inStream.readObject(); + } } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/BaseFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/BaseFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/BaseFetchGroupTests.java (working copy) @@ -70,15 +70,6 @@ super(name); } - /* - * Fetch Group tests require weaving. - */ - public void runBare() throws Throwable { - if (isWeavingEnabled("fieldaccess")) { - super.runBare(); - } - } - /** * Any FetchGroups setup in test cases are removed. * Descriptors should not be isolated. @@ -448,8 +439,7 @@ } protected QuerySQLTracker getQuerySQLTracker(EntityManager em) { - return QuerySQLTracker.getTracker(JpaHelper.getEntityManager(em) - .getActiveSession()); + return QuerySQLTracker.getTracker(getServerSession("fieldaccess")); } ClassDescriptor getDescriptor(String entityName) { Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FAServerTestSuite.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FAServerTestSuite.java (revision 0) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FAServerTestSuite.java (revision 0) @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 1998, 2010 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 + * which accompanies this distribution. + * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Oracle - initial API and implementation from Oracle TopLink + ******************************************************************************/ +package org.eclipse.persistence.testing.tests.jpa.fieldaccess.fetchgroups; + +import junit.framework.TestSuite; +import junit.framework.Test; + +/** + *

Purpose: To collect the tests that will run against Application Server only. + */ +public class FAServerTestSuite extends TestSuite { + + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.setName("FieldAccess FetchGroups ServerTestSuite"); + suite.addTest(FetchGroupMergeWithCacheTests.suite()); + suite.addTest(FetchGroupTrackerWeavingTests.suite()); + suite.addTest(NestedDefaultFetchGroupTests.suite()); + suite.addTest(NestedFetchGroupTests.suite()); + suite.addTest(NestedNamedFetchGroupTests.suite()); + suite.addTest(SimpleDefaultFetchGroupTests.suite()); + suite.addTest(SimpleFetchGroupTests.suite()); + suite.addTest(SimpleNamedFetchGroupTests.suite()); + suite.addTest(SimpleSerializeFetchGroupTests.suite()); + return suite; + } +} Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FetchGroupMergeWithCacheTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FetchGroupMergeWithCacheTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FetchGroupMergeWithCacheTests.java (working copy) @@ -40,8 +40,9 @@ suite.addTest(new FetchGroupMergeWithCacheTests("testSetup")); suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_QueryWithFetchGroup_Simple")); - suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_FindWithFetchGroup_Simple")); - + if (!isJPA10()) { + suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_FindWithFetchGroup_Simple")); + } return suite; } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FetchGroupTrackerWeavingTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FetchGroupTrackerWeavingTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FetchGroupTrackerWeavingTests.java (working copy) @@ -51,15 +51,6 @@ public FetchGroupTrackerWeavingTests(String name) { super(name); } - - /* - * Fetch Group tests require weaving. - */ - public void runBare() throws Throwable { - if (isWeavingEnabled("fieldaccess")) { - super.runBare(); - } - } public static junit.framework.Test suite() { TestSuite suite = new TestSuite(); Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedDefaultFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedDefaultFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedDefaultFetchGroupTests.java (working copy) @@ -56,15 +56,16 @@ suite.addTest(new NestedDefaultFetchGroupTests("testSetup")); suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployee")); - suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddress")); - suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadPhones")); - suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhones")); suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhoneUsingFetchGroup")); - suite.addTest(new NestedDefaultFetchGroupTests("allAddress")); - suite.addTest(new NestedDefaultFetchGroupTests("allPhone")); - suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddress")); - suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddressLoad")); - + if (!isJPA10()) { + suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddress")); + suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadPhones")); + suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhones")); + suite.addTest(new NestedDefaultFetchGroupTests("allAddress")); + suite.addTest(new NestedDefaultFetchGroupTests("allPhone")); + suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddress")); + suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddressLoad")); + } return suite; } @@ -117,6 +118,8 @@ void internalFindMinEmployee(boolean loadAddress, boolean loadPhones, boolean useLoadGroup) { EntityManager em = createEntityManager("fieldaccess"); + beginTransaction(em); + int minId = minEmployeeIdWithAddressAndPhones(em); assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); @@ -188,6 +191,10 @@ defaultEmployeeFG.setShouldLoad(originalLoad); } } + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } /* void internalFindMinEmployee(boolean loadAddress, boolean loadPhones) { Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedFetchGroupTests.java (working copy) @@ -97,198 +97,222 @@ @Test public void dynamicFetchGroup_EmployeeAddress() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup fg = new FetchGroup(); - fg.addAttribute("id"); - fg.addAttribute("version"); - fg.addAttribute("firstName"); - fg.addAttribute("lastName"); - fg.addAttribute("address.city"); - fg.addAttribute("address.postalCode"); + // Define the fields to be fetched on Employee + FetchGroup fg = new FetchGroup(); + fg.addAttribute("id"); + fg.addAttribute("version"); + fg.addAttribute("firstName"); + fg.addAttribute("lastName"); + fg.addAttribute("address.city"); + fg.addAttribute("address.postalCode"); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, fg); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, fg); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("address")); - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("address")); + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("address")); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("address")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); - assertTrue(phoneTracker._persistence_isAttributeFetched("number")); - assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); + assertTrue(phoneTracker._persistence_isAttributeFetched("number")); + assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void dynamicFetchGroup_Employee_NullAddress() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup empGroup = new FetchGroup(); - empGroup.addAttribute("firstName"); - empGroup.addAttribute("lastName"); - empGroup.addAttribute("address"); + // Define the fields to be fetched on Employee + FetchGroup empGroup = new FetchGroup(); + empGroup.addAttribute("firstName"); + empGroup.addAttribute("lastName"); + empGroup.addAttribute("address"); - // Define the fields to be fetched on Address - FetchGroup addressGroup = new FetchGroup(); - addressGroup.addAttribute("city"); - addressGroup.addAttribute("postalCode"); + // Define the fields to be fetched on Address + FetchGroup addressGroup = new FetchGroup(); + addressGroup.addAttribute("city"); + addressGroup.addAttribute("postalCode"); - empGroup.addAttribute("address"); + empGroup.addAttribute("address"); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, empGroup); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, empGroup); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNull("Address has an unexpected FetchGroup", addrTracker._persistence_getFetchGroup()); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNull("Address has an unexpected FetchGroup", addrTracker._persistence_getFetchGroup()); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); - assertTrue(phoneTracker._persistence_isAttributeFetched("number")); - assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); + assertTrue(phoneTracker._persistence_isAttributeFetched("number")); + assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup empGroup = new FetchGroup(); - empGroup.addAttribute("firstName"); - empGroup.addAttribute("lastName"); - empGroup.addAttribute("address"); - empGroup.addAttribute("address.city"); - empGroup.addAttribute("address.postalCode"); + // Define the fields to be fetched on Employee + FetchGroup empGroup = new FetchGroup(); + empGroup.addAttribute("firstName"); + empGroup.addAttribute("lastName"); + empGroup.addAttribute("address"); + empGroup.addAttribute("address.city"); + empGroup.addAttribute("address.postalCode"); -// empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false); - FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); - // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group - fullPhone.addAttribute("owner.id"); - empGroup.addAttribute("phoneNumbers", fullPhone); + //empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false); + FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); + // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group + fullPhone.addAttribute("owner.id"); + empGroup.addAttribute("phoneNumbers", fullPhone); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, empGroup); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, empGroup); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup()); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup()); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -301,76 +325,84 @@ } void internal_dynamicFetchGroup_EmployeeAddressEmptyPhone(boolean shouldLoad) { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup fg = new FetchGroup(); - fg.addAttribute("firstName"); - fg.addAttribute("lastName"); - fg.addAttribute("address.city"); - fg.addAttribute("address.postalCode"); - // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group - FetchGroup ownerId = new FetchGroup(); - ownerId.addAttribute("owner.id"); - fg.addAttribute("phoneNumbers", ownerId); - - if(shouldLoad) { - fg.setShouldLoad(true); - } + // Define the fields to be fetched on Employee + FetchGroup fg = new FetchGroup(); + fg.addAttribute("firstName"); + fg.addAttribute("lastName"); + fg.addAttribute("address.city"); + fg.addAttribute("address.postalCode"); + // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group + FetchGroup ownerId = new FetchGroup(); + ownerId.addAttribute("owner.id"); + fg.addAttribute("phoneNumbers", ownerId); + + if(shouldLoad) { + fg.setShouldLoad(true); + } - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, fg); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, fg); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1 + (shouldLoad ? 0 : (emps.size() * 2)), getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + assertEquals(1 + (shouldLoad ? 0 : (emps.size() * 2)), getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); - assertFalse(phoneTracker._persistence_isAttributeFetched("number")); - assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); + assertFalse(phoneTracker._persistence_isAttributeFetched("number")); + assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); - phone.getNumber(); + phone.getNumber(); - assertTrue(phoneTracker._persistence_isAttributeFetched("number")); - assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode")); + assertTrue(phoneTracker._persistence_isAttributeFetched("number")); + assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode")); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -421,132 +453,154 @@ void internalDynamicHierarchicalFetchGroup_JOIN_FETCH(boolean useCopy) throws Exception { EntityManager em = createEntityManager("fieldaccess"); - - Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.manager WHERE e.lastName LIKE :LNAME AND e.manager.lastName <> e.lastName"); - query.setParameter("LNAME", "%"); + try { + beginTransaction(em); - // Define the fields to be fetched on Employee - FetchGroup fg = new FetchGroup(); - fg.addAttribute("firstName"); - fg.addAttribute("lastName"); - fg.addAttribute("manager.firstName"); - fg.addAttribute("manager.salary"); - fg.addAttribute("manager.manager"); - query.setHint(QueryHints.FETCH_GROUP, fg); - - // applied to the selected Employee who is not a manager of some other selected Employee - FetchGroup employeeFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "lastName", "manager"}); - // applied to the manager of a selected Employee who is not selected as an Employee - FetchGroup managerFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "salary", "manager"}); - // applied to the object which is both selected as an Employee and the manager of another selected Employee - FetchGroup employeeManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(employeeFG, managerFG); - - // used in useCopy case only - FetchGroup employeeManagerManagerFG = null; - if(useCopy) { - employeeManagerManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(new EntityFetchGroup("manager"), employeeDescriptor.getFetchGroupManager().getNonReferenceEntityFetchGroup()); - } - - /* - * These are the first names of Employees involved; --> means "managed by". - * All the employees here are returned by the query except Jill and Sarah-loo (they got no manager). - * - * Sarah ------>Bob -------> John ----> Jim-bob ---> Jill ---> null - * Charles -----^ Marius ----^ - * - * Nancy ------> Sarah-loo ---> null - * - * Sarah, Charles, Nancy should have employeeFG; - * Sarah-loo - managerFG; - * Bob, Marius - employeeManagerFG; - * John, Jim-bob should have a union of three fetch groups: {firstName,lastName,manager}, {firstName,salary,manager}, {manager} - * Jill should have a union of two groups: {firstName,salary,manager}, {manager} - * The result for all three of them is the same: - * in read case (useCopy == false) it should be null (no fetch group), because defaultFetchGroup is null; - * in copy case (useCopy == true) it should be a union of "manager" and all non relational attributes (NonReferenceEntityFetchGroup). - * That's how leaf reference attribute is treated: - * default fetch group for read; - * NonReferenceEntityFetchGroup (see FetchGroupManager) for copy. - * In this test defaultFetchGroup (null) / NonReferenceEntityFetchGroup comes from {manager}, - * in useCopy == true case additional manager comes from another fetch group (they all contain manager). - */ - - List emps = query.getResultList(); - - if(useCopy) { -/* for(Employee emp : emps) { - int idHashCode = System.identityHashCode(emp); - System.out.println(emp.getFirstName() + '\t' + idHashCode); - }*/ - emps = (List)JpaHelper.getEntityManager(em).copy(emps, fg); - } + Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.manager WHERE e.lastName LIKE :LNAME AND e.manager.lastName <> e.lastName"); + query.setParameter("LNAME", "%"); - // Sets of managed Employees keyed by their manager - Map> managedEmployeesByManager = new IdentityHashMap(); - for (Employee emp : emps) { - Employee manager = emp.getManager(); - Set managedEmployees = managedEmployeesByManager.get(manager); - if(managedEmployees == null) { - managedEmployees = new IdentityHashSet(); - managedEmployeesByManager.put(manager, managedEmployees); + // Define the fields to be fetched on Employee + FetchGroup fg = new FetchGroup(); + fg.addAttribute("firstName"); + fg.addAttribute("lastName"); + fg.addAttribute("manager.firstName"); + fg.addAttribute("manager.salary"); + fg.addAttribute("manager.manager"); + query.setHint(QueryHints.FETCH_GROUP, fg); + + // applied to the selected Employee who is not a manager of some other selected Employee + FetchGroup employeeFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "lastName", "manager"}); + // applied to the manager of a selected Employee who is not selected as an Employee + FetchGroup managerFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "salary", "manager"}); + // applied to the object which is both selected as an Employee and the manager of another selected Employee + FetchGroup employeeManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(employeeFG, managerFG); + + // used in useCopy case only + FetchGroup employeeManagerManagerFG = null; + if(useCopy) { + employeeManagerManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(new EntityFetchGroup("manager"), employeeDescriptor.getFetchGroupManager().getNonReferenceEntityFetchGroup()); } - managedEmployees.add(emp); - } + + /* + * These are the first names of Employees involved; --> means "managed by". + * All the employees here are returned by the query except Jill and Sarah-loo (they got no manager). + * + * Sarah ------>Bob -------> John ----> Jim-bob ---> Jill ---> null + * Charles -----^ Marius ----^ + * + * Nancy ------> Sarah-loo ---> null + * + * Sarah, Charles, Nancy should have employeeFG; + * Sarah-loo - managerFG; + * Bob, Marius - employeeManagerFG; + * John, Jim-bob should have a union of three fetch groups: {firstName,lastName,manager}, {firstName,salary,manager}, {manager} + * Jill should have a union of two groups: {firstName,salary,manager}, {manager} + * The result for all three of them is the same: + * in read case (useCopy == false) it should be null (no fetch group), because defaultFetchGroup is null; + * in copy case (useCopy == true) it should be a union of "manager" and all non relational attributes (NonReferenceEntityFetchGroup). + * That's how leaf reference attribute is treated: + * default fetch group for read; + * NonReferenceEntityFetchGroup (see FetchGroupManager) for copy. + * In this test defaultFetchGroup (null) / NonReferenceEntityFetchGroup comes from {manager}, + * in useCopy == true case additional manager comes from another fetch group (they all contain manager). + */ + + List emps = query.getResultList(); + + if(useCopy) { + /*for(Employee emp : emps) { + int idHashCode = System.identityHashCode(emp); + System.out.println(emp.getFirstName() + '\t' + idHashCode); + }*/ + emps = (List)JpaHelper.getEntityManager(em).copy(emps, fg); + } - for (Employee emp : emps) { - Set managedEmployees = managedEmployeesByManager.get(emp); - Employee manager = emp.getManager(); - if(managedEmployees == null) { - // employee is NOT a manager of any of the selected employees: - assertFetched(emp, employeeFG); + // Sets of managed Employees keyed by their manager + Map> managedEmployeesByManager = new IdentityHashMap(); + for (Employee emp : emps) { + Employee manager = emp.getManager(); + Set managedEmployees = managedEmployeesByManager.get(manager); + if(managedEmployees == null) { + managedEmployees = new IdentityHashSet(); + managedEmployeesByManager.put(manager, managedEmployees); + } + managedEmployees.add(emp); + } - Set managedByManagerEmployees = managedEmployeesByManager.get(manager); - // indicates whether one of manager's managed employees is a manager itself - boolean isManagersManager = false; - for(Employee managedEmp : managedByManagerEmployees) { - if(managedEmployeesByManager.containsKey(managedEmp)) { - isManagersManager = true; - break; + for (Employee emp : emps) { + Set managedEmployees = managedEmployeesByManager.get(emp); + Employee manager = emp.getManager(); + if(managedEmployees == null) { + // employee is NOT a manager of any of the selected employees: + assertFetched(emp, employeeFG); + + Set managedByManagerEmployees = managedEmployeesByManager.get(manager); + // indicates whether one of manager's managed employees is a manager itself + boolean isManagersManager = false; + for(Employee managedEmp : managedByManagerEmployees) { + if(managedEmployeesByManager.containsKey(managedEmp)) { + isManagersManager = true; + break; + } } - } - if(isManagersManager) { - if(useCopy) { - // for at least one of the selected employees manager is manager's manager: - // someSelectedEmp.getManager().getManager() == manager - // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, - // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk) - // for another employee it's just a manager - which means it should include "manager": - // employeeManagerManagerFG is the union of these two EntityFetchGroups. - assertFetched(manager, employeeManagerManagerFG); + if(isManagersManager) { + if(useCopy) { + // for at least one of the selected employees manager is manager's manager: + // someSelectedEmp.getManager().getManager() == manager + // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, + // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk) + // for another employee it's just a manager - which means it should include "manager": + // employeeManagerManagerFG is the union of these two EntityFetchGroups. + assertFetched(manager, employeeManagerManagerFG); + } else { + // for at least one of the selected employees manager is manager's manager: + // someSelectedEmp.getManager().getManager() == manager + // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, + // which means no fetch group should be used. + assertNoFetchGroup(manager); + } } else { - // for at least one of the selected employees manager is manager's manager: - // someSelectedEmp.getManager().getManager() == manager - // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, - // which means no fetch group should be used. - assertNoFetchGroup(manager); + // it's not manager's manager + if(emps.contains(manager)) { + // it's a manager of one of the selected Employees, and selected itself. + assertFetched(manager, employeeManagerFG); + } else { + // it's a manager of one of the selected Employees, but not selected itself. + assertFetched(manager, managerFG); + } } } else { - // it's not manager's manager - if(emps.contains(manager)) { - // it's a manager of one of the selected Employees, and selected itself. - assertFetched(manager, employeeManagerFG); + // employee is a manager of at least one of the selected employees + // indicates whether one of emp's managed employees is a manager itself + boolean isManagersManager = false; + for(Employee managedEmp : managedEmployees) { + if(managedEmployeesByManager.containsKey(managedEmp)) { + isManagersManager = true; + break; + } + } + + if(isManagersManager) { + if(useCopy) { + // for at least one of the selected employees manager is manager's manager: + // someSelectedEmp.getManager().getManager() == manager + // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, + // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk) + // for another employee it's just a manager - which means it should include "manager": + // employeeManagerManagerFG is the union of these two EntityFetchGroups. + assertFetched(emp, employeeManagerManagerFG); + } else { + // for at least one of the selected employees emp is manager's manager: + // someSelectedEmp.getManager().getManager() == emp + // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, + // which means no fetch group should be used. + assertNoFetchGroup(emp); + } } else { - // it's a manager of one of the selected Employees, but not selected itself. - assertFetched(manager, managerFG); + // it's selected employee, manager of some selected employee, but not manager's manager + assertFetched(emp, employeeManagerFG); } - } - } else { - // employee is a manager of at least one of the selected employees - // indicates whether one of emp's managed employees is a manager itself - boolean isManagersManager = false; - for(Employee managedEmp : managedEmployees) { - if(managedEmployeesByManager.containsKey(managedEmp)) { - isManagersManager = true; - break; - } - } - - if(isManagersManager) { + if(useCopy) { // for at least one of the selected employees manager is manager's manager: // someSelectedEmp.getManager().getManager() == manager @@ -554,35 +608,21 @@ // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk) // for another employee it's just a manager - which means it should include "manager": // employeeManagerManagerFG is the union of these two EntityFetchGroups. - assertFetched(emp, employeeManagerManagerFG); + assertFetched(manager, employeeManagerManagerFG); } else { - // for at least one of the selected employees emp is manager's manager: - // someSelectedEmp.getManager().getManager() == emp - // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, + // for at least one of the selected employees manager is manager's manager: + // someSelectedEmp.getManager().getManager() == manager + // That means for someSelectedEmp emp.getManager() is defined by {manager.manager} FetchGroup's item, // which means no fetch group should be used. - assertNoFetchGroup(emp); + assertNoFetchGroup(manager); } - } else { - // it's selected employee, manager of some selected employee, but not manager's manager - assertFetched(emp, employeeManagerFG); } - - if(useCopy) { - // for at least one of the selected employees manager is manager's manager: - // someSelectedEmp.getManager().getManager() == manager - // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item, - // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk) - // for another employee it's just a manager - which means it should include "manager": - // employeeManagerManagerFG is the union of these two EntityFetchGroups. - assertFetched(manager, employeeManagerManagerFG); - } else { - // for at least one of the selected employees manager is manager's manager: - // someSelectedEmp.getManager().getManager() == manager - // That means for someSelectedEmp emp.getManager() is defined by {manager.manager} FetchGroup's item, - // which means no fetch group should be used. - assertNoFetchGroup(manager); - } - } + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -598,157 +638,173 @@ void managerNestedFetchGroupWithJoinFetch(boolean isDouble) { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager.manager IS NOT NULL"); - FetchGroup managerFG = new FetchGroup(); - if(isDouble) { - // Double - managerFG.addAttribute("manager.manager"); - } else { - // Triple - managerFG.addAttribute("manager.manager.manager"); - } + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager.manager IS NOT NULL"); + FetchGroup managerFG = new FetchGroup(); + if(isDouble) { + // Double + managerFG.addAttribute("manager.manager"); + } else { + // Triple + managerFG.addAttribute("manager.manager.manager"); + } - query.setHint(QueryHints.FETCH_GROUP, managerFG); - query.setHint(QueryHints.LEFT_FETCH, "e.manager"); + query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.LEFT_FETCH, "e.manager"); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - List employees = query.getResultList(); + List employees = query.getResultList(); - int nSql; - if(isDouble) { - // In this case the number of generated sqls is unpredictable. - // Additional sql generated for every object that - // has been first fetched as manager.manager - // and then is selected as an employee - getting its manger - // performed without fetch group therefore triggering reading of the whole object - nSql = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); - } else { - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - nSql = 1; - } - - Employee emp = employees.get(0); - assertFetched(emp, managerFG); - - // manager (if not null) is instantiated by the fetch group, before emp.getManager call. - Employee manager = emp.getManager(); - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(manager, managerFG); - - // instantiates the whole object - emp.getLastName(); - nSql++; - assertNoFetchGroup(emp); - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - assertFetched(manager, managerFG); - // instantiates the whole object - manager.getLastName(); - nSql++; - assertNoFetchGroup(manager); - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int nSql; + if(isDouble) { + // In this case the number of generated sqls is unpredictable. + // Additional sql generated for every object that + // has been first fetched as manager.manager + // and then is selected as an employee - getting its manger + // performed without fetch group therefore triggering reading of the whole object + nSql = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); + } else { + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + nSql = 1; + } + + Employee emp = employees.get(0); + assertFetched(emp, managerFG); + + // manager (if not null) is instantiated by the fetch group, before emp.getManager call. + Employee manager = emp.getManager(); + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(manager, managerFG); + + // instantiates the whole object + emp.getLastName(); + nSql++; + assertNoFetchGroup(emp); + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + assertFetched(manager, managerFG); + // instantiates the whole object + manager.getLastName(); + nSql++; + assertNoFetchGroup(manager); + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - nSql++; - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertFetched(phone, this.defaultPhoneFG); - phone.getAreaCode(); nSql++; - assertNoFetchGroup(phone); - } - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertFetched(phone, this.defaultPhoneFG); + phone.getAreaCode(); + nSql++; + assertNoFetchGroup(phone); + } + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - nSql++; - for (PhoneNumber phone : manager.getPhoneNumbers()) { - assertFetched(phone, this.defaultPhoneFG); - phone.getAreaCode(); nSql++; - assertNoFetchGroup(phone); + for (PhoneNumber phone : manager.getPhoneNumbers()) { + assertFetched(phone, this.defaultPhoneFG); + phone.getAreaCode(); + nSql++; + assertNoFetchGroup(phone); + } + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void allNestedFetchGroupWithJoinFetch() { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - // select employees who are neither managers nor team leaders - Query query = em.createQuery("SELECT e FROM Employee e WHERE NOT EXISTS(SELECT p.id FROM Project p WHERE p.teamLeader = e) AND NOT EXISTS(SELECT e2.id FROM Employee e2 WHERE e2.manager = e)"); - FetchGroup employeeFG = new FetchGroup("employee"); - employeeFG.addAttribute("lastName"); - - employeeFG.addAttribute("address.country"); - employeeFG.addAttribute("address.city"); - query.setHint(QueryHints.LEFT_FETCH, "e.address"); - - employeeFG.addAttribute("phoneNumbers"); - query.setHint(QueryHints.LEFT_FETCH, "e.phoneNumbers"); - - employeeFG.addAttribute("projects.name"); + // select employees who are neither managers nor team leaders + Query query = em.createQuery("SELECT e FROM Employee e WHERE NOT EXISTS(SELECT p.id FROM Project p WHERE p.teamLeader = e) AND NOT EXISTS(SELECT e2.id FROM Employee e2 WHERE e2.manager = e)"); + FetchGroup employeeFG = new FetchGroup("employee"); + employeeFG.addAttribute("lastName"); + + employeeFG.addAttribute("address.country"); + employeeFG.addAttribute("address.city"); + query.setHint(QueryHints.LEFT_FETCH, "e.address"); + + employeeFG.addAttribute("phoneNumbers"); + query.setHint(QueryHints.LEFT_FETCH, "e.phoneNumbers"); + + employeeFG.addAttribute("projects.name"); - employeeFG.addAttribute("projects.teamLeader.firstName"); -// employeeFG.addAttribute("projects.teamLeader.address.street"); -// employeeFG.addAttribute("projects.teamLeader.address.postalCode"); - employeeFG.addAttribute("projects.teamLeader.phoneNumbers.owner"); - employeeFG.addAttribute("projects.teamLeader.phoneNumbers.type"); - employeeFG.addAttribute("projects.teamLeader.phoneNumbers.areaCode"); - query.setHint(QueryHints.LEFT_FETCH, "e.projects.teamLeader.phoneNumbers"); - - employeeFG.addAttribute("manager.firstName"); -// employeeFG.addAttribute("manager.address.street"); -// employeeFG.addAttribute("manager.address.postalCode"); - employeeFG.addAttribute("manager.phoneNumbers.owner"); - employeeFG.addAttribute("manager.phoneNumbers.type"); - employeeFG.addAttribute("manager.phoneNumbers.areaCode"); - query.setHint(QueryHints.LEFT_FETCH, "e.manager.phoneNumbers"); + employeeFG.addAttribute("projects.teamLeader.firstName"); + //employeeFG.addAttribute("projects.teamLeader.address.street"); + //employeeFG.addAttribute("projects.teamLeader.address.postalCode"); + employeeFG.addAttribute("projects.teamLeader.phoneNumbers.owner"); + employeeFG.addAttribute("projects.teamLeader.phoneNumbers.type"); + employeeFG.addAttribute("projects.teamLeader.phoneNumbers.areaCode"); + query.setHint(QueryHints.LEFT_FETCH, "e.projects.teamLeader.phoneNumbers"); + + employeeFG.addAttribute("manager.firstName"); + //employeeFG.addAttribute("manager.address.street"); + //employeeFG.addAttribute("manager.address.postalCode"); + employeeFG.addAttribute("manager.phoneNumbers.owner"); + employeeFG.addAttribute("manager.phoneNumbers.type"); + employeeFG.addAttribute("manager.phoneNumbers.areaCode"); + query.setHint(QueryHints.LEFT_FETCH, "e.manager.phoneNumbers"); - // department attribute defined with JoinFetchType.OUTER - employeeFG.addAttribute("department.name"); - - query.setHint(QueryHints.FETCH_GROUP, employeeFG); + // department attribute defined with JoinFetchType.OUTER + employeeFG.addAttribute("department.name"); + + query.setHint(QueryHints.FETCH_GROUP, employeeFG); - List employees = query.getResultList(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - for(Employee emp :employees) { - assertFetched(emp, employeeFG); + List employees = query.getResultList(); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - Address address = emp.getAddress(); - if(address != null) { - assertFetched(address, employeeFG.getGroup("address")); - } + for(Employee emp :employees) { + assertFetched(emp, employeeFG); + + Address address = emp.getAddress(); + if(address != null) { + assertFetched(address, employeeFG.getGroup("address")); + } - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertFetched(phone, defaultPhoneFG); - } - - for (Project project : emp.getProjects()) { - assertFetched(project, employeeFG.getGroup("projects")); - Employee teamLeader = project.getTeamLeader(); - if(teamLeader != null) { - assertFetched(teamLeader, employeeFG.getGroup("projects.teamLeader")); - for (PhoneNumber phone : teamLeader.getPhoneNumbers()) { - assertFetched(phone, employeeFG.getGroup("projects.teamLeader.phoneNumbers")); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertFetched(phone, defaultPhoneFG); + } + + for (Project project : emp.getProjects()) { + assertFetched(project, employeeFG.getGroup("projects")); + Employee teamLeader = project.getTeamLeader(); + if(teamLeader != null) { + assertFetched(teamLeader, employeeFG.getGroup("projects.teamLeader")); + for (PhoneNumber phone : teamLeader.getPhoneNumbers()) { + assertFetched(phone, employeeFG.getGroup("projects.teamLeader.phoneNumbers")); + } } } - } - - Employee manager = emp.getManager(); - if(manager != null) { - assertFetched(manager, employeeFG.getGroup("manager")); - for (PhoneNumber phone : manager.getPhoneNumbers()) { - assertFetched(phone, employeeFG.getGroup("manager.phoneNumbers")); + + Employee manager = emp.getManager(); + if(manager != null) { + assertFetched(manager, employeeFG.getGroup("manager")); + for (PhoneNumber phone : manager.getPhoneNumbers()) { + assertFetched(phone, employeeFG.getGroup("manager.phoneNumbers")); + } } + + Department department = emp.getDepartment(); + if(department != null) { + assertFetched(department, employeeFG.getGroup("department")); + } } - - Department department = emp.getDepartment(); - if(department != null) { - assertFetched(department, employeeFG.getGroup("department")); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); } + closeEntityManager(em); } - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test @@ -786,114 +842,130 @@ @Test public void simpleNestedFetchGroupWithBatch() { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e"); + Query query = em.createQuery("SELECT e FROM Employee e"); - // Define the fields to be fetched on Employee - FetchGroup employeeFG = new FetchGroup(); - employeeFG.setShouldLoad(true); - employeeFG.addAttribute("firstName"); - employeeFG.addAttribute("lastName"); - employeeFG.addAttribute("address.country"); - employeeFG.addAttribute("address.city"); - - FetchGroup phonesFG = defaultPhoneFG.clone(); - // to preclude PhoneNumber from triggering owner's full read - phonesFG.addAttribute("owner.id"); - employeeFG.addAttribute("phoneNumbers", phonesFG); - - FetchGroup projectsFG = new FetchGroup("projects"); - projectsFG.addAttribute("name"); - projectsFG.addAttribute("name"); - // to preclude Project from triggering full read of the referenced Employee(s) - projectsFG.addAttribute("teamMembers.id"); - projectsFG.addAttribute("teamLeader.id"); - employeeFG.addAttribute("projects", projectsFG); + // Define the fields to be fetched on Employee + FetchGroup employeeFG = new FetchGroup(); + employeeFG.setShouldLoad(true); + employeeFG.addAttribute("firstName"); + employeeFG.addAttribute("lastName"); + employeeFG.addAttribute("address.country"); + employeeFG.addAttribute("address.city"); + + FetchGroup phonesFG = defaultPhoneFG.clone(); + // to preclude PhoneNumber from triggering owner's full read + phonesFG.addAttribute("owner.id"); + employeeFG.addAttribute("phoneNumbers", phonesFG); + + FetchGroup projectsFG = new FetchGroup("projects"); + projectsFG.addAttribute("name"); + projectsFG.addAttribute("name"); + // to preclude Project from triggering full read of the referenced Employee(s) + projectsFG.addAttribute("teamMembers.id"); + projectsFG.addAttribute("teamLeader.id"); + employeeFG.addAttribute("projects", projectsFG); - query.setHint(QueryHints.FETCH_GROUP, employeeFG); - - query.setHint(QueryHints.BATCH, "e.address"); - query.setHint(QueryHints.BATCH, "e.phoneNumbers"); - query.setHint(QueryHints.BATCH, "e.projects"); - - // A single sql will be used to read all Project subclasses. - query.setHint(QueryHints.INHERITANCE_OUTER_JOIN, "true"); + query.setHint(QueryHints.FETCH_GROUP, employeeFG); + + query.setHint(QueryHints.BATCH, "e.address"); + query.setHint(QueryHints.BATCH, "e.phoneNumbers"); + query.setHint(QueryHints.BATCH, "e.projects"); + + // A single sql will be used to read all Project subclasses. + query.setHint(QueryHints.INHERITANCE_OUTER_JOIN, "true"); - List employees = query.getResultList(); + List employees = query.getResultList(); - // Employee, Address, PhoneNumbers, Projects - an sql per class. - // Address, PhoneNumbers and Projects are already loaded because - // employeeFG.shouldLoad is set to true. - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // verify fetch groups - for(Employee emp : employees) { - assertFetched(emp, employeeFG); + // Employee, Address, PhoneNumbers, Projects - an sql per class. + // Address, PhoneNumbers and Projects are already loaded because + // employeeFG.shouldLoad is set to true. + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // verify fetch groups + for(Employee emp : employees) { + assertFetched(emp, employeeFG); - Address address = emp.getAddress(); - if(address != null) { - assertFetched(address, employeeFG.getGroup("address")); - } + Address address = emp.getAddress(); + if(address != null) { + assertFetched(address, employeeFG.getGroup("address")); + } - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertFetched(phone, phonesFG); - } - - for (Project project : emp.getProjects()) { - assertFetched(project, projectsFG); - } - } + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertFetched(phone, phonesFG); + } + + for (Project project : emp.getProjects()) { + assertFetched(project, projectsFG); + } + } - // Now let's access an attribute outside of the fetch group. - // That triggers loading of the whole object. - for(Employee emp : employees) { - emp.getSalary(); - assertNoFetchGroup(emp); + // Now let's access an attribute outside of the fetch group. + // That triggers loading of the whole object. + for(Employee emp : employees) { + emp.getSalary(); + assertNoFetchGroup(emp); - Address address = emp.getAddress(); - if(address != null) { - address.getStreet(); - assertNoFetchGroup(address); - } + Address address = emp.getAddress(); + if(address != null) { + address.getStreet(); + assertNoFetchGroup(address); + } - for (PhoneNumber phone : emp.getPhoneNumbers()) { - phone.getAreaCode(); - assertNoFetchGroup(phone); - } - - for (Project project : emp.getProjects()) { - project.getDescription(); - assertNoFetchGroup(project); - } - } + for (PhoneNumber phone : emp.getPhoneNumbers()) { + phone.getAreaCode(); + assertNoFetchGroup(phone); + } + + for (Project project : emp.getProjects()) { + project.getDescription(); + assertNoFetchGroup(project); + } + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); + } } @Test public void simpleLoadGroup() { EntityManager em = createEntityManager("fieldaccess"); - - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Female); - List employees = query.getResultList(); - - LoadGroup group = new LoadGroup(); - group.addAttribute("address"); - group.addAttribute("phoneNumbers"); - group.addAttribute("manager.projects"); - ((AbstractSession)((EntityManagerImpl)em.getDelegate()).getActiveSession()).load(employees, group); + try { + beginTransaction(em); - int numSelectBefore = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); - - // All indirections specified in the plan should have been already triggered. - for(Employee emp : employees) { - emp.getAddress(); - emp.getPhoneNumbers().size(); - if(emp.getManager() != null) { - emp.getManager().getProjects().size(); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Female); + List employees = query.getResultList(); + + LoadGroup group = new LoadGroup(); + group.addAttribute("address"); + group.addAttribute("phoneNumbers"); + group.addAttribute("manager.projects"); + ((AbstractSession)((EntityManagerImpl)em.getDelegate()).getActiveSession()).load(employees, group); + + int numSelectBefore = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); + + // All indirections specified in the plan should have been already triggered. + for(Employee emp : employees) { + emp.getAddress(); + emp.getPhoneNumbers().size(); + if(emp.getManager() != null) { + emp.getManager().getProjects().size(); + } + } + + int numSelectAfter = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); + assertEquals(numSelectBefore, numSelectAfter); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); } + closeEntityManager(em); } - - int numSelectAfter = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); - assertEquals(numSelectBefore, numSelectAfter); } } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedNamedFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedNamedFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedNamedFetchGroupTests.java (working copy) @@ -83,62 +83,70 @@ @Test public void dynamicFetchGroup_EmployeeAddress() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup fg = new FetchGroup(); - fg.addAttribute("firstName"); - fg.addAttribute("lastName"); - fg.addAttribute("address"); - fg.addAttribute("address.city"); - fg.addAttribute("address.postalCode"); + // Define the fields to be fetched on Employee + FetchGroup fg = new FetchGroup(); + fg.addAttribute("firstName"); + fg.addAttribute("lastName"); + fg.addAttribute("address"); + fg.addAttribute("address.city"); + fg.addAttribute("address.postalCode"); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, fg); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, fg); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); - assertTrue(phoneTracker._persistence_isAttributeFetched("number")); - assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); + assertTrue(phoneTracker._persistence_isAttributeFetched("number")); + assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -208,147 +216,163 @@ @Test public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup empGroup = new FetchGroup(); - empGroup.addAttribute("firstName"); - empGroup.addAttribute("lastName"); - empGroup.addAttribute("address"); + // Define the fields to be fetched on Employee + FetchGroup empGroup = new FetchGroup(); + empGroup.addAttribute("firstName"); + empGroup.addAttribute("lastName"); + empGroup.addAttribute("address"); - // Define the fields to be fetched on Address - FetchGroup addressGroup = new FetchGroup(); - addressGroup.addAttribute("city"); - addressGroup.addAttribute("postalCode"); + // Define the fields to be fetched on Address + FetchGroup addressGroup = new FetchGroup(); + addressGroup.addAttribute("city"); + addressGroup.addAttribute("postalCode"); - empGroup.addAttribute("address", addressGroup); + empGroup.addAttribute("address", addressGroup); -// empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false); - FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); - // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group - fullPhone.addAttribute("owner.id"); - empGroup.addAttribute("phoneNumbers", fullPhone); + //empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false); + FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); + // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group + fullPhone.addAttribute("owner.id"); + empGroup.addAttribute("phoneNumbers", fullPhone); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, empGroup); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, empGroup); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup()); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup()); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void dynamicFetchGroup_EmployeeAddressEmptyPhone() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); - query.setParameter("GENDER", Gender.Male); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER"); + query.setParameter("GENDER", Gender.Male); - // Define the fields to be fetched on Employee - FetchGroup empGroup = new FetchGroup(); - empGroup.addAttribute("firstName"); - empGroup.addAttribute("lastName"); - empGroup.addAttribute("address"); + // Define the fields to be fetched on Employee + FetchGroup empGroup = new FetchGroup(); + empGroup.addAttribute("firstName"); + empGroup.addAttribute("lastName"); + empGroup.addAttribute("address"); - // Define the fields to be fetched on Address - FetchGroup addressGroup = new FetchGroup(); - addressGroup.addAttribute("city"); - addressGroup.addAttribute("postalCode"); + // Define the fields to be fetched on Address + FetchGroup addressGroup = new FetchGroup(); + addressGroup.addAttribute("city"); + addressGroup.addAttribute("postalCode"); - empGroup.addAttribute("address", addressGroup); - // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group - FetchGroup ownerId = new FetchGroup(); - ownerId.addAttribute("owner.id"); - empGroup.addAttribute("phoneNumbers", ownerId); + empGroup.addAttribute("address", addressGroup); + // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group + FetchGroup ownerId = new FetchGroup(); + ownerId.addAttribute("owner.id"); + empGroup.addAttribute("phoneNumbers", ownerId); - // Configure the dynamic FetchGroup - query.setHint(QueryHints.FETCH_GROUP, empGroup); + // Configure the dynamic FetchGroup + query.setHint(QueryHints.FETCH_GROUP, empGroup); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - for (Employee emp : emps) { - FetchGroupTracker tracker = (FetchGroupTracker) emp; + assertNotNull(emps); + for (Employee emp : emps) { + FetchGroupTracker tracker = (FetchGroupTracker) emp; - assertNotNull(tracker._persistence_getFetchGroup()); + assertNotNull(tracker._persistence_getFetchGroup()); - // Verify specified fields plus mandatory ones are loaded - assertTrue(tracker._persistence_isAttributeFetched("id")); - assertTrue(tracker._persistence_isAttributeFetched("firstName")); - assertTrue(tracker._persistence_isAttributeFetched("lastName")); - assertTrue(tracker._persistence_isAttributeFetched("version")); + // Verify specified fields plus mandatory ones are loaded + assertTrue(tracker._persistence_isAttributeFetched("id")); + assertTrue(tracker._persistence_isAttributeFetched("firstName")); + assertTrue(tracker._persistence_isAttributeFetched("lastName")); + assertTrue(tracker._persistence_isAttributeFetched("version")); - // Verify the other fields are not loaded - assertFalse(tracker._persistence_isAttributeFetched("salary")); - assertFalse(tracker._persistence_isAttributeFetched("startTime")); - assertFalse(tracker._persistence_isAttributeFetched("endTime")); + // Verify the other fields are not loaded + assertFalse(tracker._persistence_isAttributeFetched("salary")); + assertFalse(tracker._persistence_isAttributeFetched("startTime")); + assertFalse(tracker._persistence_isAttributeFetched("endTime")); - // Force the loading of lazy fields and verify - emp.getSalary(); + // Force the loading of lazy fields and verify + emp.getSalary(); - assertTrue(tracker._persistence_isAttributeFetched("salary")); - assertTrue(tracker._persistence_isAttributeFetched("startTime")); - assertTrue(tracker._persistence_isAttributeFetched("endTime")); + assertTrue(tracker._persistence_isAttributeFetched("salary")); + assertTrue(tracker._persistence_isAttributeFetched("startTime")); + assertTrue(tracker._persistence_isAttributeFetched("endTime")); - // Now we'll check the address uses the provided dynamic fetch-group - FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); - assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); - assertTrue(addrTracker._persistence_isAttributeFetched("city")); - assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); - assertFalse(addrTracker._persistence_isAttributeFetched("street")); - assertFalse(addrTracker._persistence_isAttributeFetched("country")); + // Now we'll check the address uses the provided dynamic fetch-group + FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress(); + assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup()); + assertTrue(addrTracker._persistence_isAttributeFetched("city")); + assertTrue(addrTracker._persistence_isAttributeFetched("postalCode")); + assertFalse(addrTracker._persistence_isAttributeFetched("street")); + assertFalse(addrTracker._persistence_isAttributeFetched("country")); - // Now we'll check the phoneNumbers use of the default fetch group - for (PhoneNumber phone : emp.getPhoneNumbers()) { - FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; - assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); - assertFalse(phoneTracker._persistence_isAttributeFetched("number")); - assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); + // Now we'll check the phoneNumbers use of the default fetch group + for (PhoneNumber phone : emp.getPhoneNumbers()) { + FetchGroupTracker phoneTracker = (FetchGroupTracker) phone; + assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup()); + assertFalse(phoneTracker._persistence_isAttributeFetched("number")); + assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode")); - phone.getNumber(); + phone.getNumber(); - assertTrue(phoneTracker._persistence_isAttributeFetched("number")); - assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode")); + assertTrue(phoneTracker._persistence_isAttributeFetched("number")); + assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode")); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleDefaultFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleDefaultFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleDefaultFetchGroupTests.java (working copy) @@ -101,116 +101,136 @@ @Test public void findDefaultFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Employee emp = minimumEmployee(em); + Employee emp = minimumEmployee(em); + assertNotNull(emp); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertDefaultFetched(emp); - assertNotNull(emp); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertDefaultFetched(emp); + assertNotFetchedAttribute(emp, "salary"); + emp.getSalary(); - assertNotFetchedAttribute(emp, "salary"); - emp.getSalary(); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetchedAttribute(emp, "salary"); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetchedAttribute(emp, "salary"); + assertNoFetchGroup(emp.getAddress()); - assertNoFetchGroup(emp.getAddress()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); - } + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - if (emp.getManager() != null) { - assertDefaultFetched(emp.getManager()); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getManager() != null) { + assertDefaultFetched(emp.getManager()); + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void singleResultDefaultFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertNotNull(emp); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertDefaultFetched(emp); + assertDefaultFetched(emp); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetchedAttribute(emp, "salary"); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); - } + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if (emp.getManager() != null) { - assertDefaultFetched(emp.getManager()); - assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getManager() != null) { + assertDefaultFetched(emp.getManager()); + assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - } @Test public void resultListDefaultFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); + List emps = query.getResultList(); - List emps = query.getResultList(); + assertNotNull(emps); + assertEquals(1, emps.size()); - assertNotNull(emps); - assertEquals(1, emps.size()); + Employee emp = emps.get(0); - Employee emp = emps.get(0); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertDefaultFetched(emp); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertDefaultFetched(emp); + emp.getSalary(); - emp.getSalary(); + assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - assertNoFetchGroup(emp.getAddress()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + if (emp.getManager() != null) { + assertDefaultFetched(emp.getManager()); + assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - if (emp.getManager() != null) { - assertDefaultFetched(emp.getManager()); - assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } - } @Test @@ -224,248 +244,296 @@ } void internalResultListWithJoinFetchAddress(boolean addAddressToFetchGroup) { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); + Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + FetchGroup fg = null; + if(addAddressToFetchGroup) { + // that returns clone of the default fetch group + fg = employeeDescriptor.getFetchGroupManager().createDefaultFetchGroup(); + fg.addAttribute("address"); + query.setHint(QueryHints.FETCH_GROUP, fg); + } + Employee emp = (Employee)query.getSingleResult(); + int nSql = 2; + if(!addAddressToFetchGroup) { + // An extra sql to read employee's Address - + // because address attribute is not in the fetch group the Address object was not built + // by join fetch - though the db row for address was read in. + // + // yet another extra sql generated when the whole employee object is read when address is set. + nSql = nSql + 2; + } - FetchGroup fg = null; - if(addAddressToFetchGroup) { - // that returns clone of the default fetch group - fg = employeeDescriptor.getFetchGroupManager().createDefaultFetchGroup(); - fg.addAttribute("address"); - query.setHint(QueryHints.FETCH_GROUP, fg); - } - Employee emp = (Employee)query.getSingleResult(); - int nSql = 2; - if(!addAddressToFetchGroup) { - // An extra sql to read employee's Address - - // because address attribute is not in the fetch group the Address object was not built - // by join fetch - though the db row for address was read in. - // - // yet another extra sql generated when the whole employee object is read when address is set. - nSql = nSql + 2; - } + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if(addAddressToFetchGroup) { + assertFetched(emp, fg); + } else { + // the whole object has been instantiated when address has been set + assertNoFetchGroup(emp); + } - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if(addAddressToFetchGroup) { - assertFetched(emp, fg); - } else { - // the whole object has been instantiated when address has been set + // instantiates the whole object - unless already instantiated + emp.getSalary(); + assertNoFetchGroup(emp); - } + if(addAddressToFetchGroup) { + nSql++; + } + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // instantiates the whole object - unless already instantiated - emp.getSalary(); + assertNoFetchGroup(emp.getAddress()); + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); - if(addAddressToFetchGroup) { - nSql++; - } - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } + assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + if (emp.getManager() != null) { + assertDefaultFetched(emp.getManager()); + assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - if (emp.getManager() != null) { - assertDefaultFetched(emp.getManager()); - assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } } @Test public void singleResultNoFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); - assertNull(getFetchGroup(query)); - assertNotNull(employeeDescriptor.getFetchGroupManager().getDefaultFetchGroup()); + assertNull(getFetchGroup(query)); + assertNotNull(employeeDescriptor.getFetchGroupManager().getDefaultFetchGroup()); - query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false"); - assertNull(getFetchGroup(query)); + query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false"); + assertNull(getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertNotNull(emp); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); - assertNoFetchGroup(emp.getAddress()); + assertNotNull(emp); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); + assertNoFetchGroup(emp.getAddress()); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } + + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void resultListNoFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false"); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false"); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1, emps.size()); + assertNotNull(emps); + assertEquals(1, emps.size()); - Employee emp = emps.get(0); + Employee emp = emps.get(0); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp); + assertNoFetchGroup(emp.getAddress()); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + } + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void emptyFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - // Use q query since find will only use default fetch group - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup emptyFG = new FetchGroup("empty@" + System.currentTimeMillis()); - query.setHint(QueryHints.FETCH_GROUP, emptyFG); + // Use q query since find will only use default fetch group + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup emptyFG = new FetchGroup("empty@" + System.currentTimeMillis()); + query.setHint(QueryHints.FETCH_GROUP, emptyFG); - assertEquals(emptyFG, getFetchGroup(query)); + assertEquals(emptyFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertFetched(emp, emptyFG); + assertFetched(emp, emptyFG); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); - phone.getAreaCode(); - assertNoFetchGroup(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); + phone.getAreaCode(); + assertNoFetchGroup(phone); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void managerFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minimumEmployeeId(em)); - - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + //Use q query since find will only use default fetch group + //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + //query.setParameter("ID", minimumEmployeeId(em)); + + //Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - query.setHint(QueryHints.FETCH_GROUP, managerFG); - query.setHint(QueryHints.LEFT_FETCH, "e.manager"); + query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.LEFT_FETCH, "e.manager"); - assertEquals(managerFG, getFetchGroup(query)); + assertEquals(managerFG, getFetchGroup(query)); - List employees = query.getResultList(); - Employee emp = (Employee)employees.get(0); + List employees = query.getResultList(); + Employee emp = (Employee)employees.get(0); - assertFetched(emp, managerFG); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getManager(); + emp.getManager(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, managerFG); - emp.getLastName(); + emp.getLastName(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - int numPhones = 0; - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + int numPhones = 0; + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); - phone.getAreaCode(); + phone.getAreaCode(); - assertNoFetchGroup(phone); - numPhones++; + assertNoFetchGroup(phone); + numPhones++; + } + // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group + assertEquals(3 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group - assertEquals(3 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void employeeNamesFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - int minId = minimumEmployeeId(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int minId = minimumEmployeeId(em); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Use q query since find will only use default fetch group - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minId); + // Use q query since find will only use default fetch group + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minId); - FetchGroup namesFG = new FetchGroup(); - namesFG.addAttribute("firstName"); - namesFG.addAttribute("lastName"); - query.setHint(QueryHints.FETCH_GROUP, namesFG); + FetchGroup namesFG = new FetchGroup(); + namesFG.addAttribute("firstName"); + namesFG.addAttribute("lastName"); + query.setHint(QueryHints.FETCH_GROUP, namesFG); - assertNotNull(getFetchGroup(query)); - assertSame(namesFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(namesFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getId(); - emp.getFirstName(); - emp.getLastName(); - emp.getVersion(); + emp.getId(); + emp.getFirstName(); + emp.getLastName(); + emp.getVersion(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getGender(); - emp.getSalary(); + emp.getGender(); + emp.getSalary(); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - int numPhones = 0; - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertDefaultFetched(phone); + int numPhones = 0; + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertDefaultFetched(phone); - phone.getAreaCode(); + phone.getAreaCode(); - assertNoFetchGroup(phone); - numPhones++; - } - // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group - assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(phone); + numPhones++; + } + // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group + assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if(emp.getManager() != null) { - assertEquals(5 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertDefaultFetched(emp.getManager()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if(emp.getManager() != null) { + assertEquals(5 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertDefaultFetched(emp.getManager()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -553,33 +621,41 @@ } void internalJoinFetchEmployeeAddressPhoneWithDynamicFetchGroup(boolean addAddressToFetchGroup) { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.owner.id FROM PhoneNumber p)"); + Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.owner.id FROM PhoneNumber p)"); - FetchGroup fetchGroup = new FetchGroup("names"); - fetchGroup.addAttribute("firstName"); - fetchGroup.addAttribute("lastName"); - if(addAddressToFetchGroup) { - fetchGroup.addAttribute("address"); - } - query.setHint(QueryHints.FETCH_GROUP, fetchGroup); + FetchGroup fetchGroup = new FetchGroup("names"); + fetchGroup.addAttribute("firstName"); + fetchGroup.addAttribute("lastName"); + if(addAddressToFetchGroup) { + fetchGroup.addAttribute("address"); + } + query.setHint(QueryHints.FETCH_GROUP, fetchGroup); - List emps = query.getResultList(); - assertNotNull(emps); + List emps = query.getResultList(); + assertNotNull(emps); - if(addAddressToFetchGroup) { - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - assertEquals(1 + 2*emps.size(), getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } - for (Employee emp : emps) { if(addAddressToFetchGroup) { - assertFetched(emp, fetchGroup); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } else { - // the whole object has been instantiated when address has been set - assertNoFetchGroup(emp); + assertEquals(1 + 2*emps.size(), getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } + for (Employee emp : emps) { + if(addAddressToFetchGroup) { + assertFetched(emp, fetchGroup); + } else { + // the whole object has been instantiated when address has been set + assertNoFetchGroup(emp); + } } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); + } } public static class EmployeeCustomizer implements DescriptorCustomizer { Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleFetchGroupTests.java (working copy) @@ -55,8 +55,6 @@ suite.addTest(new SimpleFetchGroupTests("findNoFetchGroup")); suite.addTest(new SimpleFetchGroupTests("singleResultNoFetchGroup")); suite.addTest(new SimpleFetchGroupTests("resultListNoFetchGroup")); - suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup")); - suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary")); suite.addTest(new SimpleFetchGroupTests("singleResultEmptyFetchGroup")); suite.addTest(new SimpleFetchGroupTests("resultListEmptyFetchGroup")); suite.addTest(new SimpleFetchGroupTests("resultListPeriodFetchGroup")); @@ -65,11 +63,14 @@ suite.addTest(new SimpleFetchGroupTests("employeeNamesFetchGroup")); suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup")); suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup")); - suite.addTest(new SimpleFetchGroupTests("verifyUnfetchedAttributes")); suite.addTest(new SimpleFetchGroupTests("verifyFetchedRelationshipAttributes")); suite.addTest(new SimpleFetchGroupTests("detachedByClosingEntityManagerObjectWithFetchGroup")); - suite.addTest(new SimpleFetchGroupTests("explicitlyDetachedObjectWithFetchGroup")); - + if (!isJPA10()) { + suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup")); + suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary")); + suite.addTest(new SimpleFetchGroupTests("verifyUnfetchedAttributes")); + suite.addTest(new SimpleFetchGroupTests("explicitlyDetachedObjectWithFetchGroup")); + } return suite; } @@ -176,177 +177,203 @@ @Test public void findEmptyFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); - int minId = minimumEmployeeId(em); + try { + beginTransaction(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int minId = minimumEmployeeId(em); - Map properties = new HashMap(); - FetchGroup emptyFG = new FetchGroup(); - properties.put(QueryHints.FETCH_GROUP, emptyFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - Employee emp = em.find(Employee.class, minId, properties); + Map properties = new HashMap(); + FetchGroup emptyFG = new FetchGroup(); + properties.put(QueryHints.FETCH_GROUP, emptyFG); - assertNotNull(emp); - assertFetched(emp, emptyFG); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + Employee emp = em.find(Employee.class, minId, properties); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + assertNotNull(emp); + assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - emp.getSalary(); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertFetchedAttribute(emp, "salary"); + emp.getSalary(); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertFetchedAttribute(emp, "salary"); - emp.getAddress(); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + emp.getAddress(); - emp.getPhoneNumbers().size(); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - } + emp.getPhoneNumbers().size(); - if (emp.getManager() != null) { - assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + + if (emp.getManager() != null) { + assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + }finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception { EntityManager em = createEntityManager("fieldaccess"); - int minId = minimumEmployeeId(em); + try { + beginTransaction(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int minId = minimumEmployeeId(em); - Map properties = new HashMap(); - FetchGroup emptyFG = new FetchGroup(); - properties.put(QueryHints.FETCH_GROUP, emptyFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - Employee emp = em.find(Employee.class, minId, properties); + Map properties = new HashMap(); + FetchGroup emptyFG = new FetchGroup(); + properties.put(QueryHints.FETCH_GROUP, emptyFG); - assertNotNull(emp); - assertFetched(emp, emptyFG); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + Employee emp = em.find(Employee.class, minId, properties); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.setSalary(1); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertFetchedAttribute(emp, "salary"); + emp.setSalary(1); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertFetchedAttribute(emp, "salary"); - emp.getAddress(); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + emp.getAddress(); - emp.getPhoneNumbers().size(); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + emp.getPhoneNumbers().size(); + + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @Test public void singleResultEmptyFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup emptyFG = new FetchGroup(); - query.setHint(QueryHints.FETCH_GROUP, emptyFG); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup emptyFG = new FetchGroup(); + query.setHint(QueryHints.FETCH_GROUP, emptyFG); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertNotNull(emp); - assertFetched(emp, emptyFG); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); + assertFetchedAttribute(emp, "salary"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - emp.getAddress(); + emp.getAddress(); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - emp.getPhoneNumbers().size(); + emp.getPhoneNumbers().size(); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -356,59 +383,67 @@ @Test public void resultListEmptyFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup emptyFG = new FetchGroup(); - query.setHint(QueryHints.FETCH_GROUP, emptyFG); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup emptyFG = new FetchGroup(); + query.setHint(QueryHints.FETCH_GROUP, emptyFG); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1, emps.size()); + assertNotNull(emps); + assertEquals(1, emps.size()); - Employee emp = emps.get(0); + Employee emp = emps.get(0); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, emptyFG); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); - assertNoFetchGroup(emp); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetchedAttribute(emp, "salary"); + assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } /** @@ -417,209 +452,241 @@ @Test public void resultListPeriodFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup fg = new FetchGroup(); - fg.addAttribute("period"); - query.setHint(QueryHints.FETCH_GROUP, fg); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup fg = new FetchGroup(); + fg.addAttribute("period"); + query.setHint(QueryHints.FETCH_GROUP, fg); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1, emps.size()); + assertNotNull(emps); + assertEquals(1, emps.size()); - Employee emp = emps.get(0); + Employee emp = emps.get(0); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, fg); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, fg); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); - assertNoFetchGroup(emp); + assertFetchedAttribute(emp, "salary"); + assertNoFetchGroup(emp); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void managerFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minimumEmployeeId(em)); - - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + // Use q query since find will only use default fetch group + //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + //query.setParameter("ID", minimumEmployeeId(em)); + + // Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.FETCH_GROUP, managerFG); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertFetched(emp, managerFG); -// int nSqlBeforeGetManager = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); - // manager hasn't been instantiated yet - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - int nSqlToAdd = 0; - if (emp.getManager() != null) { - assertFetchedAttribute(emp, "manager"); - // additional sql to select the manager - nSqlToAdd++; - } - assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // acuses instantioation of the whole object - emp.getLastName(); + assertFetched(emp, managerFG); + //int nSqlBeforeGetManager = getQuerySQLTracker(em).getTotalSQLSELECTCalls(); + // manager hasn't been instantiated yet + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + int nSqlToAdd = 0; + if (emp.getManager() != null) { + assertFetchedAttribute(emp, "manager"); + // additional sql to select the manager + nSqlToAdd++; + } + assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // acuses instantioation of the whole object + emp.getLastName(); - assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + + assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void managerFetchGroupWithJoinFetch() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); -// int minId = minimumEmployeeId(em); -// assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + //int minId = minimumEmployeeId(em); + //assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minId); + // Use q query since find will only use default fetch group + //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + //query.setParameter("ID", minId); - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + // Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - query.setHint(QueryHints.FETCH_GROUP, managerFG); - query.setHint(QueryHints.LEFT_FETCH, "e.manager"); + query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.LEFT_FETCH, "e.manager"); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertFetched(emp, managerFG); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // manager (if not null) is instantiated by the fetch group, before emp.getManager call. - emp.getManager(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // instantiates the whole object - emp.getLastName(); + assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // manager (if not null) is instantiated by the fetch group, before emp.getManager call. + emp.getManager(); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // instantiates the whole object + emp.getLastName(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void employeeNamesFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - int minId = minimumEmployeeId(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int minId = minimumEmployeeId(em); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Use q query since find will only use default fetch group - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minId); - FetchGroup namesFG = new FetchGroup(); - namesFG.addAttribute("firstName"); - namesFG.addAttribute("lastName"); + // Use q query since find will only use default fetch group + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minId); + FetchGroup namesFG = new FetchGroup(); + namesFG.addAttribute("firstName"); + namesFG.addAttribute("lastName"); - query.setHint(QueryHints.FETCH_GROUP, namesFG); + query.setHint(QueryHints.FETCH_GROUP, namesFG); - assertNotNull(getFetchGroup(query)); - assertSame(namesFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(namesFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getId(); - emp.getFirstName(); - emp.getLastName(); - emp.getVersion(); + emp.getId(); + emp.getFirstName(); + emp.getLastName(); + emp.getVersion(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getGender(); - emp.getSalary(); + emp.getGender(); + emp.getSalary(); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); - } - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if (emp.getManager() != null) { - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getManager()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getManager() != null) { + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getManager()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -658,29 +725,36 @@ @Test public void verifyUnfetchedAttributes() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); + TypedQuery q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.owner.id) FROM PhoneNumber p)", Employee.class); + FetchGroup fg = new FetchGroup("Employee.empty"); + q.setHint(QueryHints.FETCH_GROUP, fg); + Employee emp = q.getSingleResult(); - TypedQuery q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.owner.id) FROM PhoneNumber p)", Employee.class); - FetchGroup fg = new FetchGroup("Employee.empty"); - q.setHint(QueryHints.FETCH_GROUP, fg); - Employee emp = q.getSingleResult(); + assertNotNull(emp); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNotNull(emp); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + // This check using the mapping returns a default (empty) IndirectList + /*OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers"); + IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp); + assertNotNull(phones); + assertTrue(phones.isInstantiated()); + assertEquals(0, phones.size()); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/ - // This check using the mapping returns a default (empty) IndirectList -/* OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers"); - IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp); - assertNotNull(phones); - assertTrue(phones.isInstantiated()); - assertEquals(0, phones.size()); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/ + IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers(); + assertFalse(phonesIL.isInstantiated()); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers(); - assertFalse(phonesIL.isInstantiated()); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - assertTrue(emp.getPhoneNumbers().size() > 0); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertTrue(emp.getPhoneNumbers().size() > 0); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); + } } @Test @@ -725,20 +799,27 @@ @Test public void explicitlyDetachedObjectWithFetchGroup() { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); + FetchGroup fg = new FetchGroup(); + fg.addAttribute("firstName"); + fg.addAttribute("lastName"); - FetchGroup fg = new FetchGroup(); - fg.addAttribute("firstName"); - fg.addAttribute("lastName"); + Map hints = new HashMap(); + hints.put(QueryHints.FETCH_GROUP, fg); - Map hints = new HashMap(); - hints.put(QueryHints.FETCH_GROUP, fg); - - Employee emp = minimumEmployee(em, hints); - em.detach(emp); - assertFetched(emp, fg); - - // trigger the fetch group - emp.getSalary(); - assertNoFetchGroup(emp); + Employee emp = minimumEmployee(em, hints); + em.detach(emp); + assertFetched(emp, fg); + + // trigger the fetch group + emp.getSalary(); + assertNoFetchGroup(emp); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); + } } } Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleNamedFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleNamedFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleNamedFetchGroupTests.java (working copy) @@ -269,48 +269,55 @@ @Test public void managerFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); + // Use q query since find will only use default fetch group + // Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + // query.setParameter("ID", minimumEmployeeId(em)); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minimumEmployeeId(em)); + // Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + query.setHint(QueryHints.FETCH_GROUP, managerFG); - query.setHint(QueryHints.FETCH_GROUP, managerFG); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + Employee emp = (Employee) query.getSingleResult(); - Employee emp = (Employee) query.getSingleResult(); + assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + int nSqlToAdd = 0; + if (emp.getManager() != null) { + assertFetchedAttribute(emp, "manager"); + // additional sql to select the manager + nSqlToAdd++; + } + + assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, managerFG); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - int nSqlToAdd = 0; - if (emp.getManager() != null) { - assertFetchedAttribute(emp, "manager"); - // additional sql to select the manager - nSqlToAdd++; - } - - assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + // instantiates the whole object + emp.getLastName(); - // instantiates the whole object - emp.getLastName(); + assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test Index: jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleSerializeFetchGroupTests.java =================================================================== --- jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleSerializeFetchGroupTests.java (revision 7828) +++ jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleSerializeFetchGroupTests.java (working copy) @@ -12,6 +12,9 @@ ******************************************************************************/ package org.eclipse.persistence.testing.tests.jpa.fieldaccess.fetchgroups; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; @@ -65,8 +68,6 @@ suite.addTest(new SimpleSerializeFetchGroupTests("testSetup")); suite.addTest(new SimpleSerializeFetchGroupTests("verifyWriteReplaceOnFetchGroup")); - suite.addTest(new SimpleSerializeFetchGroupTests("findMinimalFetchGroup")); - suite.addTest(new SimpleSerializeFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary")); suite.addTest(new SimpleSerializeFetchGroupTests("verifyAddAttributeInDetachedEntityFetchGroup")); suite.addTest(new SimpleSerializeFetchGroupTests("singleResultEmptyFetchGroup")); suite.addTest(new SimpleSerializeFetchGroupTests("resultListEmptyFetchGroup")); @@ -76,19 +77,23 @@ suite.addTest(new SimpleSerializeFetchGroupTests("employeeNamesFetchGroup")); suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup")); suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup")); - suite.addTest(new SimpleSerializeFetchGroupTests("verifyUnfetchedAttributes")); suite.addTest(new SimpleSerializeFetchGroupTests("verifyFetchedRelationshipAttributes")); - suite.addTest(new SimpleSerializeFetchGroupTests("simpleSerializeAndMerge")); - suite.addTest(new SimpleSerializeFetchGroupTests("partialMerge")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge2")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPk")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPkUseFullGroup")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPk")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPkUseFullGroup")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyNoCascade")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadePrivateParts")); - suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadeAllParts")); + if (!isJPA10()) { + suite.addTest(new SimpleSerializeFetchGroupTests("findMinimalFetchGroup")); + suite.addTest(new SimpleSerializeFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary")); + suite.addTest(new SimpleSerializeFetchGroupTests("verifyUnfetchedAttributes")); + suite.addTest(new SimpleSerializeFetchGroupTests("simpleSerializeAndMerge")); + suite.addTest(new SimpleSerializeFetchGroupTests("partialMerge")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge2")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPk")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPkUseFullGroup")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPk")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPkUseFullGroup")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyNoCascade")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadePrivateParts")); + suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadeAllParts")); + } return suite; } @@ -96,10 +101,10 @@ @Test public void verifyWriteReplaceOnFetchGroup() throws Exception { EntityFetchGroup fg = new EntityFetchGroup(new String[]{"basic", "a"}); -// fg.addAttribute("basic"); -// fg.addAttribute("a.b"); + //fg.addAttribute("basic"); + //fg.addAttribute("a.b"); -// assertTrue(fg.getClass() == FetchGroup.class); + //assertTrue(fg.getClass() == FetchGroup.class); FetchGroup serFG = serialize(fg); @@ -110,15 +115,15 @@ AttributeItem basicFI = serFG.getItem("basic"); assertNotNull(basicFI); -// assertTrue(basicFI instanceof DetachedFetchItem); + //assertTrue(basicFI instanceof DetachedFetchItem); AttributeItem aFI = serFG.getItem("a"); assertNotNull(aFI); -// assertTrue(aFI instanceof DetachedFetchItem); + //assertTrue(aFI instanceof DetachedFetchItem); // serialized EntityFetchGroup is always flat - doesn't have nested groups. assertNull(aFI.getGroup()); -/* assertNotNull(aFI.getGroup()); + /*assertNotNull(aFI.getGroup()); assertTrue(aFI.getGroup() instanceof EntityFetchGroup); EntityFetchGroup aEFG = (EntityFetchGroup) aFI.getGroup(); assertNull(aEFG.getParent()); @@ -127,7 +132,7 @@ AttributeItem bFI = aEFG.getItem("b"); assertNotNull(bFI); -// assertTrue(bFI instanceof DetachedFetchItem); + //assertTrue(bFI instanceof DetachedFetchItem); assertNull(bFI.getGroup());*/ } @@ -194,57 +199,65 @@ public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception { EntityManager em = createEntityManager("fieldaccess"); int minId = minimumEmployeeId(em); + try { + beginTransaction(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - Map properties = new HashMap(); - FetchGroup emptyFG = new FetchGroup(); - properties.put(QueryHints.FETCH_GROUP, emptyFG); + Map properties = new HashMap(); + FetchGroup emptyFG = new FetchGroup(); + properties.put(QueryHints.FETCH_GROUP, emptyFG); - Employee emp = em.find(Employee.class, minId, properties); + Employee emp = em.find(Employee.class, minId, properties); - assertNotNull(emp); - assertFetched(emp, emptyFG); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - emp.setSalary(1); + emp.setSalary(1); - assertFetchedAttribute(emp, "salary"); + assertFetchedAttribute(emp, "salary"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - emp.getAddress(); + emp.getAddress(); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - emp.getPhoneNumbers().size(); + emp.getPhoneNumbers().size(); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -256,96 +269,104 @@ public void verifyAddAttributeInDetachedEntityFetchGroup() { EntityFetchGroup detFG = new EntityFetchGroup(new String[]{"basic", "a"}); -// detFG.addAttribute("basic"); -// detFG.addAttribute("a.b"); + //detFG.addAttribute("basic"); + //detFG.addAttribute("a.b"); -// assertNull(detFG.getParent()); + //assertNull(detFG.getParent()); assertEquals(2, detFG.getItems().size()); AttributeItem basicItem = detFG.getItem("basic"); assertNotNull(basicItem); assertEquals("basic", basicItem.getAttributeName()); -// assertTrue(basicItem instanceof DetachedFetchItem); + //assertTrue(basicItem instanceof DetachedFetchItem); assertNull(basicItem.getGroup()); assertSame(detFG, basicItem.getParent()); -// assertFalse(basicItem.useDefaultFetchGroup()); + //assertFalse(basicItem.useDefaultFetchGroup()); AttributeItem aItem = detFG.getItem("a"); assertNotNull(aItem); assertEquals("a", aItem.getAttributeName()); -// assertTrue(aItem instanceof DetachedFetchItem); + //assertTrue(aItem instanceof DetachedFetchItem); // serialized EntityFetchGroup is always flat - doesn't have nested groups. -//// assertNull(aItem.getGroup()); + //assertNull(aItem.getGroup()); assertNull(aItem.getGroup()); assertSame(detFG, aItem.getParent()); -// assertFalse(aItem.useDefaultFetchGroup()); -// assertTrue(aItem.getGroup() instanceof EntityFetchGroup); + //assertFalse(aItem.useDefaultFetchGroup()); + //assertTrue(aItem.getGroup() instanceof EntityFetchGroup); -// EntityFetchGroup aFG = (EntityFetchGroup) aItem.getGroup(); + //EntityFetchGroup aFG = (EntityFetchGroup) aItem.getGroup(); -// assertEquals(1, aFG.getItems().size()); + //assertEquals(1, aFG.getItems().size()); -// AttributeItem bItem = aFG.getItem("b"); -// assertNotNull(bItem); -// assertEquals("b", bItem.getAttributeName()); -// assertTrue(bItem instanceof DetachedFetchItem); - // assertNull(bItem.getGroup()); -// assertSame(aFG, bItem.getParent()); -// assertFalse(bItem.useDefaultFetchGroup()); + //AttributeItem bItem = aFG.getItem("b"); + //assertNotNull(bItem); + //assertEquals("b", bItem.getAttributeName()); + //assertTrue(bItem instanceof DetachedFetchItem); + //assertNull(bItem.getGroup()); + //assertSame(aFG, bItem.getParent()); + //assertFalse(bItem.useDefaultFetchGroup()); } @Test public void singleResultEmptyFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup emptyFG = new FetchGroup(); - query.setHint(QueryHints.FETCH_GROUP, emptyFG); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup emptyFG = new FetchGroup(); + query.setHint(QueryHints.FETCH_GROUP, emptyFG); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertNotNull(emp); - assertFetched(emp, emptyFG); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); + assertFetchedAttribute(emp, "salary"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - emp.getAddress(); + emp.getAddress(); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getAddress()); - emp.getPhoneNumbers().size(); + emp.getPhoneNumbers().size(); - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -355,59 +376,67 @@ @Test public void resultListEmptyFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup emptyFG = new FetchGroup(); - query.setHint(QueryHints.FETCH_GROUP, emptyFG); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup emptyFG = new FetchGroup(); + query.setHint(QueryHints.FETCH_GROUP, emptyFG); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1, emps.size()); + assertNotNull(emps); + assertEquals(1, emps.size()); - Employee emp = emps.get(0); + Employee emp = emps.get(0); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, emptyFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, emptyFG); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); - assertNoFetchGroup(emp); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetchedAttribute(emp, "salary"); + assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } /** @@ -416,209 +445,241 @@ @Test public void resultListPeriodFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minimumEmployeeId(em)); - FetchGroup fg = new FetchGroup(); - fg.addAttribute("period"); - query.setHint(QueryHints.FETCH_GROUP, fg); + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minimumEmployeeId(em)); + FetchGroup fg = new FetchGroup(); + fg.addAttribute("period"); + query.setHint(QueryHints.FETCH_GROUP, fg); - List emps = query.getResultList(); + List emps = query.getResultList(); - assertNotNull(emps); - assertEquals(1, emps.size()); + assertNotNull(emps); + assertEquals(1, emps.size()); - Employee emp = emps.get(0); + Employee emp = emps.get(0); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, fg); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, fg); - // Check Basics - assertFetchedAttribute(emp, "id"); - assertFetchedAttribute(emp, "version"); - assertNotFetchedAttribute(emp, "firstName"); - assertNotFetchedAttribute(emp, "lastName"); - assertNotFetchedAttribute(emp, "gender"); - assertNotFetchedAttribute(emp, "salary"); - assertNotFetchedAttribute(emp, "startTime"); - assertNotFetchedAttribute(emp, "endTime"); - if (emp.getPeriod() != null) { - assertFetchedAttribute(emp.getPeriod(), "startDate"); - assertFetchedAttribute(emp.getPeriod(), "endDate"); - } + // Check Basics + assertFetchedAttribute(emp, "id"); + assertFetchedAttribute(emp, "version"); + assertNotFetchedAttribute(emp, "firstName"); + assertNotFetchedAttribute(emp, "lastName"); + assertNotFetchedAttribute(emp, "gender"); + assertNotFetchedAttribute(emp, "salary"); + assertNotFetchedAttribute(emp, "startTime"); + assertNotFetchedAttribute(emp, "endTime"); + if (emp.getPeriod() != null) { + assertFetchedAttribute(emp.getPeriod(), "startDate"); + assertFetchedAttribute(emp.getPeriod(), "endDate"); + } - // Check Relationships - assertNotFetchedAttribute(emp, "address"); - assertNotFetchedAttribute(emp, "manager"); - assertNotFetchedAttribute(emp, "phoneNumbers"); - assertNotFetchedAttribute(emp, "projects"); + // Check Relationships + assertNotFetchedAttribute(emp, "address"); + assertNotFetchedAttribute(emp, "manager"); + assertNotFetchedAttribute(emp, "phoneNumbers"); + assertNotFetchedAttribute(emp, "projects"); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getSalary(); + emp.getSalary(); - assertFetchedAttribute(emp, "salary"); - assertNoFetchGroup(emp); + assertFetchedAttribute(emp, "salary"); + assertNoFetchGroup(emp); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getAddress()); + assertNoFetchGroup(emp.getAddress()); - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + } + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void managerFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minimumEmployeeId(em)); + // Use q query since find will only use default fetch group + //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + //query.setParameter("ID", minimumEmployeeId(em)); - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + // Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.FETCH_GROUP, managerFG); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertFetched(emp, managerFG); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // manager (if not null) hasn't been instantiated yet. - int nSqlToAdd = 0; - if (emp.getManager() != null) { - assertFetchedAttribute(emp, "manager"); - // additional sql to select the manager - nSqlToAdd++; - } - - assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // manager (if not null) hasn't been instantiated yet. + int nSqlToAdd = 0; + if (emp.getManager() != null) { + assertFetchedAttribute(emp, "manager"); + // additional sql to select the manager + nSqlToAdd++; + } + + assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - emp.getLastName(); + emp.getLastName(); - assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + + assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void managerFetchGroupWithJoinFetch() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); -// int minId = minimumEmployeeId(em); -// assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + //int minId = minimumEmployeeId(em); + //assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Use q query since find will only use default fetch group -// Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); -// query.setParameter("ID", minId); + // Use q query since find will only use default fetch group + //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + //query.setParameter("ID", minId); - // Complex where clause used to avoid triggering employees and their departments: - // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; - // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); + // Complex where clause used to avoid triggering employees and their departments: + // Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered; + // Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL"); - FetchGroup managerFG = new FetchGroup(); - managerFG.addAttribute("manager"); + FetchGroup managerFG = new FetchGroup(); + managerFG.addAttribute("manager"); - query.setHint(QueryHints.FETCH_GROUP, managerFG); - query.setHint(QueryHints.LEFT_FETCH, "e.manager"); + query.setHint(QueryHints.FETCH_GROUP, managerFG); + query.setHint(QueryHints.LEFT_FETCH, "e.manager"); - assertNotNull(getFetchGroup(query)); - assertSame(managerFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(managerFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertFetched(emp, managerFG); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // manager has been already instantiated by the query. - emp.getManager(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - - // instantiates the whiole object - emp.getLastName(); + assertFetched(emp, managerFG); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // manager has been already instantiated by the query. + emp.getManager(); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + + // instantiates the whiole object + emp.getLastName(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } - - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); } @Test public void employeeNamesFetchGroup() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - int minId = minimumEmployeeId(em); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + int minId = minimumEmployeeId(em); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // Use q query since find will only use default fetch group - Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); - query.setParameter("ID", minId); - FetchGroup namesFG = new FetchGroup(); - namesFG.addAttribute("firstName"); - namesFG.addAttribute("lastName"); + // Use q query since find will only use default fetch group + Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID"); + query.setParameter("ID", minId); + FetchGroup namesFG = new FetchGroup(); + namesFG.addAttribute("firstName"); + namesFG.addAttribute("lastName"); - query.setHint(QueryHints.FETCH_GROUP, namesFG); + query.setHint(QueryHints.FETCH_GROUP, namesFG); - assertNotNull(getFetchGroup(query)); - assertSame(namesFG, getFetchGroup(query)); + assertNotNull(getFetchGroup(query)); + assertSame(namesFG, getFetchGroup(query)); - Employee emp = (Employee) query.getSingleResult(); + Employee emp = (Employee) query.getSingleResult(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getId(); - emp.getFirstName(); - emp.getLastName(); - emp.getVersion(); + emp.getId(); + emp.getFirstName(); + emp.getLastName(); + emp.getVersion(); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertFetched(emp, namesFG); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertFetched(emp, namesFG); - emp.getGender(); - emp.getSalary(); + emp.getGender(); + emp.getSalary(); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp); - for (PhoneNumber phone : emp.getPhoneNumbers()) { - assertNoFetchGroup(phone); - phone.getAreaCode(); - } - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + for (PhoneNumber phone : emp.getPhoneNumbers()) { + assertNoFetchGroup(phone); + phone.getAreaCode(); + } + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - if (emp.getManager() != null) { - assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertNoFetchGroup(emp.getManager()); - } else { - // If manager_id field is null then getManager() does not trigger an sql. - assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + if (emp.getManager() != null) { + assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNoFetchGroup(emp.getManager()); + } else { + // If manager_id field is null then getManager() does not trigger an sql. + assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); } } @@ -657,29 +718,37 @@ @Test public void verifyUnfetchedAttributes() throws Exception { EntityManager em = createEntityManager("fieldaccess"); + try { + beginTransaction(em); - TypedQuery q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.owner.id) FROM PhoneNumber p)", Employee.class); - FetchGroup fg = new FetchGroup("Employee.empty"); - q.setHint(QueryHints.FETCH_GROUP, fg); - Employee emp = q.getSingleResult(); + TypedQuery q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.owner.id) FROM PhoneNumber p)", Employee.class); + FetchGroup fg = new FetchGroup("Employee.empty"); + q.setHint(QueryHints.FETCH_GROUP, fg); + Employee emp = q.getSingleResult(); - assertNotNull(emp); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertNotNull(emp); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - // This check using the mapping returns a default (empty) IndirectList -/* OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers"); - IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp); - assertNotNull(phones); - assertTrue(phones.isInstantiated()); - assertEquals(0, phones.size()); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/ + // This check using the mapping returns a default (empty) IndirectList + /*OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers"); + IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp); + assertNotNull(phones); + assertTrue(phones.isInstantiated()); + assertEquals(0, phones.size()); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/ - IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers(); - assertFalse(phonesIL.isInstantiated()); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers(); + assertFalse(phonesIL.isInstantiated()); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - assertTrue(emp.getPhoneNumbers().size() > 0); - assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + assertTrue(emp.getPhoneNumbers().size() > 0); + assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + } finally { + if (isTransactionActive(em)){ + rollbackTransaction(em); + } + closeEntityManager(em); + } } @Test @@ -805,7 +874,7 @@ em.clear(); HashMap hints = new HashMap(2); hints.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly); -// hints.put(QueryHints.FETCH_GROUP, fetchGroup); + //hints.put(QueryHints.FETCH_GROUP, fetchGroup); Employee empShared = em.find(Employee.class, id, hints); assertEquals("newFirstName", empShared.getFirstName()); assertEquals("newLastName", empShared.getLastName()); @@ -853,7 +922,7 @@ closeEntityManager(em); } } -/* public void simpleSerializeAndMerge() throws Exception { + /*public void simpleSerializeAndMerge() throws Exception { EntityManager em = createEntityManager("fieldaccess"); int id = minimumEmployeeId(em); // save the original Employee for clean up @@ -932,119 +1001,131 @@ public void partialMerge() throws Exception { EntityManager em = createEntityManager("fieldaccess"); // Search for an Employee with an Address and Phone Numbers - TypedQuery query = em.createQuery("SELECT e FROM Employee e WHERE e.address IS NOT NULL AND e.id IN (SELECT MIN(p.owner.id) FROM PhoneNumber p)", Employee.class); - - // Load only its names and phone Numbers - FetchGroup fetchGroup = new FetchGroup(); - fetchGroup.addAttribute("firstName"); - fetchGroup.addAttribute("lastName"); - FetchGroup phonesFG = phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); - // that ensures the owner is not instantiated - phonesFG.addAttribute("owner.id"); - phonesFG.removeAttribute("status"); - phonesFG.setShouldLoad(true); - fetchGroup.addAttribute("phoneNumbers", phonesFG); - - // Make sure the FetchGroup also forces the relationships to be loaded - fetchGroup.setShouldLoad(true); - query.setHint(QueryHints.FETCH_GROUP, fetchGroup); - - Employee emp = query.getSingleResult(); - - // Detach Employee through Serialization - Employee detachedEmp = (Employee) SerializationHelper.clone(emp); - // Modify the detached Employee inverting the names, adding a phone number, and setting the salary - detachedEmp.setFirstName(emp.getLastName()); - detachedEmp.setLastName(emp.getFirstName()); - detachedEmp.addPhoneNumber(new PhoneNumber("TEST", "999", "999999")); - // NOte that salary was not part of the original FetchGroupdetachedEmp.setSalary(1); - detachedEmp.setSalary(1); - - beginTransaction(em); - // Merge the detached employee - em.merge(detachedEmp); - // Flush the changes to the database - em.flush(); - rollbackTransaction(em); + try { + beginTransaction(em); + TypedQuery query = em.createQuery("SELECT e FROM Employee e WHERE e.address IS NOT NULL AND e.id IN (SELECT MIN(p.owner.id) FROM PhoneNumber p)", Employee.class); + + // Load only its names and phone Numbers + FetchGroup fetchGroup = new FetchGroup(); + fetchGroup.addAttribute("firstName"); + fetchGroup.addAttribute("lastName"); + FetchGroup phonesFG = phoneDescriptor.getFetchGroupManager().createFullFetchGroup(); + // that ensures the owner is not instantiated + phonesFG.addAttribute("owner.id"); + phonesFG.removeAttribute("status"); + phonesFG.setShouldLoad(true); + fetchGroup.addAttribute("phoneNumbers", phonesFG); + + // Make sure the FetchGroup also forces the relationships to be loaded + fetchGroup.setShouldLoad(true); + query.setHint(QueryHints.FETCH_GROUP, fetchGroup); + + Employee emp = query.getSingleResult(); + + // Detach Employee through Serialization + Employee detachedEmp = (Employee)clone(emp); + + // Modify the detached Employee inverting the names, adding a phone number, and setting the salary + detachedEmp.setFirstName(emp.getLastName()); + detachedEmp.setLastName(emp.getFirstName()); + detachedEmp.addPhoneNumber(new PhoneNumber("TEST", "999", "999999")); + // NOte that salary was not part of the original FetchGroupdetachedEmp.setSalary(1); + detachedEmp.setSalary(1); + + // Merge the detached employee + em.merge(detachedEmp); + // Flush the changes to the database + em.flush(); + } finally { + rollbackTransaction(em); + closeEntityManager(em); + } } public void copyGroupMerge() { // Search for an Employee with an Address and Phone Numbers EntityManager em = createEntityManager("fieldaccess"); - TypedQuery query = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(ee.id) FROM Employee ee)", Employee.class); - Employee emp = query.getSingleResult(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - System.out.println(">>> Employee retrieved"); - - // Copy only its names and phone Numbers - AttributeGroup group = new CopyGroup(); - group.addAttribute("firstName"); - group.addAttribute("lastName"); - group.addAttribute("address"); - - Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - System.out.println(">>> Employee copied"); - - // Modify the detached Employee inverting the names, adding a phone number, and setting the salary - empCopy.setFirstName(emp.getLastName()); - empCopy.setLastName(emp.getFirstName()); - - // Note that salary was not part of the original FetchGroup - //empCopy.setSalary(1); - - beginTransaction(em); - // Merge the detached employee - em.merge(empCopy); - System.out.println(">>> Sparse merge complete"); - - // Flush the changes to the database - em.flush(); - System.out.println(">>> Flush complete"); - - rollbackTransaction(em); + try { + beginTransaction(em); + TypedQuery query = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(ee.id) FROM Employee ee)", Employee.class); + Employee emp = query.getSingleResult(); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + System.out.println(">>> Employee retrieved"); + + // Copy only its names and phone Numbers + AttributeGroup group = new CopyGroup(); + group.addAttribute("firstName"); + group.addAttribute("lastName"); + group.addAttribute("address"); + + Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + System.out.println(">>> Employee copied"); + + // Modify the detached Employee inverting the names, adding a phone number, and setting the salary + empCopy.setFirstName(emp.getLastName()); + empCopy.setLastName(emp.getFirstName()); + + // Note that salary was not part of the original FetchGroup + //empCopy.setSalary(1); + + // Merge the detached employee + em.merge(empCopy); + System.out.println(">>> Sparse merge complete"); + + // Flush the changes to the database + em.flush(); + System.out.println(">>> Flush complete"); + } finally { + rollbackTransaction(em); + closeEntityManager(em); + } } public void copyGroupMerge2() { // Search for an Employee with an Address and Phone Numbers EntityManager em = createEntityManager("fieldaccess"); - TypedQuery query = em.createQuery("SELECT e FROM Employee e", Employee.class); - query.setHint(QueryHints.BATCH, "e.address"); - List employees = query.getResultList(); - assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - System.out.println(">>> Employees retrieved"); - - // Copy only its names and phone Numbers - AttributeGroup group = new CopyGroup(); - group.addAttribute("firstName"); - group.addAttribute("lastName"); - group.addAttribute("address"); - - List employeesCopy = (List) em.unwrap(JpaEntityManager.class).copy(employees, group); - assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); - System.out.println(">>> Employees copied"); - - beginTransaction(em); - for(Employee empCopy : employeesCopy) { - // Modify the detached Employee inverting the names, adding a phone number, and setting the salary - String firstName = empCopy.getFirstName(); - String lastName = empCopy.getLastName(); - empCopy.setFirstName(lastName); - empCopy.setLastName(firstName); - - // Note that salary was not part of the original FetchGroup - //empCopy.setSalary(1); + try { + beginTransaction(em); + TypedQuery query = em.createQuery("SELECT e FROM Employee e", Employee.class); + query.setHint(QueryHints.BATCH, "e.address"); + List employees = query.getResultList(); + assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + System.out.println(">>> Employees retrieved"); - // Merge the detached employee - em.merge(empCopy); + // Copy only its names and phone Numbers + AttributeGroup group = new CopyGroup(); + group.addAttribute("firstName"); + group.addAttribute("lastName"); + group.addAttribute("address"); + + List employeesCopy = (List) em.unwrap(JpaEntityManager.class).copy(employees, group); + assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); + System.out.println(">>> Employees copied"); + + for(Employee empCopy : employeesCopy) { + // Modify the detached Employee inverting the names, adding a phone number, and setting the salary + String firstName = empCopy.getFirstName(); + String lastName = empCopy.getLastName(); + empCopy.setFirstName(lastName); + empCopy.setLastName(firstName); + + // Note that salary was not part of the original FetchGroup + //empCopy.setSalary(1); + + // Merge the detached employee + em.merge(empCopy); + } + System.out.println(">>> Sparse merge complete"); + + // Flush the changes to the database + em.flush(); + System.out.println(">>> Flush complete"); + + } finally { + rollbackTransaction(em); + closeEntityManager(em); } - System.out.println(">>> Sparse merge complete"); - - // Flush the changes to the database - em.flush(); - System.out.println(">>> Flush complete"); - - rollbackTransaction(em); } @Test @@ -1137,11 +1218,11 @@ } EntityManager em = createEntityManager("fieldaccess"); - Employee emp = minimumEmployee(em); - Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group); - - beginTransaction(em); try { + beginTransaction(em); + Employee emp = minimumEmployee(em); + Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group); + if(noPk) { assertNoFetchGroup(empCopy); assertNoFetchGroup(empCopy.getAddress()); @@ -1232,154 +1313,168 @@ void copyCascade(int cascadeDepth) { EntityManager em = createEntityManager("fieldaccess"); - Query query = em.createQuery("SELECT e FROM Employee e"); - List employees = query.getResultList(); + try { + beginTransaction(em); + Query query = em.createQuery("SELECT e FROM Employee e"); + List employees = query.getResultList(); - CopyGroup group = new CopyGroup(); - if(cascadeDepth == CopyGroup.NO_CASCADE) { - group.dontCascade(); - } else if(cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - // default cascade depth setting - group.cascadePrivateParts(); - } else if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) { - group.cascadeAllParts(); - } else { - fail("Invalid cascadeDepth = " + cascadeDepth); - } - group.setShouldResetPrimaryKey(true); - - List employeesCopy; - if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - // In this case the objects should be copied one by one - each one using a new CopyGroup. - // That ensures most referenced object are original ones (not copies) - - // the only exception is privately owned objects in CASCADE_PRIVATE_PARTS case. - employeesCopy = new ArrayList(employees.size()); - for(Employee emp : employees) { - CopyGroup groupClone = group.clone(); - employeesCopy.add((Employee)em.unwrap(JpaEntityManager.class).copy(emp, groupClone)); + CopyGroup group = new CopyGroup(); + if(cascadeDepth == CopyGroup.NO_CASCADE) { + group.dontCascade(); + } else if(cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + // default cascade depth setting + group.cascadePrivateParts(); + } else if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) { + group.cascadeAllParts(); + } else { + fail("Invalid cascadeDepth = " + cascadeDepth); } - } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS - // In this case all objects should be copied using a single CopyGroup. - // That ensures identities of the copies: - // for instance if several employees referenced the same project, - // then all copies of these employees will reference the single copy of the project. - employeesCopy = (List)em.unwrap(JpaEntityManager.class).copy(employees, group); - } - - // IdentityHashSets will be used to verify copy identities - IdentityHashSet originalEmployees = new IdentityHashSet(); - IdentityHashSet copyEmployees = new IdentityHashSet(); - IdentityHashSet originalAddresses = new IdentityHashSet(); - IdentityHashSet copyAddresses = new IdentityHashSet(); - IdentityHashSet originalProjects = new IdentityHashSet(); - IdentityHashSet copyProjects = new IdentityHashSet(); - IdentityHashSet originalPhones = new IdentityHashSet(); - IdentityHashSet copyPhones = new IdentityHashSet(); - - int size = employees.size(); - for(int i=0; i < size; i++) { - Employee emp = employees.get(i); - Employee empCopy = employeesCopy.get(i); - if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) { - originalEmployees.add(emp); - copyEmployees.add(empCopy); + group.setShouldResetPrimaryKey(true); + + List employeesCopy; + if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + // In this case the objects should be copied one by one - each one using a new CopyGroup. + // That ensures most referenced object are original ones (not copies) - + // the only exception is privately owned objects in CASCADE_PRIVATE_PARTS case. + employeesCopy = new ArrayList(employees.size()); + for(Employee emp : employees) { + CopyGroup groupClone = group.clone(); + employeesCopy.add((Employee)em.unwrap(JpaEntityManager.class).copy(emp, groupClone)); + } } else { - // cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS - // In this case all Employees referenced by empCopyes are originals (manager and managed employees). - // Therefore if we add here each emp and empCopy to originalEmployees and copyEmployees respectively - // then copyEmployees will always contain all original managers and managed + plus all copies. - // Therefore in this case originalEmployees and copyEmployees will contain only references (managers and managed employees). + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS + // In this case all objects should be copied using a single CopyGroup. + // That ensures identities of the copies: + // for instance if several employees referenced the same project, + // then all copies of these employees will reference the single copy of the project. + employeesCopy = (List)em.unwrap(JpaEntityManager.class).copy(employees, group); } + + // IdentityHashSets will be used to verify copy identities + IdentityHashSet originalEmployees = new IdentityHashSet(); + IdentityHashSet copyEmployees = new IdentityHashSet(); + IdentityHashSet originalAddresses = new IdentityHashSet(); + IdentityHashSet copyAddresses = new IdentityHashSet(); + IdentityHashSet originalProjects = new IdentityHashSet(); + IdentityHashSet copyProjects = new IdentityHashSet(); + IdentityHashSet originalPhones = new IdentityHashSet(); + IdentityHashSet copyPhones = new IdentityHashSet(); + + int size = employees.size(); + for(int i=0; i < size; i++) { + Employee emp = employees.get(i); + Employee empCopy = employeesCopy.get(i); + if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) { + originalEmployees.add(emp); + copyEmployees.add(empCopy); + } else { + // cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS + // In this case all Employees referenced by empCopyes are originals (manager and managed employees). + // Therefore if we add here each emp and empCopy to originalEmployees and copyEmployees respectively + // then copyEmployees will always contain all original managers and managed + plus all copies. + // Therefore in this case originalEmployees and copyEmployees will contain only references (managers and managed employees). + } - if(emp.getAddress() == null) { - assertTrue("emp.getAddress() == null, but empCopy.getAddress() != null", empCopy.getAddress() == null); - } else { - originalAddresses.add(emp.getAddress()); - copyAddresses.add(empCopy.getAddress()); - if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - assertTrue("address has been copied", emp.getAddress() == empCopy.getAddress()); + if(emp.getAddress() == null) { + assertTrue("emp.getAddress() == null, but empCopy.getAddress() != null", empCopy.getAddress() == null); } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS - assertFalse("address has not been copied", emp.getAddress() == empCopy.getAddress()); + originalAddresses.add(emp.getAddress()); + copyAddresses.add(empCopy.getAddress()); + if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + assertTrue("address has been copied", emp.getAddress() == empCopy.getAddress()); + } else { + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS + assertFalse("address has not been copied", emp.getAddress() == empCopy.getAddress()); + } } - } - boolean same; - for(Project project : emp.getProjects()) { - originalProjects.add(project); - same = false; - for(Project projectCopy : empCopy.getProjects()) { - copyProjects.add(projectCopy); - if(!same && project == projectCopy) { - same = true; + boolean same; + for(Project project : emp.getProjects()) { + originalProjects.add(project); + same = false; + for(Project projectCopy : empCopy.getProjects()) { + copyProjects.add(projectCopy); + if(!same && project == projectCopy) { + same = true; + } } + if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + assertTrue("project has been copied", same); + } else { + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS + assertFalse("project has not been copied", same); + } } - if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - assertTrue("project has been copied", same); - } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS - assertFalse("project has not been copied", same); - } - } - for(Employee managedEmp : emp.getManagedEmployees()) { - originalEmployees.add(managedEmp); - same = false; - for(Employee managedEmpCopy : empCopy.getManagedEmployees()) { - copyEmployees.add(managedEmpCopy); - if(!same && managedEmp == managedEmpCopy) { - same = true; + for(Employee managedEmp : emp.getManagedEmployees()) { + originalEmployees.add(managedEmp); + same = false; + for(Employee managedEmpCopy : empCopy.getManagedEmployees()) { + copyEmployees.add(managedEmpCopy); + if(!same && managedEmp == managedEmpCopy) { + same = true; + } } + if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + assertTrue("managedEmployee has been copied", same); + } else { + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS + assertFalse("managedEmployee has not been copied", same); + } } - if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - assertTrue("managedEmployee has been copied", same); + + if(emp.getManager() == null) { + assertTrue("emp.getManager() == null, but empCopy.getManager() != null", empCopy.getManager() == null); } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS - assertFalse("managedEmployee has not been copied", same); + originalEmployees.add(emp.getManager()); + copyEmployees.add(empCopy.getManager()); + if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { + assertTrue("manager has been copied", emp.getManager() == empCopy.getManager()); + } else { + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS + assertFalse("manager has not been copied", emp.getManager() == empCopy.getManager()); + } } - } - - if(emp.getManager() == null) { - assertTrue("emp.getManager() == null, but empCopy.getManager() != null", empCopy.getManager() == null); - } else { - originalEmployees.add(emp.getManager()); - copyEmployees.add(empCopy.getManager()); - if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) { - assertTrue("manager has been copied", emp.getManager() == empCopy.getManager()); - } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS - assertFalse("manager has not been copied", emp.getManager() == empCopy.getManager()); - } - } - // phoneNumbers is privately owned - for(PhoneNumber phone : emp.getPhoneNumbers()) { - originalPhones.add(phone); - same = false; - for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) { - copyPhones.add(phoneCopy); - if(!same && phone == phoneCopy) { - same = true; + // phoneNumbers is privately owned + for(PhoneNumber phone : emp.getPhoneNumbers()) { + originalPhones.add(phone); + same = false; + for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) { + copyPhones.add(phoneCopy); + if(!same && phone == phoneCopy) { + same = true; + } } + if(cascadeDepth == CopyGroup.NO_CASCADE) { + assertTrue("phone has been copied", same); + } else { + // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS + assertFalse("phone has not been copied", same); + } } - if(cascadeDepth == CopyGroup.NO_CASCADE) { - assertTrue("phone has been copied", same); - } else { - // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS - assertFalse("phone has not been copied", same); - } } + + assertTrue("copyEmployees.size() == " + copyEmployees.size() + "; was expected " + originalEmployees.size(), originalEmployees.size() == copyEmployees.size()); + assertTrue("copyAddresses.size() == " + copyAddresses.size() + "; was expected " + originalAddresses.size(), originalAddresses.size() == copyAddresses.size()); + assertTrue("copyProjects.size() == " + copyProjects.size() + "; was expected " + originalProjects.size(), originalProjects.size() == copyProjects.size()); + assertTrue("copyPhones.size() == " + copyPhones.size() + "; was expected " + originalPhones.size(), originalPhones.size() == copyPhones.size()); + } finally { + if(isTransactionActive(em)) { + rollbackTransaction(em); + } } - - assertTrue("copyEmployees.size() == " + copyEmployees.size() + "; was expected " + originalEmployees.size(), originalEmployees.size() == copyEmployees.size()); - assertTrue("copyAddresses.size() == " + copyAddresses.size() + "; was expected " + originalAddresses.size(), originalAddresses.size() == copyAddresses.size()); - assertTrue("copyProjects.size() == " + copyProjects.size() + "; was expected " + originalProjects.size(), originalProjects.size() == copyProjects.size()); - assertTrue("copyPhones.size() == " + copyPhones.size() + "; was expected " + originalPhones.size(), originalPhones.size() == copyPhones.size()); } private T serialize(Serializable entity) throws IOException, ClassNotFoundException { byte[] bytes = SerializationHelper.serialize(entity); - return (T) SerializationHelper.deserialize(bytes); + ObjectInputStream inStream = new ObjectInputStream(new ByteArrayInputStream(bytes)); + return (T) inStream.readObject(); } + + private Object clone(Serializable object) throws IOException, ClassNotFoundException { + byte[] bytes = SerializationHelper.serialize(object); + ObjectInputStream inStream = new ObjectInputStream(new ByteArrayInputStream(bytes)); + return inStream.readObject(); + } }