Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 174413 Details for
Bug 319134
FetchGroups testsuite should run on application servers
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
patch for bug fix
319134-2.patch (text/plain), 523.81 KB, created by
Kevin Yuan
on 2010-07-15 11:48:16 EDT
(
hide
)
Description:
patch for bug fix
Filename:
MIME Type:
Creator:
Kevin Yuan
Created:
2010-07-15 11:48:16 EDT
Size:
523.81 KB
patch
obsolete
>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 @@ > <fileset dir="${eclipselink.jpa.test}/resource/${eclipselink.annotation.model}" includes="*.xml"/> > </copy> > <copy todir="${eclipselink.jpa.test}/${build.dir}/${eclipselink.annotation.model}"> >- <!-- 248780: exclude copies of classes from this eclipselink-annotation-model.jar if weaving is disabled in any other jar --> >+ <!-- 248780: exclude copies of classes from this eclipselink-annotation-model.jar if weaving is disabled in any other jar --> > <fileset dir="${eclipselink.jpa.test}/${classes.dir}" > includes="org/eclipse/persistence/testing/models/" > excludes="org/eclipse/persistence/testing/models/jpa/xml/** >@@ -511,7 +511,7 @@ > org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced/** > org/eclipse/persistence/testing/models/jpa/jpaadvancedproperties/** > org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced/** >- org/eclipse/persistence/testing/models/jpa/metamodel/** >+ org/eclipse/persistence/testing/models/jpa/metamodel/** > org/eclipse/persistence/testing/models/jpa/beanvalidation/** > org/eclipse/persistence/testing/models/weaving/**"/> > </copy> >@@ -757,10 +757,10 @@ > <fileset file="${eclipselink.jpa.test}/${eclipselink.delimited.model}.jar"/> > <fileset file="${eclipselink.jpa.test}/${eclipselink.beanvalidation.model}.jar"/> > </delete> >- >+ > </target> >+ > >- > <!-- Testing --> > > <!-- Classpath used for running tests. --> >@@ -1498,18 +1498,18 @@ > </replace> > </target> > >- <target name="recover-server-sessionbeans" depends="server-original-sessionbean-existence" if="original.sessionbean.exists"> >- <move file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_original" tofile="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java" overwrite="true"/> >+ <target name="recover-server-sessionbeans" depends="server-original-sessionbean-existence" if="original.sessionbean.exists"> >+ <move file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_original" tofile="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java" overwrite="true"/> > <antcall target="remove-multiple-persistence-units-sessionbeans" inheritRefs="true"/> > </target> >- >+ > <target name="server-original-sessionbean-existence"> > <available file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_original" property="original.sessionbean.exists" value="true" /> > </target> > > <target name="remove-multiple-persistence-units-sessionbeans" if="USE_MULTIPLE_PERSISTENCE_UNITS"> > <delete> >- <fileset dir="${eclipselink.jpa.test}/${src.dir}/org/eclipse/persistence/testing/framework/server" >+ <fileset dir="${eclipselink.jpa.test}/${src.dir}/org/eclipse/persistence/testing/framework/server" > includes="TestRunner1*.java > TestRunner2*.java > TestRunner3*.java >@@ -1738,23 +1738,23 @@ > </fileset> > </copy> > </target> >- >- <target name="prepare-non-jta-ds-servertest" depends="cleanup-non-jta-ds-servertest" if="is.nonjta.datasource"> >- <move file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java" tofile="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_jtaDS"/> >+ >+ <target name="prepare-non-jta-ds-servertest" depends="cleanup-non-jta-ds-servertest" if="is.nonjta.datasource"> >+ <move file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java" tofile="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_jtaDS"/> > <move file="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_nonjtaDS" tofile="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java"/> > </target> >- >+ > <target name="jta-ds-servertest-existence"> > <available file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_jtaDS" property="jta-ds-servertest.exists" value="true" /> > </target> >- >- <target name="cleanup-non-jta-ds-servertest" depends="jta-ds-servertest-existence" if="jta-ds-servertest.exists"> >- <move file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java" tofile="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_nonjtaDS"/> >+ >+ <target name="cleanup-non-jta-ds-servertest" depends="jta-ds-servertest-existence" if="jta-ds-servertest.exists"> >+ <move file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java" tofile="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_nonjtaDS"/> > <move file="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_jtaDS" tofile="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java"/> > </target> >- >+ > <target name="replace-datasource-type" depends="replace-jta-datasource,replace-nonjta-datasource"/> >- >+ > <target name="replace-jta-datasource" unless="is.nonjta.datasource"> > <replace dir="${eclipselink.jpa.test}/stage/META-INF" token='%%data-source-name%%' value="${DS_NAME}"> > <include name="*.xml"/> >@@ -1766,7 +1766,7 @@ > <include name="*.xml"/> > </replace> > </target> >- >+ > <target name="replace-nonjta-datasource" if="is.nonjta.datasource"> > <replace dir="${eclipselink.jpa.test}/stage/META-INF" token='%%data-source-name%%' value="${NONJTA_DS_NAME}"> > <include name="*.xml"/> >@@ -1778,7 +1778,7 @@ > <include name="*.xml"/> > </replace> > </target> >- >+ > <target name="create-ejb-jar" depends="create-ejb-jar-without-static-weaving,create-ejb-jar-with-static-weaving"/> > > <target name="create-ejb-jar-without-static-weaving" unless="is.static.server.weaving"> >@@ -1858,8 +1858,6 @@ > <path id="run.path"> > <pathelement path="${eclipselink.jpa.test}/${build.dir}/${TEST_NAME}_client.jar"/> > <pathelement path="${eclipselink.jpa.test}/${build.dir}/${MODEL_NAME}_ejb.jar"/> >- <!--this path is used for WebSphere only for now--> >- <pathelement path="${server.persistence20.lib}/${server.persistence20.jar}"/> > <fileset dir="${server.lib}" includes="${server.depend}"/> > <path refid="compile.server.path"/> > </path> >@@ -1951,7 +1949,9 @@ > <antcall target="server-test-ddlgeneration" inheritRefs="true"/> > <antcall target="server-test-cascadedeletes" inheritRefs="true"/> > <antcall target="server-test-delimited" inheritRefs="true"/> >+ <antcall target="server-test-fetchgroups" inheritRefs="true"/> > <antcall target="server-test-fieldaccess-advanced" inheritRefs="true"/> >+ <antcall target="server-test-fieldaccess-fetchgroups" inheritRefs="true"/> > <antcall target="server-test-fieldaccess-relationships" inheritRefs="true"/> > <antcall target="server-test-inheritance" inheritRefs="true"/> > <antcall target="server-test-inherited" inheritRefs="true"/> >@@ -2088,6 +2088,19 @@ > </antcall> > </target> > >+ <target name="server-test-fetchgroups"> >+ <antcall target="server-run-all" inheritRefs="true"> >+ <param name="PERSISTENCE_UNIT_NAME" value="default"/> >+ <param name="MODEL_DIR" value="org/eclipse/persistence/testing/models/jpa/advanced"/> >+ <param name="MODEL_NAME" value="eclipselink-fetchgroups-model"/> >+ <param name="TEST_DIR" value="org/eclipse/persistence/testing/tests/jpa/fetchgroups"/> >+ <param name="TEST_NAME" value="eclipselink-fetchgroups-model"/> >+ <param name="EAR_NAME" value="eclipselink-fetchgroups-model"/> >+ <param name="TEST_SUITE" value="org.eclipse.persistence.testing.tests.jpa.fetchgroups.FetchGroupsServerTestSuite"/> >+ <param name="eclipselink.jpa.test.dir" value="."/> >+ </antcall> >+ </target> >+ > <target name="server-test-fieldaccess-advanced"> > <antcall target="server-run-all" inheritRefs="true"> > <param name="PERSISTENCE_UNIT_NAME" value="fieldaccess"/> >@@ -2101,6 +2114,19 @@ > </antcall> > </target> > >+ <target name="server-test-fieldaccess-fetchgroups"> >+ <antcall target="server-run-all" inheritRefs="true"> >+ <param name="PERSISTENCE_UNIT_NAME" value="fieldaccess"/> >+ <param name="MODEL_DIR" value="org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced"/> >+ <param name="MODEL_NAME" value="eclipselink-advanced-field-access-model"/> >+ <param name="TEST_DIR" value="org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups"/> >+ <param name="TEST_NAME" value="eclipselink-fetchgroups-field-access-model"/> >+ <param name="EAR_NAME" value="eclipselink-fetchgroups-field-access-model"/> >+ <param name="TEST_SUITE" value="org.eclipse.persistence.testing.tests.jpa.fieldaccess.fetchgroups.FAServerTestSuite"/> >+ <param name="eclipselink.jpa.test.dir" value="."/> >+ </antcall> >+ </target> >+ > <target name="server-test-fieldaccess-relationships"> > <antcall target="server-run-all" inheritRefs="true"> > <param name="PERSISTENCE_UNIT_NAME" value="default"/> >@@ -2313,9 +2339,9 @@ > <target name="server-test-dll-existence"> > <available file="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_ddl" property="server_ddl.exists" value="true" /> > </target> >- >- <target name="cleanup-merge-inherited-ddl" depends="server-test-dll-existence" if="server_ddl.exists"> >- <move file="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server" tofile="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_merge-inherited"/> >+ >+ <target name="cleanup-merge-inherited-ddl" depends="server-test-dll-existence" if="server_ddl.exists"> >+ <move file="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server" tofile="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_merge-inherited"/> > <move file="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_ddl" tofile="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server"/> > <delete> > <fileset dir="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_merge-inherited/"> >@@ -2323,7 +2349,7 @@ > </fileset> > </delete> > </target> >- >+ > <target name="server-test-xmltest"> > <copy todir="${eclipselink.jpa.test}/resource/eclipselink-xml-servertest-model/server/" overwrite="true" failonerror="false"> > <fileset dir="${eclipselink.jpa.test}/resource/eclipselink-xml-merge-model/"> >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 @@ > <property name="eclipselink.target-database" value="%%database-platform%%"/> > <property name="eclipselink.validate-existence" value="true"/> > <!--property name="eclipselink.logging.level" value="FINEST"/--> >+ <property name="eclipselink.logging.logger" value="DefaultLogger"/> > </properties> > </persistence-unit> > </persistence> >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 @@ > <property name="eclipselink.target-database" value="%%database-platform%%"/> > <property name="eclipselink.validate-existence" value="true"/> > <!--property name="eclipselink.logging.level" value="FINEST"/--> >+ <property name="eclipselink.logging.logger" value="DefaultLogger"/> > <property name="eclipselink.weaving" value="%%server-weaving%%"/> > </properties> > </persistence-unit> >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<String, AttributeItem> 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; >+ >+/** >+ * <p><b>Purpose</b>: 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> 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<Employee, Set<Employee>> managedEmployeesByManager = new IdentityHashMap(); >- for (Employee emp : emps) { >- Employee manager = emp.getManager(); >- Set<Employee> 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<Employee> 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<Employee> 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<Employee, Set<Employee>> managedEmployeesByManager = new IdentityHashMap(); >+ for (Employee emp : emps) { >+ Employee manager = emp.getManager(); >+ Set<Employee> managedEmployees = managedEmployeesByManager.get(manager); >+ if(managedEmployees == null) { >+ managedEmployees = new IdentityHashSet(); >+ managedEmployeesByManager.put(manager, managedEmployees); >+ } >+ managedEmployees.add(emp); >+ } > >- Set<Employee> 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<Employee> 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<Employee> 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<Employee> employees = query.getResultList(); >+ List<Employee> 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<Employee> employees = query.getResultList(); >- assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); >- >- for(Employee emp :employees) { >- assertFetched(emp, employeeFG); >+ List<Employee> 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<Employee> employees = query.getResultList(); >+ List<Employee> 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<Employee> 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<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); > >- List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >- assertNotNull(emps); >+ List<Employee> 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<String, Object> properties = new HashMap<String, Object>(); >- FetchGroup emptyFG = new FetchGroup(); >- properties.put(QueryHints.FETCH_GROUP, emptyFG); >+ assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); > >- Employee emp = em.find(Employee.class, minId, properties); >+ Map<String, Object> properties = new HashMap<String, Object>(); >+ 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<String, Object> properties = new HashMap<String, Object>(); >- FetchGroup emptyFG = new FetchGroup(); >- properties.put(QueryHints.FETCH_GROUP, emptyFG); >+ assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); > >- Employee emp = em.find(Employee.class, minId, properties); >+ Map<String, Object> properties = new HashMap<String, Object>(); >+ 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> 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<Employee> 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<String, Object> hints = new HashMap<String, Object>(); >+ hints.put(QueryHints.FETCH_GROUP, fg); > >- Map<String, Object> hints = new HashMap<String, Object>(); >- 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<String, Object> properties = new HashMap<String, Object>(); >- FetchGroup emptyFG = new FetchGroup(); >- properties.put(QueryHints.FETCH_GROUP, emptyFG); >+ Map<String, Object> properties = new HashMap<String, Object>(); >+ 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> query = em.createQuery("SELECT e FROM Employee e", Employee.class); >- query.setHint(QueryHints.BATCH, "e.address"); >- List<Employee> 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<Employee> employeesCopy = (List<Employee>) 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<Employee> query = em.createQuery("SELECT e FROM Employee e", Employee.class); >+ query.setHint(QueryHints.BATCH, "e.address"); >+ List<Employee> 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<Employee> employeesCopy = (List<Employee>) 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<Employee> employees = query.getResultList(); >+ try { >+ beginTransaction(em); >+ Query query = em.createQuery("SELECT e FROM Employee e"); >+ List<Employee> 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<Employee> 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<Employee> 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> 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; >+ >+/** >+ * <p><b>Purpose</b>: 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> 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<Employee, Set<Employee>> managedEmployeesByManager = new IdentityHashMap(); >- for (Employee emp : emps) { >- Employee manager = emp.getManager(); >- Set<Employee> 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<Employee> 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<Employee> 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<Employee, Set<Employee>> managedEmployeesByManager = new IdentityHashMap(); >+ for (Employee emp : emps) { >+ Employee manager = emp.getManager(); >+ Set<Employee> managedEmployees = managedEmployeesByManager.get(manager); >+ if(managedEmployees == null) { >+ managedEmployees = new IdentityHashSet(); >+ managedEmployeesByManager.put(manager, managedEmployees); >+ } >+ managedEmployees.add(emp); >+ } > >- Set<Employee> 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<Employee> 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<Employee> 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<Employee> employees = query.getResultList(); >+ List<Employee> 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<Employee> employees = query.getResultList(); >- assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); >- >- for(Employee emp :employees) { >- assertFetched(emp, employeeFG); >+ List<Employee> 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<Employee> employees = query.getResultList(); >+ List<Employee> 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<Employee> 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<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); > >- List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >- assertNotNull(emps); >+ List<Employee> 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<String, Object> properties = new HashMap<String, Object>(); >- FetchGroup emptyFG = new FetchGroup(); >- properties.put(QueryHints.FETCH_GROUP, emptyFG); >+ assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); > >- Employee emp = em.find(Employee.class, minId, properties); >+ Map<String, Object> properties = new HashMap<String, Object>(); >+ 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<String, Object> properties = new HashMap<String, Object>(); >- FetchGroup emptyFG = new FetchGroup(); >- properties.put(QueryHints.FETCH_GROUP, emptyFG); >+ assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls()); > >- Employee emp = em.find(Employee.class, minId, properties); >+ Map<String, Object> properties = new HashMap<String, Object>(); >+ 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> 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<Employee> 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<String, Object> hints = new HashMap<String, Object>(); >+ hints.put(QueryHints.FETCH_GROUP, fg); > >- Map<String, Object> hints = new HashMap<String, Object>(); >- 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<String, Object> properties = new HashMap<String, Object>(); >- FetchGroup emptyFG = new FetchGroup(); >- properties.put(QueryHints.FETCH_GROUP, emptyFG); >+ Map<String, Object> properties = new HashMap<String, Object>(); >+ 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> emps = query.getResultList(); >+ List<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> 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<Employee> query = em.createQuery("SELECT e FROM Employee e", Employee.class); >- query.setHint(QueryHints.BATCH, "e.address"); >- List<Employee> 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<Employee> employeesCopy = (List<Employee>) 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<Employee> query = em.createQuery("SELECT e FROM Employee e", Employee.class); >+ query.setHint(QueryHints.BATCH, "e.address"); >+ List<Employee> 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<Employee> employeesCopy = (List<Employee>) 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<Employee> employees = query.getResultList(); >+ try { >+ beginTransaction(em); >+ Query query = em.createQuery("SELECT e FROM Employee e"); >+ List<Employee> 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<Employee> 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<Employee> 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> 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(); >+ } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 319134
:
173657
| 174413 |
174502