View | Details | Raw Unified | Return to bug 319134 | Differences between
and this patch

Collapse All | Expand All

(-)jpa/eclipselink.jpa.test/build.xml (-25 / +51 lines)
Lines 501-507 Link Here
501
            <fileset dir="${eclipselink.jpa.test}/resource/${eclipselink.annotation.model}" includes="*.xml"/>
501
            <fileset dir="${eclipselink.jpa.test}/resource/${eclipselink.annotation.model}" includes="*.xml"/>
502
        </copy>
502
        </copy>
503
        <copy todir="${eclipselink.jpa.test}/${build.dir}/${eclipselink.annotation.model}">
503
        <copy todir="${eclipselink.jpa.test}/${build.dir}/${eclipselink.annotation.model}">
504
            <!-- 248780: exclude copies of classes from this eclipselink-annotation-model.jar if weaving is disabled in any other jar -->
504
            <!-- 248780: exclude copies of classes from this eclipselink-annotation-model.jar if weaving is disabled in any other jar -->        	
505
            <fileset dir="${eclipselink.jpa.test}/${classes.dir}"
505
            <fileset dir="${eclipselink.jpa.test}/${classes.dir}"
506
                     includes="org/eclipse/persistence/testing/models/"
506
                     includes="org/eclipse/persistence/testing/models/"
507
                     excludes="org/eclipse/persistence/testing/models/jpa/xml/**
507
                     excludes="org/eclipse/persistence/testing/models/jpa/xml/**
Lines 511-517 Link Here
511
                               org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced/**
511
                               org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced/**
512
                               org/eclipse/persistence/testing/models/jpa/jpaadvancedproperties/**
512
                               org/eclipse/persistence/testing/models/jpa/jpaadvancedproperties/**
513
                               org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced/**
513
                               org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced/**
514
                               org/eclipse/persistence/testing/models/jpa/metamodel/**
514
                               org/eclipse/persistence/testing/models/jpa/metamodel/**            	
515
                               org/eclipse/persistence/testing/models/jpa/beanvalidation/**
515
                               org/eclipse/persistence/testing/models/jpa/beanvalidation/**
516
                               org/eclipse/persistence/testing/models/weaving/**"/>
516
                               org/eclipse/persistence/testing/models/weaving/**"/>
517
        </copy>
517
        </copy>
Lines 757-766 Link Here
757
            <fileset file="${eclipselink.jpa.test}/${eclipselink.delimited.model}.jar"/>
757
            <fileset file="${eclipselink.jpa.test}/${eclipselink.delimited.model}.jar"/>
758
            <fileset file="${eclipselink.jpa.test}/${eclipselink.beanvalidation.model}.jar"/>
758
            <fileset file="${eclipselink.jpa.test}/${eclipselink.beanvalidation.model}.jar"/>
759
        </delete>
759
        </delete>
760
760
        
761
    </target>
761
    </target>
762
    
762
763
763
764
    <!-- Testing -->
764
    <!-- Testing -->
765
765
766
    <!-- Classpath used for running tests. -->
766
    <!-- Classpath used for running tests. -->
Lines 1498-1515 Link Here
1498
        </replace>
1498
        </replace>
1499
    </target>
1499
    </target>
1500
1500
1501
    <target name="recover-server-sessionbeans" depends="server-original-sessionbean-existence" if="original.sessionbean.exists">
1501
    <target name="recover-server-sessionbeans" depends="server-original-sessionbean-existence" if="original.sessionbean.exists"> 
1502
        <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"/>
1502
        <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"/>     
1503
        <antcall target="remove-multiple-persistence-units-sessionbeans" inheritRefs="true"/>
1503
        <antcall target="remove-multiple-persistence-units-sessionbeans" inheritRefs="true"/>
1504
    </target>
1504
    </target>
1505
1505
    
1506
    <target name="server-original-sessionbean-existence">
1506
    <target name="server-original-sessionbean-existence">
1507
        <available file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_original" property="original.sessionbean.exists" value="true" />
1507
        <available file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_original" property="original.sessionbean.exists" value="true" />
1508
    </target>
1508
    </target>
1509
1509
1510
    <target name="remove-multiple-persistence-units-sessionbeans" if="USE_MULTIPLE_PERSISTENCE_UNITS">
1510
    <target name="remove-multiple-persistence-units-sessionbeans" if="USE_MULTIPLE_PERSISTENCE_UNITS">
1511
        <delete>
1511
        <delete>
1512
            <fileset dir="${eclipselink.jpa.test}/${src.dir}/org/eclipse/persistence/testing/framework/server"
1512
            <fileset dir="${eclipselink.jpa.test}/${src.dir}/org/eclipse/persistence/testing/framework/server" 
1513
            includes="TestRunner1*.java
1513
            includes="TestRunner1*.java
1514
                      TestRunner2*.java
1514
                      TestRunner2*.java
1515
                      TestRunner3*.java
1515
                      TestRunner3*.java
Lines 1738-1760 Link Here
1738
            </fileset>
1738
            </fileset>
1739
        </copy>
1739
        </copy>
1740
    </target>
1740
    </target>
1741
1741
    
1742
    <target name="prepare-non-jta-ds-servertest" depends="cleanup-non-jta-ds-servertest" if="is.nonjta.datasource">
1742
    <target name="prepare-non-jta-ds-servertest" depends="cleanup-non-jta-ds-servertest" if="is.nonjta.datasource"> 
1743
        <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"/>
1743
        <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"/>        
1744
        <move file="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_nonjtaDS" tofile="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java"/>
1744
        <move file="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_nonjtaDS" tofile="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java"/>
1745
    </target>
1745
    </target>
1746
1746
    
1747
    <target name="jta-ds-servertest-existence">
1747
    <target name="jta-ds-servertest-existence">
1748
        <available file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_jtaDS" property="jta-ds-servertest.exists" value="true" />
1748
        <available file="${eclipselink.jpa.test}/src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_jtaDS" property="jta-ds-servertest.exists" value="true" />
1749
    </target>
1749
    </target>
1750
1750
    
1751
    <target name="cleanup-non-jta-ds-servertest" depends="jta-ds-servertest-existence" if="jta-ds-servertest.exists">
1751
    <target name="cleanup-non-jta-ds-servertest" depends="jta-ds-servertest-existence" if="jta-ds-servertest.exists"> 
1752
        <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"/>
1752
        <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"/>        
1753
        <move file="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_jtaDS" tofile="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java"/>
1753
        <move file="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java_jtaDS" tofile="src/org/eclipse/persistence/testing/framework/server/TestRunnerBean.java"/>
1754
    </target>
1754
    </target>
1755
1755
    
1756
    <target name="replace-datasource-type" depends="replace-jta-datasource,replace-nonjta-datasource"/>
1756
    <target name="replace-datasource-type" depends="replace-jta-datasource,replace-nonjta-datasource"/>
1757
1757
    
1758
    <target name="replace-jta-datasource" unless="is.nonjta.datasource">
1758
    <target name="replace-jta-datasource" unless="is.nonjta.datasource">
1759
        <replace dir="${eclipselink.jpa.test}/stage/META-INF" token='%%data-source-name%%' value="${DS_NAME}">
1759
        <replace dir="${eclipselink.jpa.test}/stage/META-INF" token='%%data-source-name%%' value="${DS_NAME}">
1760
            <include name="*.xml"/>
1760
            <include name="*.xml"/>
Lines 1766-1772 Link Here
1766
            <include name="*.xml"/>
1766
            <include name="*.xml"/>
1767
        </replace>
1767
        </replace>
1768
    </target>
1768
    </target>
1769
1769
    
1770
    <target name="replace-nonjta-datasource" if="is.nonjta.datasource">
1770
    <target name="replace-nonjta-datasource" if="is.nonjta.datasource">
1771
        <replace dir="${eclipselink.jpa.test}/stage/META-INF" token='%%data-source-name%%' value="${NONJTA_DS_NAME}">
1771
        <replace dir="${eclipselink.jpa.test}/stage/META-INF" token='%%data-source-name%%' value="${NONJTA_DS_NAME}">
1772
            <include name="*.xml"/>
1772
            <include name="*.xml"/>
Lines 1778-1784 Link Here
1778
            <include name="*.xml"/>
1778
            <include name="*.xml"/>
1779
        </replace>
1779
        </replace>
1780
    </target>
1780
    </target>
1781
1781
    
1782
    <target name="create-ejb-jar" depends="create-ejb-jar-without-static-weaving,create-ejb-jar-with-static-weaving"/>
1782
    <target name="create-ejb-jar" depends="create-ejb-jar-without-static-weaving,create-ejb-jar-with-static-weaving"/>
1783
1783
1784
    <target name="create-ejb-jar-without-static-weaving" unless="is.static.server.weaving">
1784
    <target name="create-ejb-jar-without-static-weaving" unless="is.static.server.weaving">
Lines 1858-1865 Link Here
1858
        <path id="run.path">
1858
        <path id="run.path">
1859
            <pathelement path="${eclipselink.jpa.test}/${build.dir}/${TEST_NAME}_client.jar"/>
1859
            <pathelement path="${eclipselink.jpa.test}/${build.dir}/${TEST_NAME}_client.jar"/>
1860
            <pathelement path="${eclipselink.jpa.test}/${build.dir}/${MODEL_NAME}_ejb.jar"/>
1860
            <pathelement path="${eclipselink.jpa.test}/${build.dir}/${MODEL_NAME}_ejb.jar"/>
1861
            <!--this path is used for WebSphere only for now-->
1862
            <pathelement path="${server.persistence20.lib}/${server.persistence20.jar}"/>
1863
            <fileset dir="${server.lib}" includes="${server.depend}"/>
1861
            <fileset dir="${server.lib}" includes="${server.depend}"/>
1864
            <path refid="compile.server.path"/>
1862
            <path refid="compile.server.path"/>
1865
        </path>
1863
        </path>
Lines 1951-1957 Link Here
1951
        <antcall target="server-test-ddlgeneration" inheritRefs="true"/>
1949
        <antcall target="server-test-ddlgeneration" inheritRefs="true"/>
1952
        <antcall target="server-test-cascadedeletes" inheritRefs="true"/>
1950
        <antcall target="server-test-cascadedeletes" inheritRefs="true"/>
1953
        <antcall target="server-test-delimited" inheritRefs="true"/>
1951
        <antcall target="server-test-delimited" inheritRefs="true"/>
1952
        <antcall target="server-test-fetchgroups" inheritRefs="true"/>
1954
        <antcall target="server-test-fieldaccess-advanced" inheritRefs="true"/>
1953
        <antcall target="server-test-fieldaccess-advanced" inheritRefs="true"/>
1954
        <antcall target="server-test-fieldaccess-fetchgroups" inheritRefs="true"/>
1955
        <antcall target="server-test-fieldaccess-relationships" inheritRefs="true"/>
1955
        <antcall target="server-test-fieldaccess-relationships" inheritRefs="true"/>
1956
        <antcall target="server-test-inheritance" inheritRefs="true"/>
1956
        <antcall target="server-test-inheritance" inheritRefs="true"/>
1957
        <antcall target="server-test-inherited" inheritRefs="true"/>
1957
        <antcall target="server-test-inherited" inheritRefs="true"/>
Lines 2088-2093 Link Here
2088
        </antcall>
2088
        </antcall>
2089
    </target>
2089
    </target>
2090
2090
2091
    <target name="server-test-fetchgroups">
2092
        <antcall target="server-run-all" inheritRefs="true">
2093
            <param name="PERSISTENCE_UNIT_NAME" value="default"/>
2094
            <param name="MODEL_DIR" value="org/eclipse/persistence/testing/models/jpa/advanced"/>
2095
            <param name="MODEL_NAME" value="eclipselink-fetchgroups-model"/>
2096
            <param name="TEST_DIR" value="org/eclipse/persistence/testing/tests/jpa/fetchgroups"/>
2097
            <param name="TEST_NAME" value="eclipselink-fetchgroups-model"/>
2098
            <param name="EAR_NAME" value="eclipselink-fetchgroups-model"/>
2099
            <param name="TEST_SUITE" value="org.eclipse.persistence.testing.tests.jpa.fetchgroups.FetchGroupsServerTestSuite"/>
2100
            <param name="eclipselink.jpa.test.dir" value="."/>
2101
        </antcall>
2102
    </target>
2103
2091
    <target name="server-test-fieldaccess-advanced">
2104
    <target name="server-test-fieldaccess-advanced">
2092
        <antcall target="server-run-all" inheritRefs="true">
2105
        <antcall target="server-run-all" inheritRefs="true">
2093
            <param name="PERSISTENCE_UNIT_NAME" value="fieldaccess"/>
2106
            <param name="PERSISTENCE_UNIT_NAME" value="fieldaccess"/>
Lines 2101-2106 Link Here
2101
        </antcall>
2114
        </antcall>
2102
    </target>
2115
    </target>
2103
2116
2117
    <target name="server-test-fieldaccess-fetchgroups">
2118
        <antcall target="server-run-all" inheritRefs="true">
2119
            <param name="PERSISTENCE_UNIT_NAME" value="fieldaccess"/>
2120
            <param name="MODEL_DIR" value="org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced"/>
2121
            <param name="MODEL_NAME" value="eclipselink-advanced-field-access-model"/>
2122
            <param name="TEST_DIR" value="org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups"/>
2123
            <param name="TEST_NAME" value="eclipselink-fetchgroups-field-access-model"/>
2124
            <param name="EAR_NAME" value="eclipselink-fetchgroups-field-access-model"/>
2125
            <param name="TEST_SUITE" value="org.eclipse.persistence.testing.tests.jpa.fieldaccess.fetchgroups.FAServerTestSuite"/>
2126
            <param name="eclipselink.jpa.test.dir" value="."/>
2127
        </antcall>
2128
    </target>
2129
2104
    <target name="server-test-fieldaccess-relationships">
2130
    <target name="server-test-fieldaccess-relationships">
2105
        <antcall target="server-run-all" inheritRefs="true">
2131
        <antcall target="server-run-all" inheritRefs="true">
2106
            <param name="PERSISTENCE_UNIT_NAME" value="default"/>
2132
            <param name="PERSISTENCE_UNIT_NAME" value="default"/>
Lines 2313-2321 Link Here
2313
    <target name="server-test-dll-existence">
2339
    <target name="server-test-dll-existence">
2314
        <available file="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_ddl" property="server_ddl.exists" value="true" />
2340
        <available file="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_ddl" property="server_ddl.exists" value="true" />
2315
    </target>
2341
    </target>
2316
2342
    
2317
    <target name="cleanup-merge-inherited-ddl" depends="server-test-dll-existence" if="server_ddl.exists">
2343
    <target name="cleanup-merge-inherited-ddl" depends="server-test-dll-existence" if="server_ddl.exists"> 
2318
        <move file="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server" tofile="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_merge-inherited"/>
2344
        <move file="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server" tofile="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_merge-inherited"/>        
2319
        <move file="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_ddl" tofile="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server"/>
2345
        <move file="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_ddl" tofile="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server"/>
2320
        <delete>
2346
        <delete>
2321
            <fileset dir="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_merge-inherited/">
2347
            <fileset dir="${eclipselink.jpa.test}/resource/eclipselink-ddl-generation-model/server_merge-inherited/">
Lines 2323-2329 Link Here
2323
            </fileset>
2349
            </fileset>
2324
        </delete>
2350
        </delete>
2325
    </target>
2351
    </target>
2326
2352
        
2327
    <target name="server-test-xmltest">
2353
    <target name="server-test-xmltest">
2328
        <copy todir="${eclipselink.jpa.test}/resource/eclipselink-xml-servertest-model/server/" overwrite="true" failonerror="false">
2354
        <copy todir="${eclipselink.jpa.test}/resource/eclipselink-xml-servertest-model/server/" overwrite="true" failonerror="false">
2329
            <fileset dir="${eclipselink.jpa.test}/resource/eclipselink-xml-merge-model/">
2355
            <fileset dir="${eclipselink.jpa.test}/resource/eclipselink-xml-merge-model/">
(-)jpa/eclipselink.jpa.test/resource/eclipselink-advanced-field-access-model/server/persistence.xml (-1 / +2 lines)
Lines 7-17 Link Here
7
            <!--This property is added to test 'querytimeout' property and test is
7
            <!--This property is added to test 'querytimeout' property and test is
8
                implemented in 'EntityManagerJUnitTestSuite.testQueryTimeOut()'-->
8
                implemented in 'EntityManagerJUnitTestSuite.testQueryTimeOut()'-->
9
            <property name="javax.persistence.query.timeout" value="100"/>
9
            <property name="javax.persistence.query.timeout" value="100"/>
10
            <property name="eclipselink.weaving" value="%%server-weaving%%"/>
11
            <property name="eclipselink.target-server" value="%%server-platform%%"/>
10
            <property name="eclipselink.target-server" value="%%server-platform%%"/>
12
            <property name="eclipselink.target-database" value="%%database-platform%%"/>
11
            <property name="eclipselink.target-database" value="%%database-platform%%"/>
12
            <property name="eclipselink.weaving" value="%%server-weaving%%"/>
13
            <property name="eclipselink.validate-existence" value="true"/>
13
            <property name="eclipselink.validate-existence" value="true"/>
14
            <!--property name="eclipselink.logging.level" value="FINEST"/-->
14
            <!--property name="eclipselink.logging.level" value="FINEST"/-->
15
            <property name="eclipselink.logging.logger" value="DefaultLogger"/>
15
        </properties>
16
        </properties>
16
    </persistence-unit>
17
    </persistence-unit>
17
</persistence>
18
</persistence>
(-)jpa/eclipselink.jpa.test/resource/server/persistence.xml (-1 / +2 lines)
Lines 6-14 Link Here
6
        <properties>
6
        <properties>
7
            <property name="eclipselink.target-server" value="%%server-platform%%"/>
7
            <property name="eclipselink.target-server" value="%%server-platform%%"/>
8
            <property name="eclipselink.target-database" value="%%database-platform%%"/>
8
            <property name="eclipselink.target-database" value="%%database-platform%%"/>
9
            <property name="eclipselink.weaving" value="%%server-weaving%%"/>
9
            <property name="eclipselink.validate-existence" value="true"/>
10
            <property name="eclipselink.validate-existence" value="true"/>
10
            <!--property name="eclipselink.logging.level" value="FINEST"/-->
11
            <!--property name="eclipselink.logging.level" value="FINEST"/-->
11
            <property name="eclipselink.weaving" value="%%server-weaving%%"/>
12
            <property name="eclipselink.logging.logger" value="DefaultLogger"/>
12
        </properties>
13
        </properties>
13
    </persistence-unit>
14
    </persistence-unit>
14
</persistence>
15
</persistence>
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/AdvancedServerTestSuite.java (+4 lines)
Lines 13-18 Link Here
13
package org.eclipse.persistence.testing.tests.jpa.advanced;
13
package org.eclipse.persistence.testing.tests.jpa.advanced;
14
14
15
import org.eclipse.persistence.testing.tests.jpa.advanced.compositepk.AdvancedCompositePKJunitTest;
15
import org.eclipse.persistence.testing.tests.jpa.advanced.compositepk.AdvancedCompositePKJunitTest;
16
import org.eclipse.persistence.testing.tests.jpa.advanced.fetchgroup.AdvancedFetchGroupJunitTest;
16
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
17
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
17
18
18
import junit.framework.TestSuite;
19
import junit.framework.TestSuite;
Lines 40-45 Link Here
40
        suite.addTest(AdvancedJunitTest.suite());
41
        suite.addTest(AdvancedJunitTest.suite());
41
        suite.addTest(AdvancedCompositePKJunitTest.suite());
42
        suite.addTest(AdvancedCompositePKJunitTest.suite());
42
        suite.addTest(QueryCastTestSuite.suite());
43
        suite.addTest(QueryCastTestSuite.suite());
44
        if (! JUnitTestCase.isJPA10()) {
45
            suite.addTest(AdvancedFetchGroupJunitTest.suite());
46
        }
43
        return suite;
47
        return suite;
44
    }
48
    }
45
}
49
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/BaseFetchGroupTests.java (-3 / +6 lines)
Lines 73-80 Link Here
73
     * Fetch Group tests require weaving.
73
     * Fetch Group tests require weaving.
74
     */
74
     */
75
    public void runBare() throws Throwable {
75
    public void runBare() throws Throwable {
76
        if (isWeavingEnabled()) {
76
        if (this.shouldRunTestOnServer()) {
77
            super.runBare();
77
            super.runBare();
78
        } else {
79
           if (isWeavingEnabled()) {
80
                super.runBare();
81
            }
78
        }
82
        }
79
    }
83
    }
80
84
Lines 447-454 Link Here
447
    }
451
    }
448
    
452
    
449
    protected QuerySQLTracker getQuerySQLTracker(EntityManager em) {
453
    protected QuerySQLTracker getQuerySQLTracker(EntityManager em) {
450
        return QuerySQLTracker.getTracker(JpaHelper.getEntityManager(em)
454
        return QuerySQLTracker.getTracker(getServerSession());
451
                .getActiveSession());
452
    }
455
    }
453
456
454
    ClassDescriptor getDescriptor(String entityName) {
457
    ClassDescriptor getDescriptor(String entityName) {
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupAssert.java (-7 / +7 lines)
Lines 53-59 Link Here
53
     */
53
     */
54
    public static boolean isValid(FetchGroup fetchGroup, EntityManagerFactory emf, Class<?> entityClass) {
54
    public static boolean isValid(FetchGroup fetchGroup, EntityManagerFactory emf, Class<?> entityClass) {
55
        assertNotNull(fetchGroup);
55
        assertNotNull(fetchGroup);
56
        Session session = JpaHelper.getServerSession(emf);
56
        Session session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession();
57
        ClassDescriptor descriptor = session.getDescriptor(entityClass);
57
        ClassDescriptor descriptor = session.getDescriptor(entityClass);
58
        try {
58
        try {
59
            for (Map.Entry<String, AttributeItem> entry : fetchGroup.getItems().entrySet()) {
59
            for (Map.Entry<String, AttributeItem> entry : fetchGroup.getItems().entrySet()) {
Lines 82-88 Link Here
82
    public static void assertFetchedAttribute(EntityManagerFactory emf, Object entity, String... attribute) {
82
    public static void assertFetchedAttribute(EntityManagerFactory emf, Object entity, String... attribute) {
83
        assertNotNull("EntityManagerFactory is null", emf);
83
        assertNotNull("EntityManagerFactory is null", emf);
84
        assertNotNull("Entity is null", entity);
84
        assertNotNull("Entity is null", entity);
85
        Server session = JpaHelper.getServerSession(emf);
85
        Server session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession();
86
        assertNotNull("No Server session found for: " + emf, session);
86
        assertNotNull("No Server session found for: " + emf, session);
87
        ClassDescriptor desc = session.getClassDescriptor(entity);
87
        ClassDescriptor desc = session.getClassDescriptor(entity);
88
        assertNotNull("No descriptor found for: " + entity, desc);
88
        assertNotNull("No descriptor found for: " + entity, desc);
Lines 128-134 Link Here
128
    public static void assertNotFetchedAttribute(EntityManagerFactory emf, Object entity, String... attribute) {
128
    public static void assertNotFetchedAttribute(EntityManagerFactory emf, Object entity, String... attribute) {
129
        assertNotNull("EntityManagerFactory is null", emf);
129
        assertNotNull("EntityManagerFactory is null", emf);
130
        assertNotNull("Entity is null", entity);
130
        assertNotNull("Entity is null", entity);
131
        Server session = JpaHelper.getServerSession(emf);
131
        Server session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession();
132
        assertNotNull("No Server session found for: " + emf, session);
132
        assertNotNull("No Server session found for: " + emf, session);
133
        ClassDescriptor desc = session.getClassDescriptor(entity);
133
        ClassDescriptor desc = session.getClassDescriptor(entity);
134
        assertNotNull("No descriptor found for: " + entity, desc);
134
        assertNotNull("No descriptor found for: " + entity, desc);
Lines 178-184 Link Here
178
        }
178
        }
179
        assertTrue("FetchGroup on entity does not equal provided", tracker._persistence_getFetchGroup().equals(groupToCompare));
179
        assertTrue("FetchGroup on entity does not equal provided", tracker._persistence_getFetchGroup().equals(groupToCompare));
180
180
181
        Server session = JpaHelper.getServerSession(emf);
181
        Server session = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession();
182
        assertNotNull(session);
182
        assertNotNull(session);
183
        ClassDescriptor descriptor = session.getClassDescriptor(entity);
183
        ClassDescriptor descriptor = session.getClassDescriptor(entity);
184
        assertNotNull(descriptor);
184
        assertNotNull(descriptor);
Lines 220-226 Link Here
220
    public static void assertDefaultFetched(EntityManagerFactory emf, Object entity) {
220
    public static void assertDefaultFetched(EntityManagerFactory emf, Object entity) {
221
        assertNotNull("Null entity", entity);
221
        assertNotNull("Null entity", entity);
222
222
223
        ClassDescriptor descriptor = JpaHelper.getServerSession(emf).getClassDescriptor(entity);
223
        ClassDescriptor descriptor = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession().getClassDescriptor(entity);
224
        assertNotNull("No descriptor found for: " + entity, descriptor);
224
        assertNotNull("No descriptor found for: " + entity, descriptor);
225
225
226
        assertTrue("No FetchGroupManager on: " + descriptor, descriptor.hasFetchGroupManager());
226
        assertTrue("No FetchGroupManager on: " + descriptor, descriptor.hasFetchGroupManager());
Lines 234-240 Link Here
234
    public static void assertFetched(EntityManagerFactory emf, Object entity, String fetchGroupName) {
234
    public static void assertFetched(EntityManagerFactory emf, Object entity, String fetchGroupName) {
235
        assertNotNull("Null entity", entity);
235
        assertNotNull("Null entity", entity);
236
236
237
        ClassDescriptor descriptor = JpaHelper.getServerSession(emf).getClassDescriptor(entity);
237
        ClassDescriptor descriptor = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession().getClassDescriptor(entity);
238
        assertNotNull("No descriptor found for: " + entity, descriptor);
238
        assertNotNull("No descriptor found for: " + entity, descriptor);
239
239
240
        assertTrue("No FetchGroupManager on: " + descriptor, descriptor.hasFetchGroupManager());
240
        assertTrue("No FetchGroupManager on: " + descriptor, descriptor.hasFetchGroupManager());
Lines 263-269 Link Here
263
    }
263
    }
264
264
265
    public static void assertConfig(EntityManagerFactory emf, String entityName, FetchGroup defaultFetchGroup, int numNamedFetchGroups) {
265
    public static void assertConfig(EntityManagerFactory emf, String entityName, FetchGroup defaultFetchGroup, int numNamedFetchGroups) {
266
        ClassDescriptor descriptor = JpaHelper.getServerSession(emf).getClassDescriptorForAlias(entityName);
266
        ClassDescriptor descriptor = ((org.eclipse.persistence.jpa.JpaEntityManager)emf.createEntityManager()).getServerSession().getClassDescriptorForAlias(entityName);
267
        assertNotNull("Not descriptor found for: " + entityName, descriptor);
267
        assertNotNull("Not descriptor found for: " + entityName, descriptor);
268
        assertConfig(descriptor, defaultFetchGroup, numNamedFetchGroups);
268
        assertConfig(descriptor, defaultFetchGroup, numNamedFetchGroups);
269
    }
269
    }
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupMergeWithCacheTests.java (-2 / +3 lines)
Lines 40-47 Link Here
40
        
40
        
41
        suite.addTest(new FetchGroupMergeWithCacheTests("testSetup"));
41
        suite.addTest(new FetchGroupMergeWithCacheTests("testSetup"));
42
        suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_QueryWithFetchGroup_Simple"));
42
        suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_QueryWithFetchGroup_Simple"));
43
        suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_FindWithFetchGroup_Simple"));
43
        if (!isJPA10()) {
44
        
44
            suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_FindWithFetchGroup_Simple"));
45
        }
45
        return suite;
46
        return suite;
46
    }
47
    }
47
48
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupsServerTestSuite.java (+38 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     Oracle - initial API and implementation from Oracle TopLink
12
 ******************************************************************************/  
13
package org.eclipse.persistence.testing.tests.jpa.fetchgroups;
14
15
import junit.framework.TestSuite;
16
import junit.framework.Test;
17
18
/**
19
 * <p><b>Purpose</b>: To collect the tests that will run against Application Server only.
20
 */
21
public class FetchGroupsServerTestSuite extends TestSuite {
22
    
23
    public static Test suite() {
24
        TestSuite suite = new TestSuite();
25
        suite.setName("FetchGroups ServerTestSuite");
26
        suite.addTest(FetchGroupAPITests.suite());
27
        suite.addTest(FetchGroupMergeWithCacheTests.suite());
28
        suite.addTest(FetchGroupTrackerWeavingTests.suite());
29
        suite.addTest(NestedDefaultFetchGroupTests.suite());
30
        suite.addTest(NestedFetchGroupTests.suite());
31
        suite.addTest(NestedNamedFetchGroupTests.suite());
32
        suite.addTest(SimpleDefaultFetchGroupTests.suite());
33
        suite.addTest(SimpleFetchGroupTests.suite());
34
        suite.addTest(SimpleNamedFetchGroupTests.suite());
35
        suite.addTest(SimpleSerializeFetchGroupTests.suite());
36
        return suite;
37
    }
38
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/FetchGroupTrackerWeavingTests.java (-2 / +6 lines)
Lines 56-66 Link Here
56
     * Fetch Group tests require weaving.
56
     * Fetch Group tests require weaving.
57
     */
57
     */
58
    public void runBare() throws Throwable {
58
    public void runBare() throws Throwable {
59
        if (isWeavingEnabled()) {
59
        if (this.shouldRunTestOnServer()) {
60
            super.runBare();
60
            super.runBare();
61
        } else {
62
           if (isWeavingEnabled()) {
63
                super.runBare();
64
            }
61
        }
65
        }
62
    }
66
    }
63
67
    
64
    public static junit.framework.Test suite() {
68
    public static junit.framework.Test suite() {
65
        TestSuite suite = new TestSuite();
69
        TestSuite suite = new TestSuite();
66
        suite.setName("FetchGroupTrackerWeavingTests");
70
        suite.setName("FetchGroupTrackerWeavingTests");
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedDefaultFetchGroupTests.java (-8 / +15 lines)
Lines 56-70 Link Here
56
        
56
        
57
        suite.addTest(new NestedDefaultFetchGroupTests("testSetup"));
57
        suite.addTest(new NestedDefaultFetchGroupTests("testSetup"));
58
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployee"));
58
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployee"));
59
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddress"));
60
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadPhones"));
61
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhones"));
62
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhoneUsingFetchGroup"));
59
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhoneUsingFetchGroup"));
63
        suite.addTest(new NestedDefaultFetchGroupTests("allAddress"));
60
        if (!isJPA10()) {
64
        suite.addTest(new NestedDefaultFetchGroupTests("allPhone"));
61
            suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddress"));
65
        suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddress"));
62
            suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadPhones"));
66
        suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddressLoad"));
63
            suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhones"));
67
        
64
            suite.addTest(new NestedDefaultFetchGroupTests("allAddress"));
65
            suite.addTest(new NestedDefaultFetchGroupTests("allPhone"));
66
            suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddress"));
67
            suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddressLoad"));
68
        }
68
        return suite;
69
        return suite;
69
    }
70
    }
70
    
71
    
Lines 117-122 Link Here
117
118
118
    void internalFindMinEmployee(boolean loadAddress, boolean loadPhones, boolean useLoadGroup) {        
119
    void internalFindMinEmployee(boolean loadAddress, boolean loadPhones, boolean useLoadGroup) {        
119
        EntityManager em = createEntityManager();
120
        EntityManager em = createEntityManager();
121
        beginTransaction(em);
122
120
        int minId = minEmployeeIdWithAddressAndPhones(em);
123
        int minId = minEmployeeIdWithAddressAndPhones(em);
121
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
124
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
122
125
Lines 188-193 Link Here
188
                    defaultEmployeeFG.setShouldLoad(originalLoad);
191
                    defaultEmployeeFG.setShouldLoad(originalLoad);
189
                }
192
                }
190
            }
193
            }
194
            if (isTransactionActive(em)){
195
                rollbackTransaction(em);
196
            }
197
            closeEntityManager(em);
191
        }
198
        }
192
    }
199
    }
193
/*    void internalFindMinEmployee(boolean loadAddress, boolean loadPhones) {
200
/*    void internalFindMinEmployee(boolean loadAddress, boolean loadPhones) {
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedFetchGroupTests.java (-548 / +620 lines)
Lines 97-294 Link Here
97
    @Test
97
    @Test
98
    public void dynamicFetchGroup_EmployeeAddress() throws Exception {
98
    public void dynamicFetchGroup_EmployeeAddress() throws Exception {
99
        EntityManager em = createEntityManager();
99
        EntityManager em = createEntityManager();
100
        try {
101
            beginTransaction(em);
100
102
101
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
103
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
102
        query.setParameter("GENDER", Gender.Male);
104
            query.setParameter("GENDER", Gender.Male);
103
105
104
        // Define the fields to be fetched on Employee
106
            // Define the fields to be fetched on Employee
105
        FetchGroup fg = new FetchGroup();
107
            FetchGroup fg = new FetchGroup();
106
        fg.addAttribute("id");
108
            fg.addAttribute("id");
107
        fg.addAttribute("version");
109
            fg.addAttribute("version");
108
        fg.addAttribute("firstName");
110
            fg.addAttribute("firstName");
109
        fg.addAttribute("lastName");
111
            fg.addAttribute("lastName");
110
        fg.addAttribute("address.city");
112
            fg.addAttribute("address.city");
111
        fg.addAttribute("address.postalCode");
113
            fg.addAttribute("address.postalCode");
112
114
113
        // Configure the dynamic FetchGroup
115
            // Configure the dynamic FetchGroup
114
        query.setHint(QueryHints.FETCH_GROUP, fg);
116
            query.setHint(QueryHints.FETCH_GROUP, fg);
115
117
116
        List<Employee> emps = query.getResultList();
118
            List<Employee> emps = query.getResultList();
117
119
118
        assertNotNull(emps);
120
            assertNotNull(emps);
119
        for (Employee emp : emps) {
121
            for (Employee emp : emps) {
120
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
122
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
121
123
122
            assertNotNull(tracker._persistence_getFetchGroup());
124
                assertNotNull(tracker._persistence_getFetchGroup());
123
125
124
            // Verify specified fields plus mandatory ones are loaded
126
                // Verify specified fields plus mandatory ones are loaded
125
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
127
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
126
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
128
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
127
            assertTrue(tracker._persistence_isAttributeFetched("address"));
129
                assertTrue(tracker._persistence_isAttributeFetched("address"));
128
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
130
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
129
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
131
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
130
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
132
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
131
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
133
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
132
134
133
            // Verify the other fields are not loaded
135
                // Verify the other fields are not loaded
134
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
136
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
135
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
137
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
136
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
138
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
137
139
138
            // Force the loading of lazy fields and verify
140
                // Force the loading of lazy fields and verify
139
            emp.getSalary();
141
                emp.getSalary();
140
142
141
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
143
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
142
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
144
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
143
            assertTrue(tracker._persistence_isAttributeFetched("address"));
145
                assertTrue(tracker._persistence_isAttributeFetched("address"));
144
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
146
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
145
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
147
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
146
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
148
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
147
149
148
            // Now we'll check the address uses the provided dynamic fetch-group
150
                // Now we'll check the address uses the provided dynamic fetch-group
149
            addrTracker = (FetchGroupTracker) emp.getAddress();
151
                addrTracker = (FetchGroupTracker) emp.getAddress();
150
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
152
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
151
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
153
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
152
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
154
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
153
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
155
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
154
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
156
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
155
157
156
            // Now we'll check the phoneNumbers use of the default fetch group
158
                // Now we'll check the phoneNumbers use of the default fetch group
157
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
159
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
158
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
160
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
159
                assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
161
                    assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
160
                assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
162
                    assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
161
                assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
163
                    assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
164
                }
162
            }
165
            }
166
        } finally {
167
            if (isTransactionActive(em)){
168
                rollbackTransaction(em);
169
            }
170
            closeEntityManager(em);
163
        }
171
        }
164
    }
172
    }
165
173
166
    @Test
174
    @Test
167
    public void dynamicFetchGroup_Employee_NullAddress() throws Exception {
175
    public void dynamicFetchGroup_Employee_NullAddress() throws Exception {
168
        EntityManager em = createEntityManager();
176
        EntityManager em = createEntityManager();
177
        try {
178
            beginTransaction(em);
169
179
170
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
180
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
171
        query.setParameter("GENDER", Gender.Male);
181
            query.setParameter("GENDER", Gender.Male);
172
182
173
        // Define the fields to be fetched on Employee
183
            // Define the fields to be fetched on Employee
174
        FetchGroup empGroup = new FetchGroup();
184
            FetchGroup empGroup = new FetchGroup();
175
        empGroup.addAttribute("firstName");
185
            empGroup.addAttribute("firstName");
176
        empGroup.addAttribute("lastName");
186
            empGroup.addAttribute("lastName");
177
        empGroup.addAttribute("address");
187
            empGroup.addAttribute("address");
178
188
179
        // Define the fields to be fetched on Address
189
            // Define the fields to be fetched on Address
180
        FetchGroup addressGroup = new FetchGroup();
190
            FetchGroup addressGroup = new FetchGroup();
181
        addressGroup.addAttribute("city");
191
            addressGroup.addAttribute("city");
182
        addressGroup.addAttribute("postalCode");
192
            addressGroup.addAttribute("postalCode");
183
193
184
        empGroup.addAttribute("address");
194
            empGroup.addAttribute("address");
185
195
186
        // Configure the dynamic FetchGroup
196
            // Configure the dynamic FetchGroup
187
        query.setHint(QueryHints.FETCH_GROUP, empGroup);
197
            query.setHint(QueryHints.FETCH_GROUP, empGroup);
188
198
189
        List<Employee> emps = query.getResultList();
199
            List<Employee> emps = query.getResultList();
190
200
191
        assertNotNull(emps);
201
            assertNotNull(emps);
192
        for (Employee emp : emps) {
202
            for (Employee emp : emps) {
193
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
203
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
194
204
195
            assertNotNull(tracker._persistence_getFetchGroup());
205
                assertNotNull(tracker._persistence_getFetchGroup());
196
206
197
            // Verify specified fields plus mandatory ones are loaded
207
                // Verify specified fields plus mandatory ones are loaded
198
            assertTrue(tracker._persistence_isAttributeFetched("id"));
208
                assertTrue(tracker._persistence_isAttributeFetched("id"));
199
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
209
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
200
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
210
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
201
            assertTrue(tracker._persistence_isAttributeFetched("version"));
211
                assertTrue(tracker._persistence_isAttributeFetched("version"));
202
212
203
            // Verify the other fields are not loaded
213
                // Verify the other fields are not loaded
204
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
214
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
205
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
215
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
206
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
216
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
207
217
208
            // Force the loading of lazy fields and verify
218
                // Force the loading of lazy fields and verify
209
            emp.getSalary();
219
                emp.getSalary();
210
220
211
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
221
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
212
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
222
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
213
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
223
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
214
224
215
            // Now we'll check the address uses the provided dynamic fetch-group
225
                // Now we'll check the address uses the provided dynamic fetch-group
216
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
226
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
217
            assertNull("Address has an unexpected FetchGroup", addrTracker._persistence_getFetchGroup());
227
                assertNull("Address has an unexpected FetchGroup", addrTracker._persistence_getFetchGroup());
218
228
219
            // Now we'll check the phoneNumbers use of the default fetch group
229
                // Now we'll check the phoneNumbers use of the default fetch group
220
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
230
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
221
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
231
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
222
                assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
232
                    assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
223
                assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
233
                    assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
224
                assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
234
                    assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
235
                }
225
            }
236
            }
237
        } finally {
238
            if (isTransactionActive(em)){
239
                rollbackTransaction(em);
240
            }
241
            closeEntityManager(em);
226
        }
242
        }
227
    }
243
    }
228
244
229
    @Test
245
    @Test
230
    public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception {
246
    public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception {
231
        EntityManager em = createEntityManager();
247
        EntityManager em = createEntityManager();
248
        try {
249
            beginTransaction(em);
232
250
233
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
251
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
234
        query.setParameter("GENDER", Gender.Male);
252
            query.setParameter("GENDER", Gender.Male);
235
253
236
        // Define the fields to be fetched on Employee
254
            // Define the fields to be fetched on Employee
237
        FetchGroup empGroup = new FetchGroup();
255
            FetchGroup empGroup = new FetchGroup();
238
        empGroup.addAttribute("firstName");
256
            empGroup.addAttribute("firstName");
239
        empGroup.addAttribute("lastName");
257
            empGroup.addAttribute("lastName");
240
        empGroup.addAttribute("address");
258
            empGroup.addAttribute("address");
241
        empGroup.addAttribute("address.city");
259
            empGroup.addAttribute("address.city");
242
        empGroup.addAttribute("address.postalCode");
260
            empGroup.addAttribute("address.postalCode");
243
261
244
//        empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false);
262
            //empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false);
245
        FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
263
            FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
246
        // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
264
            // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
247
        fullPhone.addAttribute("owner.id");
265
            fullPhone.addAttribute("owner.id");
248
        empGroup.addAttribute("phoneNumbers", fullPhone);
266
            empGroup.addAttribute("phoneNumbers", fullPhone);
249
267
250
        // Configure the dynamic FetchGroup
268
            // Configure the dynamic FetchGroup
251
        query.setHint(QueryHints.FETCH_GROUP, empGroup);
269
            query.setHint(QueryHints.FETCH_GROUP, empGroup);
252
270
253
        List<Employee> emps = query.getResultList();
271
            List<Employee> emps = query.getResultList();
254
272
255
        assertNotNull(emps);
273
            assertNotNull(emps);
256
        for (Employee emp : emps) {
274
            for (Employee emp : emps) {
257
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
275
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
258
276
259
            assertNotNull(tracker._persistence_getFetchGroup());
277
                assertNotNull(tracker._persistence_getFetchGroup());
260
278
261
            // Verify specified fields plus mandatory ones are loaded
279
                // Verify specified fields plus mandatory ones are loaded
262
            assertTrue(tracker._persistence_isAttributeFetched("id"));
280
                assertTrue(tracker._persistence_isAttributeFetched("id"));
263
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
281
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
264
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
282
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
265
            assertTrue(tracker._persistence_isAttributeFetched("version"));
283
                assertTrue(tracker._persistence_isAttributeFetched("version"));
266
284
267
            // Verify the other fields are not loaded
285
                // Verify the other fields are not loaded
268
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
286
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
269
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
287
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
270
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
288
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
271
289
272
            // Force the loading of lazy fields and verify
290
                // Force the loading of lazy fields and verify
273
            emp.getSalary();
291
                emp.getSalary();
274
292
275
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
293
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
276
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
294
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
277
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
295
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
278
296
279
            // Now we'll check the address uses the provided dynamic fetch-group
297
                // Now we'll check the address uses the provided dynamic fetch-group
280
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
298
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
281
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
299
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
282
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
300
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
283
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
301
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
284
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
302
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
285
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
303
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
286
304
287
            // Now we'll check the phoneNumbers use of the default fetch group
305
                // Now we'll check the phoneNumbers use of the default fetch group
288
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
306
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
289
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
307
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
290
                assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup());
308
                    assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup());
309
                }
291
            }
310
            }
311
        } finally {
312
            if (isTransactionActive(em)){
313
                rollbackTransaction(em);
314
            }
315
            closeEntityManager(em);
292
        }
316
        }
293
    }
317
    }
294
318
Lines 301-376 Link Here
301
    }
325
    }
302
    void internal_dynamicFetchGroup_EmployeeAddressEmptyPhone(boolean shouldLoad) {
326
    void internal_dynamicFetchGroup_EmployeeAddressEmptyPhone(boolean shouldLoad) {
303
        EntityManager em = createEntityManager();
327
        EntityManager em = createEntityManager();
328
        try {
329
            beginTransaction(em);
304
330
305
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
331
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
306
        query.setParameter("GENDER", Gender.Male);
332
            query.setParameter("GENDER", Gender.Male);
307
333
308
        // Define the fields to be fetched on Employee
334
            // Define the fields to be fetched on Employee
309
        FetchGroup fg = new FetchGroup();
335
            FetchGroup fg = new FetchGroup();
310
        fg.addAttribute("firstName");
336
            fg.addAttribute("firstName");
311
        fg.addAttribute("lastName");
337
            fg.addAttribute("lastName");
312
        fg.addAttribute("address.city");
338
            fg.addAttribute("address.city");
313
        fg.addAttribute("address.postalCode");
339
            fg.addAttribute("address.postalCode");
314
        // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
340
            // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
315
        FetchGroup ownerId = new FetchGroup();
341
            FetchGroup ownerId = new FetchGroup();
316
        ownerId.addAttribute("owner.id");
342
            ownerId.addAttribute("owner.id");
317
        fg.addAttribute("phoneNumbers", ownerId);
343
            fg.addAttribute("phoneNumbers", ownerId);
318
        
344
            
319
        if(shouldLoad) {
345
            if(shouldLoad) {
320
            fg.setShouldLoad(true);
346
                fg.setShouldLoad(true);
321
        }
347
            }
322
348
323
        // Configure the dynamic FetchGroup
349
            // Configure the dynamic FetchGroup
324
        query.setHint(QueryHints.FETCH_GROUP, fg);
350
            query.setHint(QueryHints.FETCH_GROUP, fg);
325
351
326
        List<Employee> emps = query.getResultList();
352
            List<Employee> emps = query.getResultList();
327
353
328
        assertNotNull(emps);
354
            assertNotNull(emps);
329
        assertEquals(1 + (shouldLoad ? 0 : (emps.size() * 2)), getQuerySQLTracker(em).getTotalSQLSELECTCalls());
355
            assertEquals(1 + (shouldLoad ? 0 : (emps.size() * 2)), getQuerySQLTracker(em).getTotalSQLSELECTCalls());
330
        
356
            
331
        for (Employee emp : emps) {
357
            for (Employee emp : emps) {
332
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
358
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
333
359
334
            assertNotNull(tracker._persistence_getFetchGroup());
360
                assertNotNull(tracker._persistence_getFetchGroup());
335
361
336
            // Verify specified fields plus mandatory ones are loaded
362
                // Verify specified fields plus mandatory ones are loaded
337
            assertTrue(tracker._persistence_isAttributeFetched("id"));
363
                assertTrue(tracker._persistence_isAttributeFetched("id"));
338
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
364
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
339
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
365
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
340
            assertTrue(tracker._persistence_isAttributeFetched("version"));
366
                assertTrue(tracker._persistence_isAttributeFetched("version"));
341
367
342
            // Verify the other fields are not loaded
368
                // Verify the other fields are not loaded
343
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
369
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
344
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
370
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
345
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
371
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
346
372
347
            // Force the loading of lazy fields and verify
373
                // Force the loading of lazy fields and verify
348
            emp.getSalary();
374
                emp.getSalary();
349
375
350
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
376
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
351
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
377
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
352
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
378
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
353
379
354
            // Now we'll check the address uses the provided dynamic fetch-group
380
                // Now we'll check the address uses the provided dynamic fetch-group
355
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
381
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
356
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
382
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
357
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
383
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
358
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
384
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
359
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
385
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
360
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
386
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
361
387
362
            // Now we'll check the phoneNumbers use of the default fetch group
388
                // Now we'll check the phoneNumbers use of the default fetch group
363
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
389
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
364
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
390
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
365
                assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
391
                    assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
366
                assertFalse(phoneTracker._persistence_isAttributeFetched("number"));
392
                    assertFalse(phoneTracker._persistence_isAttributeFetched("number"));
367
                assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
393
                    assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
368
394
369
                phone.getNumber();
395
                    phone.getNumber();
370
396
371
                assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
397
                    assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
372
                assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode"));
398
                    assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode"));
399
                }
373
            }
400
            }
401
        } finally {
402
            if (isTransactionActive(em)){
403
                rollbackTransaction(em);
404
            }
405
            closeEntityManager(em);
374
        }
406
        }
375
    }
407
    }
376
408
Lines 421-552 Link Here
421
    void internalDynamicHierarchicalFetchGroup_JOIN_FETCH(boolean useCopy) throws Exception {
453
    void internalDynamicHierarchicalFetchGroup_JOIN_FETCH(boolean useCopy) throws Exception {
422
454
423
        EntityManager em = createEntityManager();
455
        EntityManager em = createEntityManager();
424
        
456
        try {
425
        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.manager WHERE e.lastName LIKE :LNAME AND e.manager.lastName <> e.lastName");
457
            beginTransaction(em);
426
        query.setParameter("LNAME", "%");
427
458
428
        // Define the fields to be fetched on Employee
459
            Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.manager WHERE e.lastName LIKE :LNAME AND e.manager.lastName <> e.lastName");
429
        FetchGroup fg = new FetchGroup();
460
            query.setParameter("LNAME", "%");
430
        fg.addAttribute("firstName");
431
        fg.addAttribute("lastName");
432
        fg.addAttribute("manager.firstName");
433
        fg.addAttribute("manager.salary");
434
        fg.addAttribute("manager.manager");
435
        query.setHint(QueryHints.FETCH_GROUP, fg);
436
        
437
        // applied to the selected Employee who is not a manager of some other selected Employee
438
        FetchGroup employeeFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "lastName", "manager"}); 
439
        // applied to the manager of a selected Employee who is not selected as an Employee
440
        FetchGroup managerFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "salary", "manager"});
441
        // applied to the object which is both selected as an Employee and the manager of another selected Employee
442
        FetchGroup employeeManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(employeeFG, managerFG); 
443
        
444
        // used in useCopy case only
445
        FetchGroup employeeManagerManagerFG = null;
446
        if(useCopy) {
447
            employeeManagerManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(new EntityFetchGroup("manager"), employeeDescriptor.getFetchGroupManager().getNonReferenceEntityFetchGroup()); 
448
        }
449
        
450
        /*
451
         * These are the first names of Employees involved; --> means "managed by".
452
         * All the employees here are returned by the query except Jill and Sarah-loo (they got no manager).
453
         * 
454
         * Sarah ------>Bob -------> John ----> Jim-bob ---> Jill ---> null
455
         * Charles -----^   Marius ----^
456
         * 
457
         * Nancy ------> Sarah-loo ---> null
458
         * 
459
         * Sarah, Charles, Nancy should have employeeFG;
460
         * Sarah-loo - managerFG;
461
         * Bob, Marius - employeeManagerFG;
462
         * John, Jim-bob should have a union of three fetch groups: {firstName,lastName,manager}, {firstName,salary,manager}, {manager}
463
         * Jill should have a union of two groups:  {firstName,salary,manager}, {manager}
464
         * The result for all three of them is the same:
465
         *   in read case (useCopy == false) it should be null (no fetch group), because defaultFetchGroup is null;
466
         *   in copy case (useCopy == true) it should be a union of "manager" and all non relational attributes (NonReferenceEntityFetchGroup).
467
         * That's how leaf reference attribute is treated: 
468
         *   default fetch group for read;
469
         *   NonReferenceEntityFetchGroup (see FetchGroupManager) for copy.
470
         * In this test defaultFetchGroup (null) / NonReferenceEntityFetchGroup comes from {manager},
471
         *   in useCopy == true case additional manager comes from another fetch group (they all contain manager).
472
         */
473
        
474
        List<Employee> emps = query.getResultList();
475
        
476
        if(useCopy) {
477
/*            for(Employee emp : emps) {
478
                int idHashCode =  System.identityHashCode(emp);
479
                System.out.println(emp.getFirstName() + '\t' + idHashCode);
480
            }*/
481
            emps = (List)JpaHelper.getEntityManager(em).copy(emps, fg);
482
        }
483
461
484
        // Sets of managed Employees keyed by their manager
462
            // Define the fields to be fetched on Employee
485
        Map<Employee, Set<Employee>> managedEmployeesByManager = new IdentityHashMap();
463
            FetchGroup fg = new FetchGroup();
486
        for (Employee emp : emps) {
464
            fg.addAttribute("firstName");
487
            Employee manager = emp.getManager(); 
465
            fg.addAttribute("lastName");
488
            Set<Employee> managedEmployees = managedEmployeesByManager.get(manager);
466
            fg.addAttribute("manager.firstName");
489
            if(managedEmployees == null) {
467
            fg.addAttribute("manager.salary");
490
                managedEmployees = new IdentityHashSet();
468
            fg.addAttribute("manager.manager");
491
                managedEmployeesByManager.put(manager, managedEmployees);
469
            query.setHint(QueryHints.FETCH_GROUP, fg);
470
            
471
            // applied to the selected Employee who is not a manager of some other selected Employee
472
            FetchGroup employeeFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "lastName", "manager"}); 
473
            // applied to the manager of a selected Employee who is not selected as an Employee
474
            FetchGroup managerFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "salary", "manager"});
475
            // applied to the object which is both selected as an Employee and the manager of another selected Employee
476
            FetchGroup employeeManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(employeeFG, managerFG); 
477
            
478
            // used in useCopy case only
479
            FetchGroup employeeManagerManagerFG = null;
480
            if(useCopy) {
481
                employeeManagerManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(new EntityFetchGroup("manager"), employeeDescriptor.getFetchGroupManager().getNonReferenceEntityFetchGroup()); 
492
            }
482
            }
493
            managedEmployees.add(emp);
483
            
494
        }
484
            /*
485
             * These are the first names of Employees involved; --> means "managed by".
486
             * All the employees here are returned by the query except Jill and Sarah-loo (they got no manager).
487
             * 
488
             * Sarah ------>Bob -------> John ----> Jim-bob ---> Jill ---> null
489
             * Charles -----^   Marius ----^
490
             * 
491
             * Nancy ------> Sarah-loo ---> null
492
             * 
493
             * Sarah, Charles, Nancy should have employeeFG;
494
             * Sarah-loo - managerFG;
495
             * Bob, Marius - employeeManagerFG;
496
             * John, Jim-bob should have a union of three fetch groups: {firstName,lastName,manager}, {firstName,salary,manager}, {manager}
497
             * Jill should have a union of two groups:  {firstName,salary,manager}, {manager}
498
             * The result for all three of them is the same:
499
             *   in read case (useCopy == false) it should be null (no fetch group), because defaultFetchGroup is null;
500
             *   in copy case (useCopy == true) it should be a union of "manager" and all non relational attributes (NonReferenceEntityFetchGroup).
501
             * That's how leaf reference attribute is treated: 
502
             *   default fetch group for read;
503
             *   NonReferenceEntityFetchGroup (see FetchGroupManager) for copy.
504
             * In this test defaultFetchGroup (null) / NonReferenceEntityFetchGroup comes from {manager},
505
             *   in useCopy == true case additional manager comes from another fetch group (they all contain manager).
506
             */
507
            
508
            List<Employee> emps = query.getResultList();
509
            
510
            if(useCopy) {
511
                /*for(Employee emp : emps) {
512
                    int idHashCode =  System.identityHashCode(emp);
513
                    System.out.println(emp.getFirstName() + '\t' + idHashCode);
514
                }*/
515
                emps = (List)JpaHelper.getEntityManager(em).copy(emps, fg);
516
            }
495
517
496
        for (Employee emp : emps) {
518
            // Sets of managed Employees keyed by their manager
497
            Set<Employee> managedEmployees = managedEmployeesByManager.get(emp);
519
            Map<Employee, Set<Employee>> managedEmployeesByManager = new IdentityHashMap();
498
            Employee manager = emp.getManager();
520
            for (Employee emp : emps) {
499
            if(managedEmployees == null) {
521
                Employee manager = emp.getManager(); 
500
                // employee is NOT a manager of any of the selected employees:
522
                Set<Employee> managedEmployees = managedEmployeesByManager.get(manager);
501
                assertFetched(emp, employeeFG);
523
                if(managedEmployees == null) {
524
                    managedEmployees = new IdentityHashSet();
525
                    managedEmployeesByManager.put(manager, managedEmployees);
526
                }
527
                managedEmployees.add(emp);
528
            }
502
529
503
                Set<Employee> managedByManagerEmployees = managedEmployeesByManager.get(manager); 
530
            for (Employee emp : emps) {
504
                // indicates whether one of manager's managed employees is a manager itself
531
                Set<Employee> managedEmployees = managedEmployeesByManager.get(emp);
505
                boolean isManagersManager = false;
532
                Employee manager = emp.getManager();
506
                for(Employee managedEmp : managedByManagerEmployees) {
533
                if(managedEmployees == null) {
507
                    if(managedEmployeesByManager.containsKey(managedEmp)) {
534
                    // employee is NOT a manager of any of the selected employees:
508
                        isManagersManager = true;
535
                    assertFetched(emp, employeeFG);
509
                        break;
536
537
                    Set<Employee> managedByManagerEmployees = managedEmployeesByManager.get(manager); 
538
                    // indicates whether one of manager's managed employees is a manager itself
539
                    boolean isManagersManager = false;
540
                    for(Employee managedEmp : managedByManagerEmployees) {
541
                        if(managedEmployeesByManager.containsKey(managedEmp)) {
542
                            isManagersManager = true;
543
                            break;
544
                        }
510
                    }
545
                    }
511
                }
546
                    if(isManagersManager) {
512
                if(isManagersManager) {
547
                        if(useCopy) {
513
                    if(useCopy) {
548
                            // for at least one of the selected employees manager is manager's manager:
514
                        // for at least one of the selected employees manager is manager's manager:
549
                            //   someSelectedEmp.getManager().getManager() == manager
515
                        //   someSelectedEmp.getManager().getManager() == manager
550
                            // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
516
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
551
                            // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
517
                        // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
552
                            // for another employee it's just a manager - which means it should include "manager":
518
                        // for another employee it's just a manager - which means it should include "manager":
553
                            // employeeManagerManagerFG is the union of these two EntityFetchGroups.
519
                        // employeeManagerManagerFG is the union of these two EntityFetchGroups.
554
                            assertFetched(manager, employeeManagerManagerFG);
520
                        assertFetched(manager, employeeManagerManagerFG);
555
                        } else {
556
                            // for at least one of the selected employees manager is manager's manager:
557
                            //   someSelectedEmp.getManager().getManager() == manager
558
                            // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
559
                            // which means no fetch group should be used. 
560
                            assertNoFetchGroup(manager);
561
                        }
521
                    } else {
562
                    } else {
522
                        // for at least one of the selected employees manager is manager's manager:
563
                        // it's not manager's manager
523
                        //   someSelectedEmp.getManager().getManager() == manager
564
                        if(emps.contains(manager)) {
524
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
565
                            // it's a manager of one of the selected Employees, and selected itself.
525
                        // which means no fetch group should be used. 
566
                            assertFetched(manager, employeeManagerFG);
526
                        assertNoFetchGroup(manager);
567
                        } else {
568
                            // it's a manager of one of the selected Employees, but not selected itself.
569
                            assertFetched(manager, managerFG);
570
                        }
527
                    }
571
                    }
528
                } else {
572
                } else {
529
                    // it's not manager's manager
573
                    // employee is a manager of at least one of the selected employees
530
                    if(emps.contains(manager)) {
574
                    // indicates whether one of emp's managed employees is a manager itself
531
                        // it's a manager of one of the selected Employees, and selected itself.
575
                    boolean isManagersManager = false;
532
                        assertFetched(manager, employeeManagerFG);
576
                    for(Employee managedEmp : managedEmployees) {
577
                        if(managedEmployeesByManager.containsKey(managedEmp)) {
578
                            isManagersManager = true;
579
                            break;
580
                        }
581
                    }
582
                    
583
                    if(isManagersManager) {
584
                        if(useCopy) {
585
                            // for at least one of the selected employees manager is manager's manager:
586
                            //   someSelectedEmp.getManager().getManager() == manager
587
                            // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
588
                            // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
589
                            // for another employee it's just a manager - which means it should include "manager":
590
                            // employeeManagerManagerFG is the union of these two EntityFetchGroups.
591
                            assertFetched(emp, employeeManagerManagerFG);
592
                        } else {
593
                            // for at least one of the selected employees emp is manager's manager:
594
                            //   someSelectedEmp.getManager().getManager() == emp
595
                            // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
596
                            // which means no fetch group should be used. 
597
                            assertNoFetchGroup(emp);
598
                        }
533
                    } else {
599
                    } else {
534
                        // it's a manager of one of the selected Employees, but not selected itself.
600
                        // it's selected employee, manager of some selected employee, but not manager's manager
535
                        assertFetched(manager, managerFG);
601
                        assertFetched(emp, employeeManagerFG);
536
                    }
602
                    }
537
                }
603
                    
538
            } else {
539
                // employee is a manager of at least one of the selected employees
540
                // indicates whether one of emp's managed employees is a manager itself
541
                boolean isManagersManager = false;
542
                for(Employee managedEmp : managedEmployees) {
543
                    if(managedEmployeesByManager.containsKey(managedEmp)) {
544
                        isManagersManager = true;
545
                        break;
546
                    }
547
                }
548
                
549
                if(isManagersManager) {
550
                    if(useCopy) {
604
                    if(useCopy) {
551
                        // for at least one of the selected employees manager is manager's manager:
605
                        // for at least one of the selected employees manager is manager's manager:
552
                        //   someSelectedEmp.getManager().getManager() == manager
606
                        //   someSelectedEmp.getManager().getManager() == manager
Lines 554-588 Link Here
554
                        // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
608
                        // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
555
                        // for another employee it's just a manager - which means it should include "manager":
609
                        // for another employee it's just a manager - which means it should include "manager":
556
                        // employeeManagerManagerFG is the union of these two EntityFetchGroups.
610
                        // employeeManagerManagerFG is the union of these two EntityFetchGroups.
557
                        assertFetched(emp, employeeManagerManagerFG);
611
                        assertFetched(manager, employeeManagerManagerFG);
558
                    } else {
612
                    } else {
559
                        // for at least one of the selected employees emp is manager's manager:
613
                        // for at least one of the selected employees manager is manager's manager:
560
                        //   someSelectedEmp.getManager().getManager() == emp
614
                        //   someSelectedEmp.getManager().getManager() == manager
561
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
615
                        // That means for someSelectedEmp emp.getManager() is defined by {manager.manager} FetchGroup's item,
562
                        // which means no fetch group should be used. 
616
                        // which means no fetch group should be used. 
563
                        assertNoFetchGroup(emp);
617
                        assertNoFetchGroup(manager);
564
                    }
618
                    }
565
                } else {
566
                    // it's selected employee, manager of some selected employee, but not manager's manager
567
                    assertFetched(emp, employeeManagerFG);
568
                }
619
                }
569
                
620
            }
570
                if(useCopy) {
621
        } finally {
571
                    // for at least one of the selected employees manager is manager's manager:
622
            if (isTransactionActive(em)){
572
                    //   someSelectedEmp.getManager().getManager() == manager
623
                rollbackTransaction(em);
573
                    // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
624
            }
574
                    // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
625
            closeEntityManager(em);
575
                    // for another employee it's just a manager - which means it should include "manager":
576
                    // employeeManagerManagerFG is the union of these two EntityFetchGroups.
577
                    assertFetched(manager, employeeManagerManagerFG);
578
                } else {
579
                    // for at least one of the selected employees manager is manager's manager:
580
                    //   someSelectedEmp.getManager().getManager() == manager
581
                    // That means for someSelectedEmp emp.getManager() is defined by {manager.manager} FetchGroup's item,
582
                    // which means no fetch group should be used. 
583
                    assertNoFetchGroup(manager);
584
                }
585
            }            
586
        }
626
        }
587
    }
627
    }
588
    
628
    
Lines 598-754 Link Here
598
638
599
   void managerNestedFetchGroupWithJoinFetch(boolean isDouble) {
639
   void managerNestedFetchGroupWithJoinFetch(boolean isDouble) {
600
        EntityManager em = createEntityManager();
640
        EntityManager em = createEntityManager();
641
        try {
642
            beginTransaction(em);
601
643
602
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager.manager IS NOT NULL");
644
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager.manager IS NOT NULL");
603
        FetchGroup managerFG = new FetchGroup();
645
            FetchGroup managerFG = new FetchGroup();
604
        if(isDouble) {
646
            if(isDouble) {
605
            // Double
647
                // Double
606
            managerFG.addAttribute("manager.manager");
648
                managerFG.addAttribute("manager.manager");
607
        } else {
649
            } else {
608
            // Triple
650
                // Triple
609
            managerFG.addAttribute("manager.manager.manager");
651
                managerFG.addAttribute("manager.manager.manager");
610
        }
652
            }
611
653
612
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
654
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
613
        query.setHint(QueryHints.LEFT_FETCH, "e.manager");
655
            query.setHint(QueryHints.LEFT_FETCH, "e.manager");
614
656
615
        assertNotNull(getFetchGroup(query));
657
            assertNotNull(getFetchGroup(query));
616
        assertSame(managerFG, getFetchGroup(query));
658
            assertSame(managerFG, getFetchGroup(query));
617
659
618
        List<Employee> employees = query.getResultList();
660
            List<Employee> employees = query.getResultList();
619
661
620
        int nSql;
662
            int nSql;
621
        if(isDouble) {
663
            if(isDouble) {
622
            // In this case the number of generated sqls is unpredictable.
664
                // In this case the number of generated sqls is unpredictable.
623
            // Additional sql generated for every object that 
665
                // Additional sql generated for every object that 
624
            // has been first fetched as manager.manager
666
                // has been first fetched as manager.manager
625
            // and then is selected as an employee - getting its manger
667
                // and then is selected as an employee - getting its manger
626
            // performed without fetch group therefore triggering reading of the whole object
668
                // performed without fetch group therefore triggering reading of the whole object
627
            nSql = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
669
                nSql = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
628
        } else {
670
            } else {
629
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
671
                assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
630
            nSql = 1;
672
                nSql = 1;
631
        }
673
            }
632
        
674
            
633
        Employee emp = employees.get(0);
675
            Employee emp = employees.get(0);
634
        assertFetched(emp, managerFG);
676
            assertFetched(emp, managerFG);
635
        
677
            
636
        // manager (if not null) is instantiated by the fetch group, before emp.getManager call.
678
            // manager (if not null) is instantiated by the fetch group, before emp.getManager call.
637
        Employee manager = emp.getManager();
679
            Employee manager = emp.getManager();
638
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
680
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
639
        assertFetched(manager, managerFG);
681
            assertFetched(manager, managerFG);
640
        
682
            
641
        // instantiates the whole object
683
            // instantiates the whole object
642
        emp.getLastName();
684
            emp.getLastName();
643
        nSql++;
685
            nSql++;
644
        assertNoFetchGroup(emp);
686
            assertNoFetchGroup(emp);
645
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
687
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
646
        
688
            
647
        assertFetched(manager, managerFG);
689
            assertFetched(manager, managerFG);
648
        // instantiates the whole object
690
            // instantiates the whole object
649
        manager.getLastName();
691
            manager.getLastName();
650
        nSql++;
692
            nSql++;
651
        assertNoFetchGroup(manager);
693
            assertNoFetchGroup(manager);
652
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
694
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
653
695
654
        nSql++;
655
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
656
            assertFetched(phone, this.defaultPhoneFG);
657
            phone.getAreaCode();
658
            nSql++;
696
            nSql++;
659
            assertNoFetchGroup(phone);
697
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
660
        }
698
                assertFetched(phone, this.defaultPhoneFG);
661
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
699
                phone.getAreaCode();
700
                nSql++;
701
                assertNoFetchGroup(phone);
702
            }
703
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
662
704
663
        nSql++;
664
        for (PhoneNumber phone : manager.getPhoneNumbers()) {
665
            assertFetched(phone, this.defaultPhoneFG);
666
            phone.getAreaCode();
667
            nSql++;
705
            nSql++;
668
            assertNoFetchGroup(phone);
706
            for (PhoneNumber phone : manager.getPhoneNumbers()) {
707
                assertFetched(phone, this.defaultPhoneFG);
708
                phone.getAreaCode();
709
                nSql++;
710
                assertNoFetchGroup(phone);
711
            }
712
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
713
        } finally {
714
            if (isTransactionActive(em)){
715
                rollbackTransaction(em);
716
            }
717
            closeEntityManager(em);
669
        }
718
        }
670
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
671
    }
719
    }
672
720
673
   @Test
721
   @Test
674
   public void allNestedFetchGroupWithJoinFetch() {
722
   public void allNestedFetchGroupWithJoinFetch() {
675
        EntityManager em = createEntityManager();
723
        EntityManager em = createEntityManager();
724
        try {
725
            beginTransaction(em);
676
726
677
        // select employees who are neither managers nor team leaders
727
            // select employees who are neither managers nor team leaders
678
        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)");
728
            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)");
679
        FetchGroup employeeFG = new FetchGroup("employee");
729
            FetchGroup employeeFG = new FetchGroup("employee");
680
        employeeFG.addAttribute("lastName");
730
            employeeFG.addAttribute("lastName");
681
        
731
            
682
        employeeFG.addAttribute("address.country");
732
            employeeFG.addAttribute("address.country");
683
        employeeFG.addAttribute("address.city");
733
            employeeFG.addAttribute("address.city");
684
        query.setHint(QueryHints.LEFT_FETCH, "e.address");
734
            query.setHint(QueryHints.LEFT_FETCH, "e.address");
685
        
735
            
686
        employeeFG.addAttribute("phoneNumbers");
736
            employeeFG.addAttribute("phoneNumbers");
687
        query.setHint(QueryHints.LEFT_FETCH, "e.phoneNumbers");
737
            query.setHint(QueryHints.LEFT_FETCH, "e.phoneNumbers");
688
        
738
            
689
        employeeFG.addAttribute("projects.name");
739
            employeeFG.addAttribute("projects.name");
690
740
691
        employeeFG.addAttribute("projects.teamLeader.firstName");
741
            employeeFG.addAttribute("projects.teamLeader.firstName");
692
//        employeeFG.addAttribute("projects.teamLeader.address.street");
742
            //employeeFG.addAttribute("projects.teamLeader.address.street");
693
//        employeeFG.addAttribute("projects.teamLeader.address.postalCode");
743
            //employeeFG.addAttribute("projects.teamLeader.address.postalCode");
694
        employeeFG.addAttribute("projects.teamLeader.phoneNumbers.owner");
744
            employeeFG.addAttribute("projects.teamLeader.phoneNumbers.owner");
695
        employeeFG.addAttribute("projects.teamLeader.phoneNumbers.type");
745
            employeeFG.addAttribute("projects.teamLeader.phoneNumbers.type");
696
        employeeFG.addAttribute("projects.teamLeader.phoneNumbers.areaCode");
746
            employeeFG.addAttribute("projects.teamLeader.phoneNumbers.areaCode");
697
        query.setHint(QueryHints.LEFT_FETCH, "e.projects.teamLeader.phoneNumbers");
747
            query.setHint(QueryHints.LEFT_FETCH, "e.projects.teamLeader.phoneNumbers");
698
        
748
            
699
        employeeFG.addAttribute("manager.firstName");
749
            employeeFG.addAttribute("manager.firstName");
700
//        employeeFG.addAttribute("manager.address.street");
750
            //employeeFG.addAttribute("manager.address.street");
701
//        employeeFG.addAttribute("manager.address.postalCode");
751
            //employeeFG.addAttribute("manager.address.postalCode");
702
        employeeFG.addAttribute("manager.phoneNumbers.owner");
752
            employeeFG.addAttribute("manager.phoneNumbers.owner");
703
        employeeFG.addAttribute("manager.phoneNumbers.type");
753
            employeeFG.addAttribute("manager.phoneNumbers.type");
704
        employeeFG.addAttribute("manager.phoneNumbers.areaCode");
754
            employeeFG.addAttribute("manager.phoneNumbers.areaCode");
705
        query.setHint(QueryHints.LEFT_FETCH, "e.manager.phoneNumbers");
755
            query.setHint(QueryHints.LEFT_FETCH, "e.manager.phoneNumbers");
706
756
707
        // department attribute defined with JoinFetchType.OUTER
757
            // department attribute defined with JoinFetchType.OUTER
708
        employeeFG.addAttribute("department.name");
758
            employeeFG.addAttribute("department.name");
709
        
759
            
710
        query.setHint(QueryHints.FETCH_GROUP, employeeFG);
760
            query.setHint(QueryHints.FETCH_GROUP, employeeFG);
711
761
712
        List<Employee> employees = query.getResultList();
762
            List<Employee> employees = query.getResultList();
713
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
763
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
714
        
715
        for(Employee emp :employees) {
716
            assertFetched(emp, employeeFG);
717
            
764
            
718
            Address address = emp.getAddress();
765
            for(Employee emp :employees) {
719
            if(address != null) {
766
                assertFetched(emp, employeeFG);
720
                assertFetched(address, employeeFG.getGroup("address"));
767
                
721
            }
768
                Address address = emp.getAddress();
769
                if(address != null) {
770
                    assertFetched(address, employeeFG.getGroup("address"));
771
                }
722
772
723
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
773
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
724
                assertFetched(phone, defaultPhoneFG);
774
                    assertFetched(phone, defaultPhoneFG);
725
            }
775
                }
726
            
776
                
727
            for (Project project : emp.getProjects()) {
777
                for (Project project : emp.getProjects()) {
728
                assertFetched(project, employeeFG.getGroup("projects"));
778
                    assertFetched(project, employeeFG.getGroup("projects"));
729
                Employee teamLeader = project.getTeamLeader();
779
                    Employee teamLeader = project.getTeamLeader();
730
                if(teamLeader != null) {
780
                    if(teamLeader != null) {
731
                    assertFetched(teamLeader, employeeFG.getGroup("projects.teamLeader"));
781
                        assertFetched(teamLeader, employeeFG.getGroup("projects.teamLeader"));
732
                    for (PhoneNumber phone : teamLeader.getPhoneNumbers()) {
782
                        for (PhoneNumber phone : teamLeader.getPhoneNumbers()) {
733
                        assertFetched(phone, employeeFG.getGroup("projects.teamLeader.phoneNumbers"));
783
                            assertFetched(phone, employeeFG.getGroup("projects.teamLeader.phoneNumbers"));
784
                        }
734
                    }
785
                    }
735
                }
786
                }
736
            }
787
                
737
            
788
                Employee manager = emp.getManager();
738
            Employee manager = emp.getManager();
789
                if(manager != null) {
739
            if(manager != null) {
790
                    assertFetched(manager, employeeFG.getGroup("manager"));
740
                assertFetched(manager, employeeFG.getGroup("manager"));
791
                    for (PhoneNumber phone : manager.getPhoneNumbers()) {
741
                for (PhoneNumber phone : manager.getPhoneNumbers()) {
792
                        assertFetched(phone, employeeFG.getGroup("manager.phoneNumbers"));
742
                    assertFetched(phone, employeeFG.getGroup("manager.phoneNumbers"));
793
                    }
743
                }
794
                }
795
                
796
                Department department = emp.getDepartment();
797
                if(department != null) {
798
                    assertFetched(department, employeeFG.getGroup("department"));
799
                }
744
            }
800
            }
745
            
801
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
746
            Department department = emp.getDepartment();
802
        } finally {
747
            if(department != null) {
803
            if (isTransactionActive(em)){
748
                assertFetched(department, employeeFG.getGroup("department"));
804
                rollbackTransaction(em);
749
            }
805
            }
806
            closeEntityManager(em);
750
        }
807
        }
751
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
752
    }
808
    }
753
809
754
   @Test
810
   @Test
Lines 786-899 Link Here
786
   @Test
842
   @Test
787
   public void simpleNestedFetchGroupWithBatch() {
843
   public void simpleNestedFetchGroupWithBatch() {
788
       EntityManager em = createEntityManager();
844
       EntityManager em = createEntityManager();
845
        try {
846
            beginTransaction(em);
789
847
790
       Query query = em.createQuery("SELECT e FROM Employee e");
848
            Query query = em.createQuery("SELECT e FROM Employee e");
791
849
792
       // Define the fields to be fetched on Employee
850
            // Define the fields to be fetched on Employee
793
       FetchGroup employeeFG = new FetchGroup();
851
            FetchGroup employeeFG = new FetchGroup();
794
       employeeFG.setShouldLoad(true);
852
            employeeFG.setShouldLoad(true);
795
       employeeFG.addAttribute("firstName");
853
            employeeFG.addAttribute("firstName");
796
       employeeFG.addAttribute("lastName");
854
            employeeFG.addAttribute("lastName");
797
       employeeFG.addAttribute("address.country");
855
            employeeFG.addAttribute("address.country");
798
       employeeFG.addAttribute("address.city");
856
            employeeFG.addAttribute("address.city");
799
       
857
            
800
       FetchGroup phonesFG = defaultPhoneFG.clone();
858
            FetchGroup phonesFG = defaultPhoneFG.clone();
801
       // to preclude PhoneNumber from triggering owner's full read
859
            // to preclude PhoneNumber from triggering owner's full read
802
       phonesFG.addAttribute("owner.id");
860
            phonesFG.addAttribute("owner.id");
803
       employeeFG.addAttribute("phoneNumbers", phonesFG);
861
            employeeFG.addAttribute("phoneNumbers", phonesFG);
804
       
862
            
805
       FetchGroup projectsFG = new FetchGroup("projects");
863
            FetchGroup projectsFG = new FetchGroup("projects");
806
       projectsFG.addAttribute("name");
864
            projectsFG.addAttribute("name");
807
       projectsFG.addAttribute("name");
865
            projectsFG.addAttribute("name");
808
       // to preclude Project from triggering full read of the referenced Employee(s)
866
            // to preclude Project from triggering full read of the referenced Employee(s)
809
       projectsFG.addAttribute("teamMembers.id");
867
            projectsFG.addAttribute("teamMembers.id");
810
       projectsFG.addAttribute("teamLeader.id");
868
            projectsFG.addAttribute("teamLeader.id");
811
       employeeFG.addAttribute("projects", projectsFG);
869
            employeeFG.addAttribute("projects", projectsFG);
812
870
813
       query.setHint(QueryHints.FETCH_GROUP, employeeFG);
871
            query.setHint(QueryHints.FETCH_GROUP, employeeFG);
814
       
872
            
815
       query.setHint(QueryHints.BATCH, "e.address");
873
            query.setHint(QueryHints.BATCH, "e.address");
816
       query.setHint(QueryHints.BATCH, "e.phoneNumbers");
874
            query.setHint(QueryHints.BATCH, "e.phoneNumbers");
817
       query.setHint(QueryHints.BATCH, "e.projects");
875
            query.setHint(QueryHints.BATCH, "e.projects");
818
       
876
            
819
       // A single sql will be used to read all Project subclasses.
877
            // A single sql will be used to read all Project subclasses.
820
       query.setHint(QueryHints.INHERITANCE_OUTER_JOIN, "true");
878
            query.setHint(QueryHints.INHERITANCE_OUTER_JOIN, "true");
821
879
822
       List<Employee> employees = query.getResultList();
880
            List<Employee> employees = query.getResultList();
823
881
824
       // Employee, Address, PhoneNumbers, Projects - an sql per class.
882
            // Employee, Address, PhoneNumbers, Projects - an sql per class.
825
       // Address, PhoneNumbers and Projects are already loaded because
883
            // Address, PhoneNumbers and Projects are already loaded because
826
       // employeeFG.shouldLoad is set to true.
884
            // employeeFG.shouldLoad is set to true.
827
       assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
885
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
828
       
886
            
829
       // verify fetch groups
887
            // verify fetch groups
830
       for(Employee emp : employees) {
888
            for(Employee emp : employees) {
831
           assertFetched(emp, employeeFG);
889
                assertFetched(emp, employeeFG);
832
890
833
           Address address = emp.getAddress();
891
                Address address = emp.getAddress();
834
           if(address != null) {
892
                if(address != null) {
835
               assertFetched(address, employeeFG.getGroup("address"));
893
                         assertFetched(address, employeeFG.getGroup("address"));
836
           }
894
                }
837
895
838
           for (PhoneNumber phone : emp.getPhoneNumbers()) {
896
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
839
               assertFetched(phone, phonesFG);
897
                         assertFetched(phone, phonesFG);
840
           }
898
                }
841
           
899
                
842
           for (Project project : emp.getProjects()) {
900
                for (Project project : emp.getProjects()) {
843
               assertFetched(project, projectsFG);
901
                         assertFetched(project, projectsFG);
844
           }
902
                }
845
       }
903
            }
846
904
847
       // Now let's access an attribute outside of the fetch group.
905
            // Now let's access an attribute outside of the fetch group.
848
       // That triggers loading of the whole object.
906
            // That triggers loading of the whole object.
849
       for(Employee emp : employees) {
907
            for(Employee emp : employees) {
850
           emp.getSalary();
908
                emp.getSalary();
851
           assertNoFetchGroup(emp);
909
                assertNoFetchGroup(emp);
852
910
853
           Address address = emp.getAddress();
911
                Address address = emp.getAddress();
854
           if(address != null) {
912
                if(address != null) {
855
               address.getStreet();
913
                   address.getStreet();
856
               assertNoFetchGroup(address);
914
                   assertNoFetchGroup(address);
857
           }
915
                }
858
916
859
           for (PhoneNumber phone : emp.getPhoneNumbers()) {
917
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
860
               phone.getAreaCode();
918
                    phone.getAreaCode();
861
               assertNoFetchGroup(phone);
919
                    assertNoFetchGroup(phone);
862
           }
920
                }
863
           
921
                
864
           for (Project project : emp.getProjects()) {
922
                for (Project project : emp.getProjects()) {
865
               project.getDescription();
923
                    project.getDescription();
866
               assertNoFetchGroup(project);
924
                    assertNoFetchGroup(project);
867
           }
925
                }
868
       }
926
            }
927
        } finally {
928
            if (isTransactionActive(em)){
929
                rollbackTransaction(em);
930
            }
931
            closeEntityManager(em);
932
        }
869
   }
933
   }
870
   
934
   
871
   @Test
935
   @Test
872
    public void simpleLoadGroup() {
936
    public void simpleLoadGroup() {
873
        EntityManager em = createEntityManager();
937
        EntityManager em = createEntityManager();
874
        
938
        try {
875
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
939
            beginTransaction(em);
876
        query.setParameter("GENDER", Gender.Female);        
877
        List<Employee> employees = query.getResultList();
878
        
879
        LoadGroup group = new LoadGroup();
880
        group.addAttribute("address");
881
        group.addAttribute("phoneNumbers");
882
        group.addAttribute("manager.projects");
883
        ((AbstractSession)((EntityManagerImpl)em.getDelegate()).getActiveSession()).load(employees, group);
884
940
885
        int numSelectBefore = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
941
             Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
886
        
942
             query.setParameter("GENDER", Gender.Female);
887
        // All indirections specified in the plan should have been already triggered.
943
             List<Employee> employees = query.getResultList();
888
        for(Employee emp : employees) {
944
             
889
            emp.getAddress();
945
             LoadGroup group = new LoadGroup();
890
            emp.getPhoneNumbers().size();
946
             group.addAttribute("address");
891
            if(emp.getManager() != null) {
947
             group.addAttribute("phoneNumbers");
892
                emp.getManager().getProjects().size();
948
             group.addAttribute("manager.projects");
949
             ((AbstractSession)((EntityManagerImpl)em.getDelegate()).getActiveSession()).load(employees, group);
950
951
             int numSelectBefore = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
952
             
953
             // All indirections specified in the plan should have been already triggered.
954
             for(Employee emp : employees) {
955
                 emp.getAddress();
956
                 emp.getPhoneNumbers().size();
957
                 if(emp.getManager() != null) {
958
                     emp.getManager().getProjects().size();
959
                 }
960
             }
961
             
962
             int numSelectAfter = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
963
             assertEquals(numSelectBefore, numSelectAfter);
964
        } finally {
965
            if (isTransactionActive(em)){
966
                rollbackTransaction(em);
893
            }
967
            }
968
            closeEntityManager(em);
894
        }
969
        }
895
        
896
        int numSelectAfter = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
897
        assertEquals(numSelectBefore, numSelectAfter);
898
    }
970
    }
899
}
971
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/NestedNamedFetchGroupTests.java (-145 / +169 lines)
Lines 83-144 Link Here
83
    @Test
83
    @Test
84
    public void dynamicFetchGroup_EmployeeAddress() throws Exception {
84
    public void dynamicFetchGroup_EmployeeAddress() throws Exception {
85
        EntityManager em = createEntityManager();
85
        EntityManager em = createEntityManager();
86
        try {
87
            beginTransaction(em);
86
88
87
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
89
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
88
        query.setParameter("GENDER", Gender.Male);
90
            query.setParameter("GENDER", Gender.Male);
89
91
90
        // Define the fields to be fetched on Employee
92
            // Define the fields to be fetched on Employee
91
        FetchGroup fg = new FetchGroup();
93
            FetchGroup fg = new FetchGroup();
92
        fg.addAttribute("firstName");
94
            fg.addAttribute("firstName");
93
        fg.addAttribute("lastName");
95
            fg.addAttribute("lastName");
94
        fg.addAttribute("address");
96
            fg.addAttribute("address");
95
        fg.addAttribute("address.city");
97
            fg.addAttribute("address.city");
96
        fg.addAttribute("address.postalCode");
98
            fg.addAttribute("address.postalCode");
97
99
98
        // Configure the dynamic FetchGroup
100
            // Configure the dynamic FetchGroup
99
        query.setHint(QueryHints.FETCH_GROUP, fg);
101
            query.setHint(QueryHints.FETCH_GROUP, fg);
100
102
101
        List<Employee> emps = query.getResultList();
103
            List<Employee> emps = query.getResultList();
102
104
103
        assertNotNull(emps);
105
            assertNotNull(emps);
104
        for (Employee emp : emps) {
106
            for (Employee emp : emps) {
105
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
107
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
106
108
107
            assertNotNull(tracker._persistence_getFetchGroup());
109
                assertNotNull(tracker._persistence_getFetchGroup());
108
110
109
            // Verify specified fields plus mandatory ones are loaded
111
                // Verify specified fields plus mandatory ones are loaded
110
            assertTrue(tracker._persistence_isAttributeFetched("id"));
112
                assertTrue(tracker._persistence_isAttributeFetched("id"));
111
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
113
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
112
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
114
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
113
            assertTrue(tracker._persistence_isAttributeFetched("version"));
115
                assertTrue(tracker._persistence_isAttributeFetched("version"));
114
116
115
            // Verify the other fields are not loaded
117
                // Verify the other fields are not loaded
116
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
118
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
117
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
119
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
118
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
120
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
119
121
120
            // Force the loading of lazy fields and verify
122
                // Force the loading of lazy fields and verify
121
            emp.getSalary();
123
                emp.getSalary();
122
124
123
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
125
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
124
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
126
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
125
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
127
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
126
128
127
            // Now we'll check the address uses the provided dynamic fetch-group
129
                // Now we'll check the address uses the provided dynamic fetch-group
128
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
130
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
129
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
131
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
130
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
132
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
131
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
133
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
132
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
134
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
133
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
135
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
134
136
135
            // Now we'll check the phoneNumbers use of the default fetch group
137
                // Now we'll check the phoneNumbers use of the default fetch group
136
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
138
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
137
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
139
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
138
                assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
140
                    assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
139
                assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
141
                    assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
140
                assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
142
                    assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
143
                }
141
            }
144
            }
145
        } finally {
146
            if (isTransactionActive(em)){
147
                rollbackTransaction(em);
148
            }
149
            closeEntityManager(em);
142
        }
150
        }
143
    }
151
    }
144
152
Lines 208-354 Link Here
208
    @Test
216
    @Test
209
    public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception {
217
    public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception {
210
        EntityManager em = createEntityManager();
218
        EntityManager em = createEntityManager();
219
        try {
220
            beginTransaction(em);
211
221
212
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
222
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
213
        query.setParameter("GENDER", Gender.Male);
223
            query.setParameter("GENDER", Gender.Male);
214
224
215
        // Define the fields to be fetched on Employee
225
            // Define the fields to be fetched on Employee
216
        FetchGroup empGroup = new FetchGroup();
226
            FetchGroup empGroup = new FetchGroup();
217
        empGroup.addAttribute("firstName");
227
            empGroup.addAttribute("firstName");
218
        empGroup.addAttribute("lastName");
228
            empGroup.addAttribute("lastName");
219
        empGroup.addAttribute("address");
229
            empGroup.addAttribute("address");
220
230
221
        // Define the fields to be fetched on Address
231
            // Define the fields to be fetched on Address
222
        FetchGroup addressGroup = new FetchGroup();
232
            FetchGroup addressGroup = new FetchGroup();
223
        addressGroup.addAttribute("city");
233
            addressGroup.addAttribute("city");
224
        addressGroup.addAttribute("postalCode");
234
            addressGroup.addAttribute("postalCode");
225
235
226
        empGroup.addAttribute("address", addressGroup);
236
            empGroup.addAttribute("address", addressGroup);
227
237
228
//        empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false);
238
            //empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false);
229
        FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
239
            FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
230
        // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
240
            // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
231
        fullPhone.addAttribute("owner.id");
241
            fullPhone.addAttribute("owner.id");
232
        empGroup.addAttribute("phoneNumbers", fullPhone);
242
            empGroup.addAttribute("phoneNumbers", fullPhone);
233
243
234
        // Configure the dynamic FetchGroup
244
            // Configure the dynamic FetchGroup
235
        query.setHint(QueryHints.FETCH_GROUP, empGroup);
245
            query.setHint(QueryHints.FETCH_GROUP, empGroup);
236
246
237
        List<Employee> emps = query.getResultList();
247
            List<Employee> emps = query.getResultList();
238
248
239
        assertNotNull(emps);
249
            assertNotNull(emps);
240
        for (Employee emp : emps) {
250
            for (Employee emp : emps) {
241
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
251
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
242
252
243
            assertNotNull(tracker._persistence_getFetchGroup());
253
                assertNotNull(tracker._persistence_getFetchGroup());
244
254
245
            // Verify specified fields plus mandatory ones are loaded
255
                // Verify specified fields plus mandatory ones are loaded
246
            assertTrue(tracker._persistence_isAttributeFetched("id"));
256
                assertTrue(tracker._persistence_isAttributeFetched("id"));
247
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
257
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
248
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
258
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
249
            assertTrue(tracker._persistence_isAttributeFetched("version"));
259
                assertTrue(tracker._persistence_isAttributeFetched("version"));
250
260
251
            // Verify the other fields are not loaded
261
                // Verify the other fields are not loaded
252
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
262
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
253
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
263
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
254
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
264
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
255
265
256
            // Force the loading of lazy fields and verify
266
                // Force the loading of lazy fields and verify
257
            emp.getSalary();
267
                emp.getSalary();
258
268
259
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
269
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
260
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
270
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
261
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
271
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
262
272
263
            // Now we'll check the address uses the provided dynamic fetch-group
273
                // Now we'll check the address uses the provided dynamic fetch-group
264
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
274
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
265
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
275
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
266
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
276
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
267
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
277
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
268
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
278
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
269
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
279
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
270
280
271
            // Now we'll check the phoneNumbers use of the default fetch group
281
                // Now we'll check the phoneNumbers use of the default fetch group
272
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
282
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
273
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
283
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
274
                assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup());
284
                    assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup());
285
                }
275
            }
286
            }
287
        } finally {
288
            if (isTransactionActive(em)){
289
                rollbackTransaction(em);
290
            }
291
            closeEntityManager(em);
276
        }
292
        }
277
    }
293
    }
278
294
279
    @Test
295
    @Test
280
    public void dynamicFetchGroup_EmployeeAddressEmptyPhone() throws Exception {
296
    public void dynamicFetchGroup_EmployeeAddressEmptyPhone() throws Exception {
281
        EntityManager em = createEntityManager();
297
        EntityManager em = createEntityManager();
298
        try {
299
            beginTransaction(em);
282
300
283
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
301
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
284
        query.setParameter("GENDER", Gender.Male);
302
            query.setParameter("GENDER", Gender.Male);
285
303
286
        // Define the fields to be fetched on Employee
304
            // Define the fields to be fetched on Employee
287
        FetchGroup empGroup = new FetchGroup();
305
            FetchGroup empGroup = new FetchGroup();
288
        empGroup.addAttribute("firstName");
306
            empGroup.addAttribute("firstName");
289
        empGroup.addAttribute("lastName");
307
            empGroup.addAttribute("lastName");
290
        empGroup.addAttribute("address");
308
            empGroup.addAttribute("address");
291
309
292
        // Define the fields to be fetched on Address
310
            // Define the fields to be fetched on Address
293
        FetchGroup addressGroup = new FetchGroup();
311
            FetchGroup addressGroup = new FetchGroup();
294
        addressGroup.addAttribute("city");
312
            addressGroup.addAttribute("city");
295
        addressGroup.addAttribute("postalCode");
313
            addressGroup.addAttribute("postalCode");
296
314
297
        empGroup.addAttribute("address", addressGroup);
315
            empGroup.addAttribute("address", addressGroup);
298
        // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
316
            // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
299
        FetchGroup ownerId = new FetchGroup();
317
            FetchGroup ownerId = new FetchGroup();
300
        ownerId.addAttribute("owner.id");
318
            ownerId.addAttribute("owner.id");
301
        empGroup.addAttribute("phoneNumbers", ownerId);
319
            empGroup.addAttribute("phoneNumbers", ownerId);
302
320
303
        // Configure the dynamic FetchGroup
321
            // Configure the dynamic FetchGroup
304
        query.setHint(QueryHints.FETCH_GROUP, empGroup);
322
            query.setHint(QueryHints.FETCH_GROUP, empGroup);
305
323
306
        List<Employee> emps = query.getResultList();
324
            List<Employee> emps = query.getResultList();
307
325
308
        assertNotNull(emps);
326
            assertNotNull(emps);
309
        for (Employee emp : emps) {
327
            for (Employee emp : emps) {
310
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
328
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
311
329
312
            assertNotNull(tracker._persistence_getFetchGroup());
330
                assertNotNull(tracker._persistence_getFetchGroup());
313
331
314
            // Verify specified fields plus mandatory ones are loaded
332
                // Verify specified fields plus mandatory ones are loaded
315
            assertTrue(tracker._persistence_isAttributeFetched("id"));
333
                assertTrue(tracker._persistence_isAttributeFetched("id"));
316
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
334
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
317
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
335
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
318
            assertTrue(tracker._persistence_isAttributeFetched("version"));
336
                assertTrue(tracker._persistence_isAttributeFetched("version"));
319
337
320
            // Verify the other fields are not loaded
338
                // Verify the other fields are not loaded
321
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
339
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
322
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
340
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
323
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
341
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
324
342
325
            // Force the loading of lazy fields and verify
343
                // Force the loading of lazy fields and verify
326
            emp.getSalary();
344
                emp.getSalary();
327
345
328
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
346
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
329
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
347
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
330
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
348
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
331
349
332
            // Now we'll check the address uses the provided dynamic fetch-group
350
                // Now we'll check the address uses the provided dynamic fetch-group
333
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
351
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
334
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
352
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
335
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
353
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
336
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
354
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
337
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
355
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
338
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
356
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
339
357
340
            // Now we'll check the phoneNumbers use of the default fetch group
358
                // Now we'll check the phoneNumbers use of the default fetch group
341
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
359
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
342
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
360
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
343
                assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
361
                    assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
344
                assertFalse(phoneTracker._persistence_isAttributeFetched("number"));
362
                    assertFalse(phoneTracker._persistence_isAttributeFetched("number"));
345
                assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
363
                    assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
346
364
347
                phone.getNumber();
365
                    phone.getNumber();
348
366
349
                assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
367
                    assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
350
                assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode"));
368
                    assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode"));
369
                }
351
            }
370
            }
371
        } finally {
372
            if (isTransactionActive(em)){
373
                rollbackTransaction(em);
374
            }
375
            closeEntityManager(em);
352
        }
376
        }
353
    }
377
    }
354
378
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleDefaultFetchGroupTests.java (-246 / +322 lines)
Lines 101-216 Link Here
101
    @Test
101
    @Test
102
    public void findDefaultFetchGroup() throws Exception {
102
    public void findDefaultFetchGroup() throws Exception {
103
        EntityManager em = createEntityManager();
103
        EntityManager em = createEntityManager();
104
        try {
105
            beginTransaction(em);
104
106
105
        Employee emp = minimumEmployee(em);
107
            Employee emp = minimumEmployee(em);
108
            assertNotNull(emp);
109
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
110
            assertDefaultFetched(emp);
106
111
107
        assertNotNull(emp);
112
            assertNotFetchedAttribute(emp, "salary");
108
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
113
            emp.getSalary();
109
        assertDefaultFetched(emp);
110
114
111
        assertNotFetchedAttribute(emp, "salary");
115
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
112
        emp.getSalary();
116
            assertFetchedAttribute(emp, "salary");
113
117
114
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
118
            assertNoFetchGroup(emp.getAddress());
115
        assertFetchedAttribute(emp, "salary");
116
119
117
        assertNoFetchGroup(emp.getAddress());
120
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
118
121
119
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
122
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
123
                assertDefaultFetched(phone);
124
            }
120
125
121
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
126
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
122
            assertDefaultFetched(phone);
123
        }
124
127
125
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
128
            if (emp.getManager() != null) {
126
129
                assertDefaultFetched(emp.getManager());
127
        if (emp.getManager() != null) {
130
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
128
            assertDefaultFetched(emp.getManager());
131
            } else {
129
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
132
                // If manager_id field is null then getManager() does not trigger an sql.
130
        } else {
133
                assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
131
            // If manager_id field is null then getManager() does not trigger an sql.
134
            }
132
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
135
        } finally {
136
            if (isTransactionActive(em)){
137
                rollbackTransaction(em);
138
            }
139
            closeEntityManager(em);
133
        }
140
        }
134
    }
141
    }
135
142
136
    @Test
143
    @Test
137
    public void singleResultDefaultFetchGroup() throws Exception {
144
    public void singleResultDefaultFetchGroup() throws Exception {
138
        EntityManager em = createEntityManager();
145
        EntityManager em = createEntityManager();
146
        try {
147
            beginTransaction(em);
139
148
140
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
149
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
141
        query.setParameter("ID", minimumEmployeeId(em));
150
            query.setParameter("ID", minimumEmployeeId(em));
142
151
143
        Employee emp = (Employee) query.getSingleResult();
152
            Employee emp = (Employee) query.getSingleResult();
144
153
145
        assertNotNull(emp);
154
            assertNotNull(emp);
146
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
155
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
147
156
148
        assertDefaultFetched(emp);
157
            assertDefaultFetched(emp);
149
158
150
        emp.getSalary();
159
            emp.getSalary();
151
160
152
        assertFetchedAttribute(emp, "salary");
161
            assertFetchedAttribute(emp, "salary");
153
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
162
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
154
163
155
        assertNoFetchGroup(emp.getAddress());
164
            assertNoFetchGroup(emp.getAddress());
156
165
157
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
166
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
158
167
159
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
168
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
160
            assertDefaultFetched(phone);
169
                assertDefaultFetched(phone);
161
        }
170
            }
162
171
163
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
172
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
164
173
165
        if (emp.getManager() != null) {
174
            if (emp.getManager() != null) {
166
            assertDefaultFetched(emp.getManager());
175
                assertDefaultFetched(emp.getManager());
167
            assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
176
                assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
168
        } else {
177
            } else {
169
            // If manager_id field is null then getManager() does not trigger an sql.
178
                // If manager_id field is null then getManager() does not trigger an sql.
170
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
179
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
180
            }
181
        } finally {
182
            if (isTransactionActive(em)){
183
                rollbackTransaction(em);
184
            }
185
            closeEntityManager(em);
171
        }
186
        }
172
173
    }
187
    }
174
188
175
    @Test
189
    @Test
176
    public void resultListDefaultFetchGroup() throws Exception {
190
    public void resultListDefaultFetchGroup() throws Exception {
177
        EntityManager em = createEntityManager();
191
        EntityManager em = createEntityManager();
192
        try {
193
            beginTransaction(em);
194
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
195
            query.setParameter("ID", minimumEmployeeId(em));
178
196
179
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
197
            List<Employee> emps = query.getResultList();
180
        query.setParameter("ID", minimumEmployeeId(em));
181
198
182
        List<Employee> emps = query.getResultList();
199
            assertNotNull(emps);
200
            assertEquals(1, emps.size());
183
201
184
        assertNotNull(emps);
202
            Employee emp = emps.get(0);
185
        assertEquals(1, emps.size());
186
203
187
        Employee emp = emps.get(0);
204
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
205
            assertDefaultFetched(emp);
188
206
189
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
207
            emp.getSalary();
190
        assertDefaultFetched(emp);
191
208
192
        emp.getSalary();
209
            assertNoFetchGroup(emp);
210
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
193
211
194
        assertNoFetchGroup(emp);
212
            assertNoFetchGroup(emp.getAddress());
195
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
196
213
197
        assertNoFetchGroup(emp.getAddress());
214
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
198
215
199
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
216
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
217
                assertDefaultFetched(phone);
218
            }
219
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
200
220
201
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
221
            if (emp.getManager() != null) {
202
            assertDefaultFetched(phone);
222
                assertDefaultFetched(emp.getManager());
223
                assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
224
            } else {
225
                // If manager_id field is null then getManager() does not trigger an sql.
226
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
227
            }
228
        } finally {
229
            if (isTransactionActive(em)){
230
                rollbackTransaction(em);
231
            }
232
            closeEntityManager(em);
203
        }
233
        }
204
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
205
206
        if (emp.getManager() != null) {
207
            assertDefaultFetched(emp.getManager());
208
            assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
209
        } else {
210
            // If manager_id field is null then getManager() does not trigger an sql.
211
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
212
        }
213
214
    }
234
    }
215
235
216
    @Test
236
    @Test
Lines 224-471 Link Here
224
    }
244
    }
225
    void internalResultListWithJoinFetchAddress(boolean addAddressToFetchGroup) {
245
    void internalResultListWithJoinFetchAddress(boolean addAddressToFetchGroup) {
226
        EntityManager em = createEntityManager();
246
        EntityManager em = createEntityManager();
247
        try {
248
            beginTransaction(em);
249
            Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id = :ID");
250
            query.setParameter("ID", minimumEmployeeId(em));
251
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
227
252
228
        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id = :ID");
253
            FetchGroup fg = null;
229
        query.setParameter("ID", minimumEmployeeId(em));
254
            if(addAddressToFetchGroup) {
230
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
255
                // that returns clone of the default fetch group
256
                fg = employeeDescriptor.getFetchGroupManager().createDefaultFetchGroup();
257
                fg.addAttribute("address");
258
                query.setHint(QueryHints.FETCH_GROUP, fg);
259
            }
260
            Employee emp = (Employee)query.getSingleResult();
261
            int nSql = 2;
262
            if(!addAddressToFetchGroup) {
263
                // An extra sql to read employee's Address - 
264
                // because address attribute is not in the fetch group the Address object was not built
265
                // by join fetch - though the db row for address was read in.
266
                //
267
                // yet another extra sql generated when the whole employee object is read when address is set. 
268
                nSql = nSql + 2;
269
            }
231
270
232
        FetchGroup fg = null;
271
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
233
        if(addAddressToFetchGroup) {
272
            if(addAddressToFetchGroup) {
234
            // that returns clone of the default fetch group
273
                assertFetched(emp, fg);
235
            fg = employeeDescriptor.getFetchGroupManager().createDefaultFetchGroup();
274
            } else {
236
            fg.addAttribute("address");
275
                // the whole object has been instantiated when address has been set 
237
            query.setHint(QueryHints.FETCH_GROUP, fg);
276
                assertNoFetchGroup(emp);
238
        }
277
            }
239
        Employee emp = (Employee)query.getSingleResult();
240
        int nSql = 2;
241
        if(!addAddressToFetchGroup) {
242
            // An extra sql to read employee's Address - 
243
            // because address attribute is not in the fetch group the Address object was not built
244
            // by join fetch - though the db row for address was read in.
245
            //
246
            // yet another extra sql generated when the whole employee object is read when address is set. 
247
            nSql = nSql + 2;
248
        }
249
278
250
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
279
            // instantiates the whole object - unless already instantiated
251
        if(addAddressToFetchGroup) {
280
            emp.getSalary();
252
            assertFetched(emp, fg);
281
253
        } else {
254
            // the whole object has been instantiated when address has been set 
255
            assertNoFetchGroup(emp);
282
            assertNoFetchGroup(emp);
256
        }
283
            if(addAddressToFetchGroup) {
284
                nSql++;
285
            }
286
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
257
287
258
        // instantiates the whole object - unless already instantiated
288
            assertNoFetchGroup(emp.getAddress());
259
        emp.getSalary();
289
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
260
290
261
        assertNoFetchGroup(emp);
291
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
262
        if(addAddressToFetchGroup) {
292
                assertDefaultFetched(phone);
263
            nSql++;
293
            }
264
        }
294
            assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
265
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
266
295
267
        assertNoFetchGroup(emp.getAddress());
296
            if (emp.getManager() != null) {
268
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
297
                assertDefaultFetched(emp.getManager());
269
298
                assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
270
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
299
            } else {
271
            assertDefaultFetched(phone);
300
                // If manager_id field is null then getManager() does not trigger an sql.
301
                assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
302
            }
303
        } finally {
304
            if (isTransactionActive(em)){
305
                rollbackTransaction(em);
306
            }
307
            closeEntityManager(em);
272
        }
308
        }
273
        assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
274
275
        if (emp.getManager() != null) {
276
            assertDefaultFetched(emp.getManager());
277
            assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
278
        } else {
279
            // If manager_id field is null then getManager() does not trigger an sql.
280
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
281
        }
282
    }
309
    }
283
310
284
    @Test
311
    @Test
285
    public void singleResultNoFetchGroup() throws Exception {
312
    public void singleResultNoFetchGroup() throws Exception {
286
        EntityManager em = createEntityManager();
313
        EntityManager em = createEntityManager();
314
        try {
315
            beginTransaction(em);
287
316
288
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
317
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
289
        query.setParameter("ID", minimumEmployeeId(em));
318
            query.setParameter("ID", minimumEmployeeId(em));
290
319
291
        assertNull(getFetchGroup(query));
320
            assertNull(getFetchGroup(query));
292
        assertNotNull(employeeDescriptor.getFetchGroupManager().getDefaultFetchGroup());
321
            assertNotNull(employeeDescriptor.getFetchGroupManager().getDefaultFetchGroup());
293
322
294
        query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false");
323
            query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false");
295
        assertNull(getFetchGroup(query));
324
            assertNull(getFetchGroup(query));
296
325
297
        Employee emp = (Employee) query.getSingleResult();
326
            Employee emp = (Employee) query.getSingleResult();
298
327
299
        assertNotNull(emp);
328
            assertNotNull(emp);
300
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
329
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
301
        assertNoFetchGroup(emp);
330
            assertNoFetchGroup(emp);
302
        assertNoFetchGroup(emp.getAddress());
331
            assertNoFetchGroup(emp.getAddress());
303
332
304
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
333
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
305
334
306
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
335
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
307
            assertDefaultFetched(phone);
336
                assertDefaultFetched(phone);
337
            }
338
339
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
340
341
        } finally {
342
            if (isTransactionActive(em)){
343
                rollbackTransaction(em);
344
            }
345
            closeEntityManager(em);
308
        }
346
        }
309
310
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
311
    }
347
    }
312
348
313
    @Test
349
    @Test
314
    public void resultListNoFetchGroup() throws Exception {
350
    public void resultListNoFetchGroup() throws Exception {
315
        EntityManager em = createEntityManager();
351
        EntityManager em = createEntityManager();
352
        try {
353
            beginTransaction(em);
316
354
317
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
355
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
318
        query.setParameter("ID", minimumEmployeeId(em));
356
            query.setParameter("ID", minimumEmployeeId(em));
319
        query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false");
357
            query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false");
320
358
321
        List<Employee> emps = query.getResultList();
359
            List<Employee> emps = query.getResultList();
322
360
323
        assertNotNull(emps);
361
            assertNotNull(emps);
324
        assertEquals(1, emps.size());
362
            assertEquals(1, emps.size());
325
363
326
        Employee emp = emps.get(0);
364
            Employee emp = emps.get(0);
327
365
328
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
366
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
329
367
330
        assertNoFetchGroup(emp);
368
            assertNoFetchGroup(emp);
331
        assertNoFetchGroup(emp.getAddress());
369
            assertNoFetchGroup(emp.getAddress());
332
370
333
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
371
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
334
372
335
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
373
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
336
            assertDefaultFetched(phone);
374
                assertDefaultFetched(phone);
375
            }
376
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
377
        } finally {
378
            if (isTransactionActive(em)){
379
                rollbackTransaction(em);
380
            }
381
            closeEntityManager(em);
337
        }
382
        }
338
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
339
    }
383
    }
340
384
341
    @Test
385
    @Test
342
    public void emptyFetchGroup() throws Exception {
386
    public void emptyFetchGroup() throws Exception {
343
        EntityManager em = createEntityManager();
387
        EntityManager em = createEntityManager();
388
        try {
389
            beginTransaction(em);
344
390
345
        // Use q query since find will only use default fetch group
391
            // Use q query since find will only use default fetch group
346
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
392
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
347
        query.setParameter("ID", minimumEmployeeId(em));
393
            query.setParameter("ID", minimumEmployeeId(em));
348
        FetchGroup emptyFG = new FetchGroup("empty@" + System.currentTimeMillis());
394
            FetchGroup emptyFG = new FetchGroup("empty@" + System.currentTimeMillis());
349
        query.setHint(QueryHints.FETCH_GROUP, emptyFG);
395
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);
350
396
351
        assertEquals(emptyFG, getFetchGroup(query));
397
            assertEquals(emptyFG, getFetchGroup(query));
352
398
353
        Employee emp = (Employee) query.getSingleResult();
399
            Employee emp = (Employee) query.getSingleResult();
354
400
355
        assertFetched(emp, emptyFG);
401
            assertFetched(emp, emptyFG);
356
402
357
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
403
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
358
            assertDefaultFetched(phone);
404
                assertDefaultFetched(phone);
359
            phone.getAreaCode();
405
                phone.getAreaCode();
360
            assertNoFetchGroup(phone);
406
                assertNoFetchGroup(phone);
407
            }
408
        } finally {
409
            if (isTransactionActive(em)){
410
                rollbackTransaction(em);
411
            }
412
            closeEntityManager(em);
361
        }
413
        }
362
    }
414
    }
363
415
364
    @Test
416
    @Test
365
    public void managerFetchGroup() throws Exception {
417
    public void managerFetchGroup() throws Exception {
366
        EntityManager em = createEntityManager();
418
        EntityManager em = createEntityManager();
419
        try {
420
            beginTransaction(em);
367
421
368
        // Use q query since find will only use default fetch group
422
            //Use q query since find will only use default fetch group
369
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
423
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
370
//        query.setParameter("ID", minimumEmployeeId(em));
424
            //query.setParameter("ID", minimumEmployeeId(em));
371
        
425
            
372
        // Complex where clause used to avoid triggering employees and their departments:
426
            //Complex where clause used to avoid triggering employees and their departments:
373
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
427
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
374
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
428
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
375
        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");
429
            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");
376
        FetchGroup managerFG = new FetchGroup();
430
            FetchGroup managerFG = new FetchGroup();
377
        managerFG.addAttribute("manager");
431
            managerFG.addAttribute("manager");
378
432
379
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
433
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
380
        query.setHint(QueryHints.LEFT_FETCH, "e.manager");
434
            query.setHint(QueryHints.LEFT_FETCH, "e.manager");
381
435
382
        assertEquals(managerFG, getFetchGroup(query));
436
            assertEquals(managerFG, getFetchGroup(query));
383
437
384
        List employees = query.getResultList();
438
            List employees = query.getResultList();
385
        Employee emp = (Employee)employees.get(0);
439
            Employee emp = (Employee)employees.get(0);
386
440
387
        assertFetched(emp, managerFG);
441
            assertFetched(emp, managerFG);
388
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
442
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
389
443
390
        emp.getManager();
444
            emp.getManager();
391
445
392
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
446
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
393
        assertFetched(emp, managerFG);
447
            assertFetched(emp, managerFG);
394
448
395
        emp.getLastName();
449
            emp.getLastName();
396
450
397
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
451
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
398
        assertNoFetchGroup(emp);
452
            assertNoFetchGroup(emp);
399
453
400
        int numPhones = 0;
454
            int numPhones = 0;
401
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
455
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
402
            assertDefaultFetched(phone);
456
                assertDefaultFetched(phone);
403
457
404
            phone.getAreaCode();
458
                phone.getAreaCode();
405
459
406
            assertNoFetchGroup(phone);
460
                assertNoFetchGroup(phone);
407
            numPhones++;
461
                numPhones++;
462
            }
463
            // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group
464
            assertEquals(3 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
465
        } finally {
466
            if (isTransactionActive(em)){
467
                rollbackTransaction(em);
468
            }
469
            closeEntityManager(em);
408
        }
470
        }
409
        // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group
410
        assertEquals(3 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
411
    }
471
    }
412
472
413
    @Test
473
    @Test
414
    public void employeeNamesFetchGroup() throws Exception {
474
    public void employeeNamesFetchGroup() throws Exception {
415
        EntityManager em = createEntityManager();
475
        EntityManager em = createEntityManager();
476
        try {
477
            beginTransaction(em);
416
478
417
        int minId = minimumEmployeeId(em);
479
            int minId = minimumEmployeeId(em);
418
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
480
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
419
481
420
        // Use q query since find will only use default fetch group
482
            // Use q query since find will only use default fetch group
421
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
483
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
422
        query.setParameter("ID", minId);
484
            query.setParameter("ID", minId);
423
485
424
        FetchGroup namesFG = new FetchGroup();
486
            FetchGroup namesFG = new FetchGroup();
425
        namesFG.addAttribute("firstName");
487
            namesFG.addAttribute("firstName");
426
        namesFG.addAttribute("lastName");
488
            namesFG.addAttribute("lastName");
427
        query.setHint(QueryHints.FETCH_GROUP, namesFG);
489
            query.setHint(QueryHints.FETCH_GROUP, namesFG);
428
490
429
        assertNotNull(getFetchGroup(query));
491
            assertNotNull(getFetchGroup(query));
430
        assertSame(namesFG, getFetchGroup(query));
492
            assertSame(namesFG, getFetchGroup(query));
431
493
432
        Employee emp = (Employee) query.getSingleResult();
494
            Employee emp = (Employee) query.getSingleResult();
433
495
434
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
496
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
435
        assertFetched(emp, namesFG);
497
            assertFetched(emp, namesFG);
436
498
437
        emp.getId();
499
            emp.getId();
438
        emp.getFirstName();
500
            emp.getFirstName();
439
        emp.getLastName();
501
            emp.getLastName();
440
        emp.getVersion();
502
            emp.getVersion();
441
503
442
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
504
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
443
        assertFetched(emp, namesFG);
505
            assertFetched(emp, namesFG);
444
506
445
        emp.getGender();
507
            emp.getGender();
446
        emp.getSalary();
508
            emp.getSalary();
447
509
448
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
510
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
449
        assertNoFetchGroup(emp);
511
            assertNoFetchGroup(emp);
450
512
451
        int numPhones = 0;
513
            int numPhones = 0;
452
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
514
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
453
            assertDefaultFetched(phone);
515
                assertDefaultFetched(phone);
454
516
455
            phone.getAreaCode();
517
                phone.getAreaCode();
456
518
457
            assertNoFetchGroup(phone);
519
                assertNoFetchGroup(phone);
458
            numPhones++;
520
                numPhones++;
459
        }
521
            }
460
        // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group
522
            // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group
461
        assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
523
            assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
462
524
463
        if(emp.getManager() != null) {
525
            if(emp.getManager() != null) {
464
            assertEquals(5 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
526
                assertEquals(5 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
465
            assertDefaultFetched(emp.getManager());
527
                assertDefaultFetched(emp.getManager());
466
        } else {
528
            } else {
467
            // If manager_id field is null then getManager() does not trigger an sql.
529
                // If manager_id field is null then getManager() does not trigger an sql.
468
            assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
530
                assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
531
            }
532
        } finally {
533
            if (isTransactionActive(em)){
534
                rollbackTransaction(em);
535
            }
536
            closeEntityManager(em);
469
        }
537
        }
470
    }
538
    }
471
539
Lines 553-585 Link Here
553
    }
621
    }
554
    void internalJoinFetchEmployeeAddressPhoneWithDynamicFetchGroup(boolean addAddressToFetchGroup) {
622
    void internalJoinFetchEmployeeAddressPhoneWithDynamicFetchGroup(boolean addAddressToFetchGroup) {
555
        EntityManager em = createEntityManager();
623
        EntityManager em = createEntityManager();
624
        try {
625
            beginTransaction(em);
556
626
557
        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.id FROM PhoneNumber p)");
627
            Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.id FROM PhoneNumber p)");
558
628
559
        FetchGroup fetchGroup = new FetchGroup("names");
629
            FetchGroup fetchGroup = new FetchGroup("names");
560
        fetchGroup.addAttribute("firstName");
630
            fetchGroup.addAttribute("firstName");
561
        fetchGroup.addAttribute("lastName");
631
            fetchGroup.addAttribute("lastName");
562
        if(addAddressToFetchGroup) {
632
            if(addAddressToFetchGroup) {
563
            fetchGroup.addAttribute("address");
633
                fetchGroup.addAttribute("address");
564
        }
634
            }
565
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
635
            query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
566
636
567
        List<Employee> emps = query.getResultList();
637
            List<Employee> emps = query.getResultList();
568
        assertNotNull(emps);
638
            assertNotNull(emps);
569
639
570
        if(addAddressToFetchGroup) {
571
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
572
        } else {
573
            assertEquals(1 + 2*emps.size(), getQuerySQLTracker(em).getTotalSQLSELECTCalls());
574
        }
575
        for (Employee emp : emps) {
576
            if(addAddressToFetchGroup) {
640
            if(addAddressToFetchGroup) {
577
                assertFetched(emp, fetchGroup);
641
                assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
578
            } else {
642
            } else {
579
                // the whole object has been instantiated when address has been set 
643
                assertEquals(1 + 2*emps.size(), getQuerySQLTracker(em).getTotalSQLSELECTCalls());
580
                assertNoFetchGroup(emp);
581
            }
644
            }
645
            for (Employee emp : emps) {
646
                if(addAddressToFetchGroup) {
647
                    assertFetched(emp, fetchGroup);
648
                } else {
649
                    // the whole object has been instantiated when address has been set 
650
                    assertNoFetchGroup(emp);
651
                }
582
        }
652
        }
653
        } finally {
654
            if (isTransactionActive(em)){
655
                rollbackTransaction(em);
656
            }
657
            closeEntityManager(em);
658
        }
583
    }
659
    }
584
660
585
    public static class EmployeeCustomizer implements DescriptorCustomizer {
661
    public static class EmployeeCustomizer implements DescriptorCustomizer {
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleFetchGroupTests.java (-337 / +418 lines)
Lines 55-62 Link Here
55
        suite.addTest(new SimpleFetchGroupTests("findNoFetchGroup"));
55
        suite.addTest(new SimpleFetchGroupTests("findNoFetchGroup"));
56
        suite.addTest(new SimpleFetchGroupTests("singleResultNoFetchGroup"));
56
        suite.addTest(new SimpleFetchGroupTests("singleResultNoFetchGroup"));
57
        suite.addTest(new SimpleFetchGroupTests("resultListNoFetchGroup"));
57
        suite.addTest(new SimpleFetchGroupTests("resultListNoFetchGroup"));
58
        suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup"));
59
        suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary"));
60
        suite.addTest(new SimpleFetchGroupTests("singleResultEmptyFetchGroup"));
58
        suite.addTest(new SimpleFetchGroupTests("singleResultEmptyFetchGroup"));
61
        suite.addTest(new SimpleFetchGroupTests("resultListEmptyFetchGroup"));
59
        suite.addTest(new SimpleFetchGroupTests("resultListEmptyFetchGroup"));
62
        suite.addTest(new SimpleFetchGroupTests("resultListPeriodFetchGroup"));
60
        suite.addTest(new SimpleFetchGroupTests("resultListPeriodFetchGroup"));
Lines 65-75 Link Here
65
        suite.addTest(new SimpleFetchGroupTests("employeeNamesFetchGroup"));
63
        suite.addTest(new SimpleFetchGroupTests("employeeNamesFetchGroup"));
66
        suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
64
        suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
67
        suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
65
        suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
68
        suite.addTest(new SimpleFetchGroupTests("verifyUnfetchedAttributes"));
69
        suite.addTest(new SimpleFetchGroupTests("verifyFetchedRelationshipAttributes"));
66
        suite.addTest(new SimpleFetchGroupTests("verifyFetchedRelationshipAttributes"));
70
        suite.addTest(new SimpleFetchGroupTests("detachedByClosingEntityManagerObjectWithFetchGroup"));
67
        suite.addTest(new SimpleFetchGroupTests("detachedByClosingEntityManagerObjectWithFetchGroup"));
71
        suite.addTest(new SimpleFetchGroupTests("explicitlyDetachedObjectWithFetchGroup"));
68
        if (!isJPA10()) {
72
        
69
            suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup"));
70
            suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary"));
71
            suite.addTest(new SimpleFetchGroupTests("verifyUnfetchedAttributes"));
72
            suite.addTest(new SimpleFetchGroupTests("explicitlyDetachedObjectWithFetchGroup"));
73
        }
73
        return suite;
74
        return suite;
74
    }
75
    }
75
    
76
    
Lines 176-352 Link Here
176
    @Test
177
    @Test
177
    public void findEmptyFetchGroup() throws Exception {
178
    public void findEmptyFetchGroup() throws Exception {
178
        EntityManager em = createEntityManager();
179
        EntityManager em = createEntityManager();
179
        int minId = minimumEmployeeId(em);
180
        try {
181
            beginTransaction(em);
180
182
181
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
183
            int minId = minimumEmployeeId(em);
182
184
183
        Map<String, Object> properties = new HashMap<String, Object>();
185
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
184
        FetchGroup emptyFG = new FetchGroup();
185
        properties.put(QueryHints.FETCH_GROUP, emptyFG);
186
186
187
        Employee emp = em.find(Employee.class, minId, properties);
187
            Map<String, Object> properties = new HashMap<String, Object>();
188
            FetchGroup emptyFG = new FetchGroup();
189
            properties.put(QueryHints.FETCH_GROUP, emptyFG);
188
190
189
        assertNotNull(emp);
191
            Employee emp = em.find(Employee.class, minId, properties);
190
        assertFetched(emp, emptyFG);
191
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
192
192
193
        // Check Basics
193
            assertNotNull(emp);
194
        assertFetchedAttribute(emp, "id");
194
            assertFetched(emp, emptyFG);
195
        assertFetchedAttribute(emp, "version");
195
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
196
        assertNotFetchedAttribute(emp, "firstName");
197
        assertNotFetchedAttribute(emp, "lastName");
198
        assertNotFetchedAttribute(emp, "gender");
199
        assertNotFetchedAttribute(emp, "salary");
200
        assertNotFetchedAttribute(emp, "startTime");
201
        assertNotFetchedAttribute(emp, "endTime");
202
        if (emp.getPeriod() != null) {
203
            assertFetchedAttribute(emp.getPeriod(), "startDate");
204
            assertFetchedAttribute(emp.getPeriod(), "endDate");
205
        }
206
196
207
        // Check Relationships
197
            // Check Basics
208
        assertNotFetchedAttribute(emp, "address");
198
            assertFetchedAttribute(emp, "id");
209
        assertNotFetchedAttribute(emp, "manager");
199
            assertFetchedAttribute(emp, "version");
210
        assertNotFetchedAttribute(emp, "phoneNumbers");
200
            assertNotFetchedAttribute(emp, "firstName");
211
        assertNotFetchedAttribute(emp, "projects");
201
            assertNotFetchedAttribute(emp, "lastName");
202
            assertNotFetchedAttribute(emp, "gender");
203
            assertNotFetchedAttribute(emp, "salary");
204
            assertNotFetchedAttribute(emp, "startTime");
205
            assertNotFetchedAttribute(emp, "endTime");
206
            if (emp.getPeriod() != null) {
207
                assertFetchedAttribute(emp.getPeriod(), "startDate");
208
                assertFetchedAttribute(emp.getPeriod(), "endDate");
209
            }
212
210
213
        emp.getSalary();
211
            // Check Relationships
212
            assertNotFetchedAttribute(emp, "address");
213
            assertNotFetchedAttribute(emp, "manager");
214
            assertNotFetchedAttribute(emp, "phoneNumbers");
215
            assertNotFetchedAttribute(emp, "projects");
214
216
215
        assertFetchedAttribute(emp, "salary");
217
            emp.getSalary();
216
218
217
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
219
            assertFetchedAttribute(emp, "salary");
218
        assertNoFetchGroup(emp);
219
220
220
        emp.getAddress();
221
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
222
            assertNoFetchGroup(emp);
221
223
222
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
224
            emp.getAddress();
223
        assertNoFetchGroup(emp.getAddress());
224
225
225
        emp.getPhoneNumbers().size();
226
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
227
            assertNoFetchGroup(emp.getAddress());
226
228
227
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
229
            emp.getPhoneNumbers().size();
228
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
229
            assertNoFetchGroup(phone);
230
        }
231
230
232
        if (emp.getManager() != null) {
233
            assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
234
        } else {
235
            // If manager_id field is null then getManager() does not trigger an sql.
236
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
231
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
232
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
233
                assertNoFetchGroup(phone);
234
            }
235
236
            if (emp.getManager() != null) {
237
                assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
238
            } else {
239
                // If manager_id field is null then getManager() does not trigger an sql.
240
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
241
            } 
242
        }finally {
243
            if (isTransactionActive(em)){
244
                rollbackTransaction(em);
245
            }
246
            closeEntityManager(em);
237
        }
247
        }
238
    }
248
    }
239
249
240
    @Test
250
    @Test
241
    public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception {
251
    public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception {
242
        EntityManager em = createEntityManager();
252
        EntityManager em = createEntityManager();
243
        int minId = minimumEmployeeId(em);
253
        try {
254
            beginTransaction(em);
244
255
245
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
256
            int minId = minimumEmployeeId(em);
246
257
247
        Map<String, Object> properties = new HashMap<String, Object>();
258
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
248
        FetchGroup emptyFG = new FetchGroup();
249
        properties.put(QueryHints.FETCH_GROUP, emptyFG);
250
259
251
        Employee emp = em.find(Employee.class, minId, properties);
260
            Map<String, Object> properties = new HashMap<String, Object>();
261
            FetchGroup emptyFG = new FetchGroup();
262
            properties.put(QueryHints.FETCH_GROUP, emptyFG);
252
263
253
        assertNotNull(emp);
264
            Employee emp = em.find(Employee.class, minId, properties);
254
        assertFetched(emp, emptyFG);
255
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
256
265
257
        // Check Basics
266
            assertNotNull(emp);
258
        assertFetchedAttribute(emp, "id");
267
            assertFetched(emp, emptyFG);
259
        assertFetchedAttribute(emp, "version");
268
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
260
        assertNotFetchedAttribute(emp, "firstName");
261
        assertNotFetchedAttribute(emp, "lastName");
262
        assertNotFetchedAttribute(emp, "gender");
263
        assertNotFetchedAttribute(emp, "salary");
264
        assertNotFetchedAttribute(emp, "startTime");
265
        assertNotFetchedAttribute(emp, "endTime");
266
        if (emp.getPeriod() != null) {
267
            assertFetchedAttribute(emp.getPeriod(), "startDate");
268
            assertFetchedAttribute(emp.getPeriod(), "endDate");
269
        }
270
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
271
269
272
        // Check Relationships
270
            // Check Basics
273
        assertNotFetchedAttribute(emp, "address");
271
            assertFetchedAttribute(emp, "id");
274
        assertNotFetchedAttribute(emp, "manager");
272
            assertFetchedAttribute(emp, "version");
275
        assertNotFetchedAttribute(emp, "phoneNumbers");
273
            assertNotFetchedAttribute(emp, "firstName");
276
        assertNotFetchedAttribute(emp, "projects");
274
            assertNotFetchedAttribute(emp, "lastName");
275
            assertNotFetchedAttribute(emp, "gender");
276
            assertNotFetchedAttribute(emp, "salary");
277
            assertNotFetchedAttribute(emp, "startTime");
278
            assertNotFetchedAttribute(emp, "endTime");
279
            if (emp.getPeriod() != null) {
280
                assertFetchedAttribute(emp.getPeriod(), "startDate");
281
                assertFetchedAttribute(emp.getPeriod(), "endDate");
282
            }
283
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
277
284
278
        emp.setSalary(1);
285
            // Check Relationships
286
            assertNotFetchedAttribute(emp, "address");
287
            assertNotFetchedAttribute(emp, "manager");
288
            assertNotFetchedAttribute(emp, "phoneNumbers");
289
            assertNotFetchedAttribute(emp, "projects");
279
290
280
        assertFetchedAttribute(emp, "salary");
291
            emp.setSalary(1);
281
292
282
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
293
            assertFetchedAttribute(emp, "salary");
283
        assertNoFetchGroup(emp);
284
294
285
        emp.getAddress();
295
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
296
            assertNoFetchGroup(emp);
286
297
287
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
298
            emp.getAddress();
288
        assertNoFetchGroup(emp.getAddress());
289
299
290
        emp.getPhoneNumbers().size();
300
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
301
            assertNoFetchGroup(emp.getAddress());
291
302
292
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
303
            emp.getPhoneNumbers().size();
293
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
304
294
            assertNoFetchGroup(phone);
305
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
306
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
307
                assertNoFetchGroup(phone);
308
            }
309
        } finally {
310
            if (isTransactionActive(em)){
311
                rollbackTransaction(em);
312
            }
313
            closeEntityManager(em);
295
        }
314
        }
296
    }
315
    }
297
316
298
    @Test
317
    @Test
299
    public void singleResultEmptyFetchGroup() throws Exception {
318
    public void singleResultEmptyFetchGroup() throws Exception {
300
        EntityManager em = createEntityManager();
319
        EntityManager em = createEntityManager();
320
        try {
321
            beginTransaction(em);
301
322
302
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
323
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
303
        query.setParameter("ID", minimumEmployeeId(em));
324
            query.setParameter("ID", minimumEmployeeId(em));
304
        FetchGroup emptyFG = new FetchGroup();
325
            FetchGroup emptyFG = new FetchGroup();
305
        query.setHint(QueryHints.FETCH_GROUP, emptyFG);
326
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);
306
327
307
        Employee emp = (Employee) query.getSingleResult();
328
            Employee emp = (Employee) query.getSingleResult();
308
329
309
        assertNotNull(emp);
330
            assertNotNull(emp);
310
        assertFetched(emp, emptyFG);
331
            assertFetched(emp, emptyFG);
311
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
332
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
312
333
313
        // Check Basics
334
            // Check Basics
314
        assertFetchedAttribute(emp, "id");
335
            assertFetchedAttribute(emp, "id");
315
        assertFetchedAttribute(emp, "version");
336
            assertFetchedAttribute(emp, "version");
316
        assertNotFetchedAttribute(emp, "firstName");
337
            assertNotFetchedAttribute(emp, "firstName");
317
        assertNotFetchedAttribute(emp, "lastName");
338
            assertNotFetchedAttribute(emp, "lastName");
318
        assertNotFetchedAttribute(emp, "gender");
339
            assertNotFetchedAttribute(emp, "gender");
319
        assertNotFetchedAttribute(emp, "salary");
340
            assertNotFetchedAttribute(emp, "salary");
320
        assertNotFetchedAttribute(emp, "startTime");
341
            assertNotFetchedAttribute(emp, "startTime");
321
        assertNotFetchedAttribute(emp, "endTime");
342
            assertNotFetchedAttribute(emp, "endTime");
322
        if (emp.getPeriod() != null) {
343
            if (emp.getPeriod() != null) {
323
            assertFetchedAttribute(emp.getPeriod(), "startDate");
344
                assertFetchedAttribute(emp.getPeriod(), "startDate");
324
            assertFetchedAttribute(emp.getPeriod(), "endDate");
345
                assertFetchedAttribute(emp.getPeriod(), "endDate");
325
        }
346
            }
326
347
327
        // Check Relationships
348
            // Check Relationships
328
        assertNotFetchedAttribute(emp, "address");
349
            assertNotFetchedAttribute(emp, "address");
329
        assertNotFetchedAttribute(emp, "manager");
350
            assertNotFetchedAttribute(emp, "manager");
330
        assertNotFetchedAttribute(emp, "phoneNumbers");
351
            assertNotFetchedAttribute(emp, "phoneNumbers");
331
        assertNotFetchedAttribute(emp, "projects");
352
            assertNotFetchedAttribute(emp, "projects");
332
353
333
        emp.getSalary();
354
            emp.getSalary();
334
355
335
        assertFetchedAttribute(emp, "salary");
356
            assertFetchedAttribute(emp, "salary");
336
357
337
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
358
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
338
        assertNoFetchGroup(emp);
359
            assertNoFetchGroup(emp);
339
360
340
        emp.getAddress();
361
            emp.getAddress();
341
362
342
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
363
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
343
        assertNoFetchGroup(emp.getAddress());
364
            assertNoFetchGroup(emp.getAddress());
344
365
345
        emp.getPhoneNumbers().size();
366
            emp.getPhoneNumbers().size();
346
367
347
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
368
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
348
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
369
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
349
            assertNoFetchGroup(phone);
370
                assertNoFetchGroup(phone);
371
            }
372
        } finally {
373
            if (isTransactionActive(em)){
374
                rollbackTransaction(em);
375
            }
376
            closeEntityManager(em);
350
        }
377
        }
351
    }
378
    }
352
379
Lines 356-414 Link Here
356
    @Test
383
    @Test
357
    public void resultListEmptyFetchGroup() throws Exception {
384
    public void resultListEmptyFetchGroup() throws Exception {
358
        EntityManager em = createEntityManager();
385
        EntityManager em = createEntityManager();
386
        try {
387
            beginTransaction(em);
359
388
360
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
389
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
361
        query.setParameter("ID", minimumEmployeeId(em));
390
            query.setParameter("ID", minimumEmployeeId(em));
362
        FetchGroup emptyFG = new FetchGroup();
391
            FetchGroup emptyFG = new FetchGroup();
363
        query.setHint(QueryHints.FETCH_GROUP, emptyFG);
392
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);
364
393
365
        List<Employee> emps = query.getResultList();
394
            List<Employee> emps = query.getResultList();
366
395
367
        assertNotNull(emps);
396
            assertNotNull(emps);
368
        assertEquals(1, emps.size());
397
            assertEquals(1, emps.size());
369
398
370
        Employee emp = emps.get(0);
399
            Employee emp = emps.get(0);
371
400
372
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
401
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
373
        assertFetched(emp, emptyFG);
402
            assertFetched(emp, emptyFG);
374
403
375
        // Check Basics
404
            // Check Basics
376
        assertFetchedAttribute(emp, "id");
405
            assertFetchedAttribute(emp, "id");
377
        assertFetchedAttribute(emp, "version");
406
            assertFetchedAttribute(emp, "version");
378
        assertNotFetchedAttribute(emp, "firstName");
407
            assertNotFetchedAttribute(emp, "firstName");
379
        assertNotFetchedAttribute(emp, "lastName");
408
            assertNotFetchedAttribute(emp, "lastName");
380
        assertNotFetchedAttribute(emp, "gender");
409
            assertNotFetchedAttribute(emp, "gender");
381
        assertNotFetchedAttribute(emp, "salary");
410
            assertNotFetchedAttribute(emp, "salary");
382
        assertNotFetchedAttribute(emp, "startTime");
411
            assertNotFetchedAttribute(emp, "startTime");
383
        assertNotFetchedAttribute(emp, "endTime");
412
            assertNotFetchedAttribute(emp, "endTime");
384
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
413
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
385
        if (emp.getPeriod() != null) {
414
            if (emp.getPeriod() != null) {
386
            assertFetchedAttribute(emp.getPeriod(), "startDate");
415
                assertFetchedAttribute(emp.getPeriod(), "startDate");
387
            assertFetchedAttribute(emp.getPeriod(), "endDate");
416
                assertFetchedAttribute(emp.getPeriod(), "endDate");
388
        }
417
            }
389
418
390
        // Check Relationships
419
            // Check Relationships
391
        assertNotFetchedAttribute(emp, "address");
420
            assertNotFetchedAttribute(emp, "address");
392
        assertNotFetchedAttribute(emp, "manager");
421
            assertNotFetchedAttribute(emp, "manager");
393
        assertNotFetchedAttribute(emp, "phoneNumbers");
422
            assertNotFetchedAttribute(emp, "phoneNumbers");
394
        assertNotFetchedAttribute(emp, "projects");
423
            assertNotFetchedAttribute(emp, "projects");
395
424
396
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
425
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
397
426
398
        emp.getSalary();
427
            emp.getSalary();
399
428
400
        assertFetchedAttribute(emp, "salary");
429
            assertFetchedAttribute(emp, "salary");
401
        assertNoFetchGroup(emp);
430
            assertNoFetchGroup(emp);
402
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
431
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
403
432
404
        assertNoFetchGroup(emp.getAddress());
433
            assertNoFetchGroup(emp.getAddress());
405
434
406
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
435
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
407
436
408
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
437
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
409
            assertNoFetchGroup(phone);
438
                assertNoFetchGroup(phone);
439
            }
440
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
441
        } finally {
442
            if (isTransactionActive(em)){
443
                rollbackTransaction(em);
444
            }
445
            closeEntityManager(em);
410
        }
446
        }
411
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
412
    }
447
    }
413
448
414
    /**
449
    /**
Lines 417-625 Link Here
417
    @Test
452
    @Test
418
    public void resultListPeriodFetchGroup() throws Exception {
453
    public void resultListPeriodFetchGroup() throws Exception {
419
        EntityManager em = createEntityManager();
454
        EntityManager em = createEntityManager();
455
        try {
456
            beginTransaction(em);
420
457
421
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
458
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
422
        query.setParameter("ID", minimumEmployeeId(em));
459
            query.setParameter("ID", minimumEmployeeId(em));
423
        FetchGroup fg = new FetchGroup();
460
            FetchGroup fg = new FetchGroup();
424
        fg.addAttribute("period");
461
            fg.addAttribute("period");
425
        query.setHint(QueryHints.FETCH_GROUP, fg);
462
            query.setHint(QueryHints.FETCH_GROUP, fg);
426
463
427
        List<Employee> emps = query.getResultList();
464
            List<Employee> emps = query.getResultList();
428
465
429
        assertNotNull(emps);
466
            assertNotNull(emps);
430
        assertEquals(1, emps.size());
467
            assertEquals(1, emps.size());
431
468
432
        Employee emp = emps.get(0);
469
            Employee emp = emps.get(0);
433
470
434
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
471
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
435
        assertFetched(emp, fg);
472
            assertFetched(emp, fg);
436
473
437
        // Check Basics
474
            // Check Basics
438
        assertFetchedAttribute(emp, "id");
475
            assertFetchedAttribute(emp, "id");
439
        assertFetchedAttribute(emp, "version");
476
            assertFetchedAttribute(emp, "version");
440
        assertNotFetchedAttribute(emp, "firstName");
477
            assertNotFetchedAttribute(emp, "firstName");
441
        assertNotFetchedAttribute(emp, "lastName");
478
            assertNotFetchedAttribute(emp, "lastName");
442
        assertNotFetchedAttribute(emp, "gender");
479
            assertNotFetchedAttribute(emp, "gender");
443
        assertNotFetchedAttribute(emp, "salary");
480
            assertNotFetchedAttribute(emp, "salary");
444
        assertNotFetchedAttribute(emp, "startTime");
481
            assertNotFetchedAttribute(emp, "startTime");
445
        assertNotFetchedAttribute(emp, "endTime");
482
            assertNotFetchedAttribute(emp, "endTime");
446
        if (emp.getPeriod() != null) {
483
            if (emp.getPeriod() != null) {
447
            assertFetchedAttribute(emp.getPeriod(), "startDate");
484
                assertFetchedAttribute(emp.getPeriod(), "startDate");
448
            assertFetchedAttribute(emp.getPeriod(), "endDate");
485
                assertFetchedAttribute(emp.getPeriod(), "endDate");
449
        }
486
            }
450
487
451
        // Check Relationships
488
            // Check Relationships
452
        assertNotFetchedAttribute(emp, "address");
489
            assertNotFetchedAttribute(emp, "address");
453
        assertNotFetchedAttribute(emp, "manager");
490
            assertNotFetchedAttribute(emp, "manager");
454
        assertNotFetchedAttribute(emp, "phoneNumbers");
491
            assertNotFetchedAttribute(emp, "phoneNumbers");
455
        assertNotFetchedAttribute(emp, "projects");
492
            assertNotFetchedAttribute(emp, "projects");
456
493
457
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
494
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
458
495
459
        emp.getSalary();
496
            emp.getSalary();
460
497
461
        assertFetchedAttribute(emp, "salary");
498
            assertFetchedAttribute(emp, "salary");
462
        assertNoFetchGroup(emp);
499
            assertNoFetchGroup(emp);
463
500
464
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
501
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
465
502
466
        assertNoFetchGroup(emp.getAddress());
503
            assertNoFetchGroup(emp.getAddress());
467
504
468
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
505
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
469
506
470
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
507
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
471
            assertNoFetchGroup(phone);
508
                assertNoFetchGroup(phone);
509
            }
510
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
511
        } finally {
512
            if (isTransactionActive(em)){
513
                rollbackTransaction(em);
514
            }
515
            closeEntityManager(em);
472
        }
516
        }
473
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
474
    }
517
    }
475
518
476
    @Test
519
    @Test
477
    public void managerFetchGroup() throws Exception {
520
    public void managerFetchGroup() throws Exception {
478
        EntityManager em = createEntityManager();
521
        EntityManager em = createEntityManager();
522
        try {
523
            beginTransaction(em);
479
524
480
        // Use q query since find will only use default fetch group
525
            // Use q query since find will only use default fetch group
481
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
526
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
482
//        query.setParameter("ID", minimumEmployeeId(em));
527
            //query.setParameter("ID", minimumEmployeeId(em));
483
        
528
            
484
        // Complex where clause used to avoid triggering employees and their departments:
529
            // Complex where clause used to avoid triggering employees and their departments:
485
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
530
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
486
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
531
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
487
        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");
532
            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");
488
533
489
        FetchGroup managerFG = new FetchGroup();
534
            FetchGroup managerFG = new FetchGroup();
490
        managerFG.addAttribute("manager");
535
            managerFG.addAttribute("manager");
491
536
492
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
537
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
493
538
494
        assertNotNull(getFetchGroup(query));
539
            assertNotNull(getFetchGroup(query));
495
        assertSame(managerFG, getFetchGroup(query));
540
            assertSame(managerFG, getFetchGroup(query));
496
541
497
        Employee emp = (Employee) query.getSingleResult();
542
            Employee emp = (Employee) query.getSingleResult();
498
543
499
        assertFetched(emp, managerFG);
544
            assertFetched(emp, managerFG);
500
//        int nSqlBeforeGetManager = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
545
            //int nSqlBeforeGetManager = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
501
        // manager hasn't been instantiated yet
546
            // manager hasn't been instantiated yet
502
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
547
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
503
        
548
            
504
        int nSqlToAdd = 0;
549
            int nSqlToAdd = 0;
505
        if (emp.getManager() != null) {
550
            if (emp.getManager() != null) {
506
            assertFetchedAttribute(emp, "manager");
551
                assertFetchedAttribute(emp, "manager");
507
            // additional sql to select the manager
552
                // additional sql to select the manager
508
            nSqlToAdd++;
553
                nSqlToAdd++;
509
        }        
554
            }
510
        assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
555
            assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
511
        
556
            
512
        // acuses instantioation of the whole object
557
            // acuses instantioation of the whole object
513
        emp.getLastName();
558
            emp.getLastName();
514
559
515
        assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
560
            assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
516
        assertNoFetchGroup(emp);
561
            assertNoFetchGroup(emp);
517
562
518
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
563
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
519
            assertNoFetchGroup(phone);
564
                assertNoFetchGroup(phone);
520
            phone.getAreaCode();
565
                phone.getAreaCode();
566
            }
567
568
            assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
569
        } finally {
570
            if (isTransactionActive(em)){
571
                rollbackTransaction(em);
572
            }
573
            closeEntityManager(em);
521
        }
574
        }
522
523
        assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
524
    }
575
    }
525
576
526
    @Test
577
    @Test
527
    public void managerFetchGroupWithJoinFetch() throws Exception {
578
    public void managerFetchGroupWithJoinFetch() throws Exception {
528
        EntityManager em = createEntityManager();
579
        EntityManager em = createEntityManager();
580
        try {
581
            beginTransaction(em);
529
582
530
//        int minId = minimumEmployeeId(em);
583
            //int minId = minimumEmployeeId(em);
531
//        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
584
            //assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
532
585
533
        // Use q query since find will only use default fetch group
586
            // Use q query since find will only use default fetch group
534
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
587
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
535
//        query.setParameter("ID", minId);
588
            //query.setParameter("ID", minId);
536
589
537
        // Complex where clause used to avoid triggering employees and their departments:
590
            // Complex where clause used to avoid triggering employees and their departments:
538
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
591
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
539
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
592
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
540
        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");
593
            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");
541
        FetchGroup managerFG = new FetchGroup();
594
            FetchGroup managerFG = new FetchGroup();
542
        managerFG.addAttribute("manager");
595
            managerFG.addAttribute("manager");
543
596
544
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
597
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
545
        query.setHint(QueryHints.LEFT_FETCH, "e.manager");
598
            query.setHint(QueryHints.LEFT_FETCH, "e.manager");
546
599
547
        assertNotNull(getFetchGroup(query));
600
            assertNotNull(getFetchGroup(query));
548
        assertSame(managerFG, getFetchGroup(query));
601
            assertSame(managerFG, getFetchGroup(query));
549
602
550
        Employee emp = (Employee) query.getSingleResult();
603
            Employee emp = (Employee) query.getSingleResult();
551
604
552
        assertFetched(emp, managerFG);
605
            assertFetched(emp, managerFG);
553
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
606
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
554
        
607
            
555
        // manager (if not null) is instantiated by the fetch group, before emp.getManager call.
608
            // manager (if not null) is instantiated by the fetch group, before emp.getManager call.
556
        emp.getManager();
609
            emp.getManager();
557
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
610
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
558
        
611
            
559
        // instantiates the whole object
612
            // instantiates the whole object
560
        emp.getLastName();
613
            emp.getLastName();
561
614
562
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
615
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
563
        assertNoFetchGroup(emp);
616
            assertNoFetchGroup(emp);
564
617
565
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
618
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
566
            assertNoFetchGroup(phone);
619
                assertNoFetchGroup(phone);
567
            phone.getAreaCode();
620
                phone.getAreaCode();
621
            }
622
623
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
624
        } finally {
625
            if (isTransactionActive(em)){
626
                rollbackTransaction(em);
627
            }
628
            closeEntityManager(em);
568
        }
629
        }
569
570
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
571
    }
630
    }
572
631
573
    @Test
632
    @Test
574
    public void employeeNamesFetchGroup() throws Exception {
633
    public void employeeNamesFetchGroup() throws Exception {
575
        EntityManager em = createEntityManager();
634
        EntityManager em = createEntityManager();
635
        try {
636
            beginTransaction(em);
576
637
577
        int minId = minimumEmployeeId(em);
638
            int minId = minimumEmployeeId(em);
578
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
639
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
579
640
580
        // Use q query since find will only use default fetch group
641
            // Use q query since find will only use default fetch group
581
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
642
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
582
        query.setParameter("ID", minId);
643
            query.setParameter("ID", minId);
583
        FetchGroup namesFG = new FetchGroup();
644
            FetchGroup namesFG = new FetchGroup();
584
        namesFG.addAttribute("firstName");
645
            namesFG.addAttribute("firstName");
585
        namesFG.addAttribute("lastName");
646
            namesFG.addAttribute("lastName");
586
647
587
        query.setHint(QueryHints.FETCH_GROUP, namesFG);
648
            query.setHint(QueryHints.FETCH_GROUP, namesFG);
588
649
589
        assertNotNull(getFetchGroup(query));
650
            assertNotNull(getFetchGroup(query));
590
        assertSame(namesFG, getFetchGroup(query));
651
            assertSame(namesFG, getFetchGroup(query));
591
652
592
        Employee emp = (Employee) query.getSingleResult();
653
            Employee emp = (Employee) query.getSingleResult();
593
654
594
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
655
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
595
        assertFetched(emp, namesFG);
656
            assertFetched(emp, namesFG);
596
657
597
        emp.getId();
658
            emp.getId();
598
        emp.getFirstName();
659
            emp.getFirstName();
599
        emp.getLastName();
660
            emp.getLastName();
600
        emp.getVersion();
661
            emp.getVersion();
601
662
602
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
663
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
603
        assertFetched(emp, namesFG);
664
            assertFetched(emp, namesFG);
604
665
605
        emp.getGender();
666
            emp.getGender();
606
        emp.getSalary();
667
            emp.getSalary();
607
668
608
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
669
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
609
        assertNoFetchGroup(emp);
670
            assertNoFetchGroup(emp);
610
671
611
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
672
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
612
            assertNoFetchGroup(phone);
673
                assertNoFetchGroup(phone);
613
            phone.getAreaCode();
674
                phone.getAreaCode();
614
        }
675
            }
615
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
676
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
616
677
617
        if (emp.getManager() != null) {
678
            if (emp.getManager() != null) {
618
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
679
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
619
            assertNoFetchGroup(emp.getManager());
680
                assertNoFetchGroup(emp.getManager());
620
        } else {
681
            } else {
621
            // If manager_id field is null then getManager() does not trigger an sql.
682
                // If manager_id field is null then getManager() does not trigger an sql.
622
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
683
                assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
684
            }
685
        } finally {
686
            if (isTransactionActive(em)){
687
                rollbackTransaction(em);
688
            }
689
            closeEntityManager(em);
623
        }
690
        }
624
    }
691
    }
625
692
Lines 658-686 Link Here
658
    @Test
725
    @Test
659
    public void verifyUnfetchedAttributes() throws Exception {
726
    public void verifyUnfetchedAttributes() throws Exception {
660
        EntityManager em = createEntityManager();
727
        EntityManager em = createEntityManager();
728
        try {
729
            beginTransaction(em);
730
            TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class);
731
            FetchGroup fg = new FetchGroup("Employee.empty");
732
            q.setHint(QueryHints.FETCH_GROUP, fg);
733
            Employee emp = q.getSingleResult();
661
734
662
        TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class);
735
            assertNotNull(emp);
663
        FetchGroup fg = new FetchGroup("Employee.empty");
736
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
664
        q.setHint(QueryHints.FETCH_GROUP, fg);
665
        Employee emp = q.getSingleResult();
666
737
667
        assertNotNull(emp);
738
            // This check using the mapping returns a default (empty) IndirectList
668
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
739
            /*OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers");
740
            IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp);
741
            assertNotNull(phones);
742
            assertTrue(phones.isInstantiated());
743
            assertEquals(0, phones.size());
744
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/
669
745
670
        // This check using the mapping returns a default (empty) IndirectList
746
            IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers();
671
/*        OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers");
747
            assertFalse(phonesIL.isInstantiated());
672
        IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp);
748
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
673
        assertNotNull(phones);
674
        assertTrue(phones.isInstantiated());
675
        assertEquals(0, phones.size());
676
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/
677
749
678
        IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers();
750
            assertTrue(emp.getPhoneNumbers().size() > 0);
679
        assertFalse(phonesIL.isInstantiated());
751
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
680
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
752
        } finally {
681
753
            if (isTransactionActive(em)){
682
        assertTrue(emp.getPhoneNumbers().size() > 0);
754
                rollbackTransaction(em);
683
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
755
            }
756
            closeEntityManager(em);
757
        }
684
    }
758
    }
685
759
686
    @Test
760
    @Test
Lines 725-744 Link Here
725
    @Test
799
    @Test
726
    public void explicitlyDetachedObjectWithFetchGroup() {
800
    public void explicitlyDetachedObjectWithFetchGroup() {
727
        EntityManager em = createEntityManager();
801
        EntityManager em = createEntityManager();
802
        try {
803
            beginTransaction(em);
804
            FetchGroup fg = new FetchGroup();
805
            fg.addAttribute("firstName");
806
            fg.addAttribute("lastName");
728
807
729
        FetchGroup fg = new FetchGroup();
808
            Map<String, Object> hints = new HashMap<String, Object>();
730
        fg.addAttribute("firstName");
809
            hints.put(QueryHints.FETCH_GROUP, fg);
731
        fg.addAttribute("lastName");
732
810
733
        Map<String, Object> hints = new HashMap<String, Object>();
811
            Employee emp = minimumEmployee(em, hints);
734
        hints.put(QueryHints.FETCH_GROUP, fg);
812
            em.detach(emp);
735
813
            assertFetched(emp, fg);
736
        Employee emp = minimumEmployee(em, hints);
814
            
737
        em.detach(emp);
815
            // trigger the fetch group
738
        assertFetched(emp, fg);
816
            emp.getSalary();
739
        
817
            assertNoFetchGroup(emp);
740
        // trigger the fetch group
818
        } finally {
741
        emp.getSalary();
819
            if (isTransactionActive(em)){
742
        assertNoFetchGroup(emp);
820
                rollbackTransaction(em);
821
            }
822
            closeEntityManager(em);
823
        }
743
    }
824
    }
744
}
825
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleNamedFetchGroupTests.java (-32 / +39 lines)
Lines 269-316 Link Here
269
    @Test
269
    @Test
270
    public void managerFetchGroup() throws Exception {
270
    public void managerFetchGroup() throws Exception {
271
        EntityManager em = createEntityManager();
271
        EntityManager em = createEntityManager();
272
        try {
273
            beginTransaction(em);
274
            // Use q query since find will only use default fetch group
275
            // Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
276
            // query.setParameter("ID", minimumEmployeeId(em));
272
277
273
        // Use q query since find will only use default fetch group
278
            // Complex where clause used to avoid triggering employees and their departments:
274
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
279
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
275
//        query.setParameter("ID", minimumEmployeeId(em));
280
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
281
            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");
282
            FetchGroup managerFG = new FetchGroup();
283
            managerFG.addAttribute("manager");
276
284
277
        // Complex where clause used to avoid triggering employees and their departments:
285
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
278
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
279
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
280
        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");
281
        FetchGroup managerFG = new FetchGroup();
282
        managerFG.addAttribute("manager");
283
286
284
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
287
            assertNotNull(getFetchGroup(query));
288
            assertSame(managerFG, getFetchGroup(query));
285
289
286
        assertNotNull(getFetchGroup(query));
290
            Employee emp = (Employee) query.getSingleResult();
287
        assertSame(managerFG, getFetchGroup(query));
288
291
289
        Employee emp = (Employee) query.getSingleResult();
292
            assertFetched(emp, managerFG);
293
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
294
            
295
            int nSqlToAdd = 0;
296
            if (emp.getManager() != null) {
297
                assertFetchedAttribute(emp, "manager");
298
                // additional sql to select the manager
299
                nSqlToAdd++;
300
            }
301
            
302
            assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
290
303
291
        assertFetched(emp, managerFG);
304
            // instantiates the whole object
292
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
305
            emp.getLastName();
293
        
294
        int nSqlToAdd = 0;
295
        if (emp.getManager() != null) {
296
            assertFetchedAttribute(emp, "manager");
297
            // additional sql to select the manager
298
            nSqlToAdd++;
299
        }
300
        
301
        assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
302
306
303
        // instantiates the whole object
307
            assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
304
        emp.getLastName();
308
            assertNoFetchGroup(emp);
305
309
306
        assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
310
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
307
        assertNoFetchGroup(emp);
311
                assertNoFetchGroup(phone);
312
            }
308
313
309
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
314
            assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
310
            assertNoFetchGroup(phone);
315
        } finally {
316
            if (isTransactionActive(em)){
317
                rollbackTransaction(em);
318
            }
319
            closeEntityManager(em);
311
        }
320
        }
312
313
        assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
314
    }
321
    }
315
322
316
    @Test
323
    @Test
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fetchgroups/SimpleSerializeFetchGroupTests.java (-544 / +640 lines)
Lines 12-17 Link Here
12
 ******************************************************************************/
12
 ******************************************************************************/
13
package org.eclipse.persistence.testing.tests.jpa.fetchgroups;
13
package org.eclipse.persistence.testing.tests.jpa.fetchgroups;
14
14
15
import java.io.ByteArrayInputStream;
16
import java.io.ObjectInputStream;
17
import java.io.ObjectOutputStream;
15
import java.io.IOException;
18
import java.io.IOException;
16
import java.io.Serializable;
19
import java.io.Serializable;
17
import java.util.ArrayList;
20
import java.util.ArrayList;
Lines 65-72 Link Here
65
        
68
        
66
        suite.addTest(new SimpleSerializeFetchGroupTests("testSetup"));
69
        suite.addTest(new SimpleSerializeFetchGroupTests("testSetup"));
67
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyWriteReplaceOnFetchGroup"));
70
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyWriteReplaceOnFetchGroup"));
68
        suite.addTest(new SimpleSerializeFetchGroupTests("findMinimalFetchGroup"));
69
        suite.addTest(new SimpleSerializeFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary"));
70
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyAddAttributeInDetachedEntityFetchGroup"));
71
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyAddAttributeInDetachedEntityFetchGroup"));
71
        suite.addTest(new SimpleSerializeFetchGroupTests("singleResultEmptyFetchGroup"));
72
        suite.addTest(new SimpleSerializeFetchGroupTests("singleResultEmptyFetchGroup"));
72
        suite.addTest(new SimpleSerializeFetchGroupTests("resultListEmptyFetchGroup"));
73
        suite.addTest(new SimpleSerializeFetchGroupTests("resultListEmptyFetchGroup"));
Lines 76-94 Link Here
76
        suite.addTest(new SimpleSerializeFetchGroupTests("employeeNamesFetchGroup"));
77
        suite.addTest(new SimpleSerializeFetchGroupTests("employeeNamesFetchGroup"));
77
        suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
78
        suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
78
        suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
79
        suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
79
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyUnfetchedAttributes"));
80
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyFetchedRelationshipAttributes"));
80
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyFetchedRelationshipAttributes"));
81
        suite.addTest(new SimpleSerializeFetchGroupTests("simpleSerializeAndMerge"));
81
        if (!isJPA10()) {
82
        suite.addTest(new SimpleSerializeFetchGroupTests("partialMerge"));
82
            suite.addTest(new SimpleSerializeFetchGroupTests("findMinimalFetchGroup"));
83
        suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge"));
83
            suite.addTest(new SimpleSerializeFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary"));
84
        suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge2"));
84
            suite.addTest(new SimpleSerializeFetchGroupTests("verifyUnfetchedAttributes"));
85
        suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPk"));
85
            suite.addTest(new SimpleSerializeFetchGroupTests("simpleSerializeAndMerge"));
86
        suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPkUseFullGroup"));
86
            suite.addTest(new SimpleSerializeFetchGroupTests("partialMerge"));
87
        suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPk"));
87
            suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge"));
88
        suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPkUseFullGroup"));
88
            suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge2"));
89
        suite.addTest(new SimpleSerializeFetchGroupTests("copyNoCascade"));
89
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPk"));
90
        suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadePrivateParts"));
90
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPkUseFullGroup"));
91
        suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadeAllParts"));
91
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPk"));
92
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPkUseFullGroup"));
93
            suite.addTest(new SimpleSerializeFetchGroupTests("copyNoCascade"));
94
            suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadePrivateParts"));
95
            suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadeAllParts"));
96
        }
92
        
97
        
93
        return suite;
98
        return suite;
94
    }
99
    }
Lines 96-105 Link Here
96
    @Test
101
    @Test
97
    public void verifyWriteReplaceOnFetchGroup() throws Exception {
102
    public void verifyWriteReplaceOnFetchGroup() throws Exception {
98
        EntityFetchGroup fg = new EntityFetchGroup(new String[]{"basic", "a"});
103
        EntityFetchGroup fg = new EntityFetchGroup(new String[]{"basic", "a"});
99
//        fg.addAttribute("basic");
104
        //fg.addAttribute("basic");
100
//        fg.addAttribute("a.b");
105
        //fg.addAttribute("a.b");
101
106
102
//        assertTrue(fg.getClass() == FetchGroup.class);
107
        //assertTrue(fg.getClass() == FetchGroup.class);
103
108
104
        FetchGroup serFG = serialize(fg);
109
        FetchGroup serFG = serialize(fg);
105
110
Lines 110-124 Link Here
110
        AttributeItem basicFI = serFG.getItem("basic");
115
        AttributeItem basicFI = serFG.getItem("basic");
111
116
112
        assertNotNull(basicFI);
117
        assertNotNull(basicFI);
113
//        assertTrue(basicFI instanceof DetachedFetchItem);
118
        //assertTrue(basicFI instanceof DetachedFetchItem);
114
119
115
        AttributeItem aFI = serFG.getItem("a");
120
        AttributeItem aFI = serFG.getItem("a");
116
121
117
        assertNotNull(aFI);
122
        assertNotNull(aFI);
118
//        assertTrue(aFI instanceof DetachedFetchItem);
123
        //assertTrue(aFI instanceof DetachedFetchItem);
119
        // serialized EntityFetchGroup is always flat - doesn't have nested groups.
124
        // serialized EntityFetchGroup is always flat - doesn't have nested groups.
120
        assertNull(aFI.getGroup());
125
        assertNull(aFI.getGroup());
121
/*        assertNotNull(aFI.getGroup());
126
        /*assertNotNull(aFI.getGroup());
122
        assertTrue(aFI.getGroup() instanceof EntityFetchGroup);
127
        assertTrue(aFI.getGroup() instanceof EntityFetchGroup);
123
        EntityFetchGroup aEFG = (EntityFetchGroup) aFI.getGroup();
128
        EntityFetchGroup aEFG = (EntityFetchGroup) aFI.getGroup();
124
        assertNull(aEFG.getParent());
129
        assertNull(aEFG.getParent());
Lines 127-133 Link Here
127
        AttributeItem bFI = aEFG.getItem("b");
132
        AttributeItem bFI = aEFG.getItem("b");
128
133
129
        assertNotNull(bFI);
134
        assertNotNull(bFI);
130
//        assertTrue(bFI instanceof DetachedFetchItem);
135
        //assertTrue(bFI instanceof DetachedFetchItem);
131
        assertNull(bFI.getGroup());*/
136
        assertNull(bFI.getGroup());*/
132
    }
137
    }
133
138
Lines 194-250 Link Here
194
    public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception {
199
    public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception {
195
        EntityManager em = createEntityManager();
200
        EntityManager em = createEntityManager();
196
        int minId = minimumEmployeeId(em);
201
        int minId = minimumEmployeeId(em);
202
        try {
203
            beginTransaction(em);
197
204
198
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
205
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
199
206
200
        Map<String, Object> properties = new HashMap<String, Object>();
207
            Map<String, Object> properties = new HashMap<String, Object>();
201
        FetchGroup emptyFG = new FetchGroup();
208
            FetchGroup emptyFG = new FetchGroup();
202
        properties.put(QueryHints.FETCH_GROUP, emptyFG);
209
            properties.put(QueryHints.FETCH_GROUP, emptyFG);
203
210
204
        Employee emp = em.find(Employee.class, minId, properties);
211
            Employee emp = em.find(Employee.class, minId, properties);
205
212
206
        assertNotNull(emp);
213
            assertNotNull(emp);
207
        assertFetched(emp, emptyFG);
214
            assertFetched(emp, emptyFG);
208
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
215
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
209
216
210
        // Check Basics
217
            // Check Basics
211
        assertFetchedAttribute(emp, "id");
218
            assertFetchedAttribute(emp, "id");
212
        assertFetchedAttribute(emp, "version");
219
            assertFetchedAttribute(emp, "version");
213
        assertNotFetchedAttribute(emp, "firstName");
220
            assertNotFetchedAttribute(emp, "firstName");
214
        assertNotFetchedAttribute(emp, "lastName");
221
            assertNotFetchedAttribute(emp, "lastName");
215
        assertNotFetchedAttribute(emp, "gender");
222
            assertNotFetchedAttribute(emp, "gender");
216
        assertNotFetchedAttribute(emp, "salary");
223
            assertNotFetchedAttribute(emp, "salary");
217
        assertNotFetchedAttribute(emp, "startTime");
224
            assertNotFetchedAttribute(emp, "startTime");
218
        assertNotFetchedAttribute(emp, "endTime");
225
            assertNotFetchedAttribute(emp, "endTime");
219
        if (emp.getPeriod() != null) {
226
            if (emp.getPeriod() != null) {
220
            assertFetchedAttribute(emp.getPeriod(), "startDate");
227
                assertFetchedAttribute(emp.getPeriod(), "startDate");
221
            assertFetchedAttribute(emp.getPeriod(), "endDate");
228
                assertFetchedAttribute(emp.getPeriod(), "endDate");
222
        }
229
            }
223
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
230
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
224
231
225
        // Check Relationships
232
            // Check Relationships
226
        assertNotFetchedAttribute(emp, "address");
233
            assertNotFetchedAttribute(emp, "address");
227
        assertNotFetchedAttribute(emp, "manager");
234
            assertNotFetchedAttribute(emp, "manager");
228
        assertNotFetchedAttribute(emp, "phoneNumbers");
235
            assertNotFetchedAttribute(emp, "phoneNumbers");
229
        assertNotFetchedAttribute(emp, "projects");
236
            assertNotFetchedAttribute(emp, "projects");
230
237
231
        emp.setSalary(1);
238
            emp.setSalary(1);
232
239
233
        assertFetchedAttribute(emp, "salary");
240
            assertFetchedAttribute(emp, "salary");
234
241
235
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
242
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
236
        assertNoFetchGroup(emp);
243
            assertNoFetchGroup(emp);
237
244
238
        emp.getAddress();
245
            emp.getAddress();
239
246
240
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
247
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
241
        assertNoFetchGroup(emp.getAddress());
248
            assertNoFetchGroup(emp.getAddress());
242
249
243
        emp.getPhoneNumbers().size();
250
            emp.getPhoneNumbers().size();
244
251
245
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
252
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
246
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
253
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
247
            assertNoFetchGroup(phone);
254
                assertNoFetchGroup(phone);
255
            }
256
        } finally {
257
            if (isTransactionActive(em)){
258
                rollbackTransaction(em);
259
            }
260
            closeEntityManager(em);
248
        }
261
        }
249
    }
262
    }
250
263
Lines 256-351 Link Here
256
    public void verifyAddAttributeInDetachedEntityFetchGroup() {
269
    public void verifyAddAttributeInDetachedEntityFetchGroup() {
257
        EntityFetchGroup detFG = new EntityFetchGroup(new String[]{"basic", "a"});
270
        EntityFetchGroup detFG = new EntityFetchGroup(new String[]{"basic", "a"});
258
271
259
//        detFG.addAttribute("basic");
272
        //detFG.addAttribute("basic");
260
//        detFG.addAttribute("a.b");
273
        //detFG.addAttribute("a.b");
261
274
262
//        assertNull(detFG.getParent());
275
        //assertNull(detFG.getParent());
263
        assertEquals(2, detFG.getItems().size());
276
        assertEquals(2, detFG.getItems().size());
264
277
265
        AttributeItem basicItem = detFG.getItem("basic");
278
        AttributeItem basicItem = detFG.getItem("basic");
266
        assertNotNull(basicItem);
279
        assertNotNull(basicItem);
267
        assertEquals("basic", basicItem.getAttributeName());
280
        assertEquals("basic", basicItem.getAttributeName());
268
//        assertTrue(basicItem instanceof DetachedFetchItem);
281
        //assertTrue(basicItem instanceof DetachedFetchItem);
269
        assertNull(basicItem.getGroup());
282
        assertNull(basicItem.getGroup());
270
        assertSame(detFG, basicItem.getParent());
283
        assertSame(detFG, basicItem.getParent());
271
//        assertFalse(basicItem.useDefaultFetchGroup());
284
        //assertFalse(basicItem.useDefaultFetchGroup());
272
285
273
        AttributeItem aItem = detFG.getItem("a");
286
        AttributeItem aItem = detFG.getItem("a");
274
        assertNotNull(aItem);
287
        assertNotNull(aItem);
275
        assertEquals("a", aItem.getAttributeName());
288
        assertEquals("a", aItem.getAttributeName());
276
//        assertTrue(aItem instanceof DetachedFetchItem);
289
        //assertTrue(aItem instanceof DetachedFetchItem);
277
        // serialized EntityFetchGroup is always flat - doesn't have nested groups.
290
        // serialized EntityFetchGroup is always flat - doesn't have nested groups.
278
////        assertNull(aItem.getGroup());
291
        //assertNull(aItem.getGroup());
279
        assertNull(aItem.getGroup());
292
        assertNull(aItem.getGroup());
280
        assertSame(detFG, aItem.getParent());
293
        assertSame(detFG, aItem.getParent());
281
//        assertFalse(aItem.useDefaultFetchGroup());
294
        //assertFalse(aItem.useDefaultFetchGroup());
282
//        assertTrue(aItem.getGroup() instanceof EntityFetchGroup);
295
        //assertTrue(aItem.getGroup() instanceof EntityFetchGroup);
283
296
284
//        EntityFetchGroup aFG = (EntityFetchGroup) aItem.getGroup();
297
        //EntityFetchGroup aFG = (EntityFetchGroup) aItem.getGroup();
285
298
286
//        assertEquals(1, aFG.getItems().size());
299
        //assertEquals(1, aFG.getItems().size());
287
300
288
//        AttributeItem bItem = aFG.getItem("b");
301
        //AttributeItem bItem = aFG.getItem("b");
289
//        assertNotNull(bItem);
302
        //assertNotNull(bItem);
290
//        assertEquals("b", bItem.getAttributeName());
303
        //assertEquals("b", bItem.getAttributeName());
291
//        assertTrue(bItem instanceof DetachedFetchItem);
304
        //assertTrue(bItem instanceof DetachedFetchItem);
292
  //      assertNull(bItem.getGroup());
305
        //assertNull(bItem.getGroup());
293
//        assertSame(aFG, bItem.getParent());
306
        //assertSame(aFG, bItem.getParent());
294
//        assertFalse(bItem.useDefaultFetchGroup());
307
        //assertFalse(bItem.useDefaultFetchGroup());
295
    }
308
    }
296
309
297
    @Test
310
    @Test
298
    public void singleResultEmptyFetchGroup() throws Exception {
311
    public void singleResultEmptyFetchGroup() throws Exception {
299
        EntityManager em = createEntityManager();
312
        EntityManager em = createEntityManager();
313
        try {
314
            beginTransaction(em);
300
315
301
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
316
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
302
        query.setParameter("ID", minimumEmployeeId(em));
317
            query.setParameter("ID", minimumEmployeeId(em));
303
        FetchGroup emptyFG = new FetchGroup();
318
            FetchGroup emptyFG = new FetchGroup();
304
        query.setHint(QueryHints.FETCH_GROUP, emptyFG);
319
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);
305
320
306
        Employee emp = (Employee) query.getSingleResult();
321
            Employee emp = (Employee) query.getSingleResult();
307
322
308
        assertNotNull(emp);
323
            assertNotNull(emp);
309
        assertFetched(emp, emptyFG);
324
            assertFetched(emp, emptyFG);
310
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
325
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
311
326
312
        // Check Basics
327
            // Check Basics
313
        assertFetchedAttribute(emp, "id");
328
            assertFetchedAttribute(emp, "id");
314
        assertFetchedAttribute(emp, "version");
329
            assertFetchedAttribute(emp, "version");
315
        assertNotFetchedAttribute(emp, "firstName");
330
            assertNotFetchedAttribute(emp, "firstName");
316
        assertNotFetchedAttribute(emp, "lastName");
331
            assertNotFetchedAttribute(emp, "lastName");
317
        assertNotFetchedAttribute(emp, "gender");
332
            assertNotFetchedAttribute(emp, "gender");
318
        assertNotFetchedAttribute(emp, "salary");
333
            assertNotFetchedAttribute(emp, "salary");
319
        assertNotFetchedAttribute(emp, "startTime");
334
            assertNotFetchedAttribute(emp, "startTime");
320
        assertNotFetchedAttribute(emp, "endTime");
335
            assertNotFetchedAttribute(emp, "endTime");
321
        if (emp.getPeriod() != null) {
336
            if (emp.getPeriod() != null) {
322
            assertFetchedAttribute(emp.getPeriod(), "startDate");
337
                assertFetchedAttribute(emp.getPeriod(), "startDate");
323
            assertFetchedAttribute(emp.getPeriod(), "endDate");
338
                assertFetchedAttribute(emp.getPeriod(), "endDate");
324
        }
339
            }
325
340
326
        // Check Relationships
341
            // Check Relationships
327
        assertNotFetchedAttribute(emp, "address");
342
            assertNotFetchedAttribute(emp, "address");
328
        assertNotFetchedAttribute(emp, "manager");
343
            assertNotFetchedAttribute(emp, "manager");
329
        assertNotFetchedAttribute(emp, "phoneNumbers");
344
            assertNotFetchedAttribute(emp, "phoneNumbers");
330
        assertNotFetchedAttribute(emp, "projects");
345
            assertNotFetchedAttribute(emp, "projects");
331
346
332
        emp.getSalary();
347
            emp.getSalary();
333
348
334
        assertFetchedAttribute(emp, "salary");
349
            assertFetchedAttribute(emp, "salary");
335
350
336
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
351
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
337
        assertNoFetchGroup(emp);
352
            assertNoFetchGroup(emp);
338
353
339
        emp.getAddress();
354
            emp.getAddress();
340
355
341
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
356
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
342
        assertNoFetchGroup(emp.getAddress());
357
            assertNoFetchGroup(emp.getAddress());
343
358
344
        emp.getPhoneNumbers().size();
359
            emp.getPhoneNumbers().size();
345
360
346
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
361
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
347
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
362
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
348
            assertNoFetchGroup(phone);
363
                assertNoFetchGroup(phone);
364
            }
365
        } finally {
366
            if (isTransactionActive(em)){
367
                rollbackTransaction(em);
368
            }
369
            closeEntityManager(em);
349
        }
370
        }
350
    }
371
    }
351
372
Lines 355-413 Link Here
355
    @Test
376
    @Test
356
    public void resultListEmptyFetchGroup() throws Exception {
377
    public void resultListEmptyFetchGroup() throws Exception {
357
        EntityManager em = createEntityManager();
378
        EntityManager em = createEntityManager();
379
        try {
380
            beginTransaction(em);
358
381
359
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
382
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
360
        query.setParameter("ID", minimumEmployeeId(em));
383
            query.setParameter("ID", minimumEmployeeId(em));
361
        FetchGroup emptyFG = new FetchGroup();
384
            FetchGroup emptyFG = new FetchGroup();
362
        query.setHint(QueryHints.FETCH_GROUP, emptyFG);
385
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);
363
386
364
        List<Employee> emps = query.getResultList();
387
            List<Employee> emps = query.getResultList();
365
388
366
        assertNotNull(emps);
389
            assertNotNull(emps);
367
        assertEquals(1, emps.size());
390
            assertEquals(1, emps.size());
368
391
369
        Employee emp = emps.get(0);
392
            Employee emp = emps.get(0);
370
393
371
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
394
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
372
        assertFetched(emp, emptyFG);
395
            assertFetched(emp, emptyFG);
373
396
374
        // Check Basics
397
            // Check Basics
375
        assertFetchedAttribute(emp, "id");
398
            assertFetchedAttribute(emp, "id");
376
        assertFetchedAttribute(emp, "version");
399
            assertFetchedAttribute(emp, "version");
377
        assertNotFetchedAttribute(emp, "firstName");
400
            assertNotFetchedAttribute(emp, "firstName");
378
        assertNotFetchedAttribute(emp, "lastName");
401
            assertNotFetchedAttribute(emp, "lastName");
379
        assertNotFetchedAttribute(emp, "gender");
402
            assertNotFetchedAttribute(emp, "gender");
380
        assertNotFetchedAttribute(emp, "salary");
403
            assertNotFetchedAttribute(emp, "salary");
381
        assertNotFetchedAttribute(emp, "startTime");
404
            assertNotFetchedAttribute(emp, "startTime");
382
        assertNotFetchedAttribute(emp, "endTime");
405
            assertNotFetchedAttribute(emp, "endTime");
383
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
406
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
384
        if (emp.getPeriod() != null) {
407
            if (emp.getPeriod() != null) {
385
            assertFetchedAttribute(emp.getPeriod(), "startDate");
408
                assertFetchedAttribute(emp.getPeriod(), "startDate");
386
            assertFetchedAttribute(emp.getPeriod(), "endDate");
409
                assertFetchedAttribute(emp.getPeriod(), "endDate");
387
        }
410
            }
388
411
389
        // Check Relationships
412
            // Check Relationships
390
        assertNotFetchedAttribute(emp, "address");
413
            assertNotFetchedAttribute(emp, "address");
391
        assertNotFetchedAttribute(emp, "manager");
414
            assertNotFetchedAttribute(emp, "manager");
392
        assertNotFetchedAttribute(emp, "phoneNumbers");
415
            assertNotFetchedAttribute(emp, "phoneNumbers");
393
        assertNotFetchedAttribute(emp, "projects");
416
            assertNotFetchedAttribute(emp, "projects");
394
417
395
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
418
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
396
419
397
        emp.getSalary();
420
            emp.getSalary();
398
421
399
        assertFetchedAttribute(emp, "salary");
422
            assertFetchedAttribute(emp, "salary");
400
        assertNoFetchGroup(emp);
423
            assertNoFetchGroup(emp);
401
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
424
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
402
425
403
        assertNoFetchGroup(emp.getAddress());
426
            assertNoFetchGroup(emp.getAddress());
404
427
405
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
428
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
406
429
407
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
430
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
408
            assertNoFetchGroup(phone);
431
                assertNoFetchGroup(phone);
432
            }
433
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
434
        } finally {
435
            if (isTransactionActive(em)){
436
                rollbackTransaction(em);
437
            }
438
            closeEntityManager(em);
409
        }
439
        }
410
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
411
    }
440
    }
412
441
413
    /**
442
    /**
Lines 416-624 Link Here
416
    @Test
445
    @Test
417
    public void resultListPeriodFetchGroup() throws Exception {
446
    public void resultListPeriodFetchGroup() throws Exception {
418
        EntityManager em = createEntityManager();
447
        EntityManager em = createEntityManager();
448
        try {
449
            beginTransaction(em);
419
450
420
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
451
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
421
        query.setParameter("ID", minimumEmployeeId(em));
452
            query.setParameter("ID", minimumEmployeeId(em));
422
        FetchGroup fg = new FetchGroup();
453
            FetchGroup fg = new FetchGroup();
423
        fg.addAttribute("period");
454
            fg.addAttribute("period");
424
        query.setHint(QueryHints.FETCH_GROUP, fg);
455
            query.setHint(QueryHints.FETCH_GROUP, fg);
425
456
426
        List<Employee> emps = query.getResultList();
457
            List<Employee> emps = query.getResultList();
427
458
428
        assertNotNull(emps);
459
            assertNotNull(emps);
429
        assertEquals(1, emps.size());
460
            assertEquals(1, emps.size());
430
461
431
        Employee emp = emps.get(0);
462
            Employee emp = emps.get(0);
432
463
433
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
464
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
434
        assertFetched(emp, fg);
465
            assertFetched(emp, fg);
435
466
436
        // Check Basics
467
            // Check Basics
437
        assertFetchedAttribute(emp, "id");
468
            assertFetchedAttribute(emp, "id");
438
        assertFetchedAttribute(emp, "version");
469
            assertFetchedAttribute(emp, "version");
439
        assertNotFetchedAttribute(emp, "firstName");
470
            assertNotFetchedAttribute(emp, "firstName");
440
        assertNotFetchedAttribute(emp, "lastName");
471
            assertNotFetchedAttribute(emp, "lastName");
441
        assertNotFetchedAttribute(emp, "gender");
472
            assertNotFetchedAttribute(emp, "gender");
442
        assertNotFetchedAttribute(emp, "salary");
473
            assertNotFetchedAttribute(emp, "salary");
443
        assertNotFetchedAttribute(emp, "startTime");
474
            assertNotFetchedAttribute(emp, "startTime");
444
        assertNotFetchedAttribute(emp, "endTime");
475
            assertNotFetchedAttribute(emp, "endTime");
445
        if (emp.getPeriod() != null) {
476
            if (emp.getPeriod() != null) {
446
            assertFetchedAttribute(emp.getPeriod(), "startDate");
477
                assertFetchedAttribute(emp.getPeriod(), "startDate");
447
            assertFetchedAttribute(emp.getPeriod(), "endDate");
478
                assertFetchedAttribute(emp.getPeriod(), "endDate");
448
        }
479
            }
449
480
450
        // Check Relationships
481
            // Check Relationships
451
        assertNotFetchedAttribute(emp, "address");
482
            assertNotFetchedAttribute(emp, "address");
452
        assertNotFetchedAttribute(emp, "manager");
483
            assertNotFetchedAttribute(emp, "manager");
453
        assertNotFetchedAttribute(emp, "phoneNumbers");
484
            assertNotFetchedAttribute(emp, "phoneNumbers");
454
        assertNotFetchedAttribute(emp, "projects");
485
            assertNotFetchedAttribute(emp, "projects");
455
486
456
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
487
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
457
488
458
        emp.getSalary();
489
            emp.getSalary();
459
490
460
        assertFetchedAttribute(emp, "salary");
491
            assertFetchedAttribute(emp, "salary");
461
        assertNoFetchGroup(emp);
492
            assertNoFetchGroup(emp);
462
493
463
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
494
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
464
495
465
        assertNoFetchGroup(emp.getAddress());
496
            assertNoFetchGroup(emp.getAddress());
466
497
467
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
498
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
468
499
469
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
500
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
470
            assertNoFetchGroup(phone);
501
                assertNoFetchGroup(phone);
502
            }
503
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
504
        } finally {
505
            if (isTransactionActive(em)){
506
                rollbackTransaction(em);
507
            }
508
            closeEntityManager(em);
471
        }
509
        }
472
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
473
    }
510
    }
474
511
475
    @Test
512
    @Test
476
    public void managerFetchGroup() throws Exception {
513
    public void managerFetchGroup() throws Exception {
477
        EntityManager em = createEntityManager();
514
        EntityManager em = createEntityManager();
515
        try {
516
            beginTransaction(em);
478
517
479
        // Use q query since find will only use default fetch group
518
            // Use q query since find will only use default fetch group
480
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
519
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
481
//        query.setParameter("ID", minimumEmployeeId(em));
520
            //query.setParameter("ID", minimumEmployeeId(em));
482
521
483
        // Complex where clause used to avoid triggering employees and their departments:
522
            // Complex where clause used to avoid triggering employees and their departments:
484
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
523
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
485
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
524
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
486
        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");
525
            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");
487
        
526
            
488
        FetchGroup managerFG = new FetchGroup();
527
            FetchGroup managerFG = new FetchGroup();
489
        managerFG.addAttribute("manager");
528
            managerFG.addAttribute("manager");
490
529
491
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
530
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
492
531
493
        assertNotNull(getFetchGroup(query));
532
            assertNotNull(getFetchGroup(query));
494
        assertSame(managerFG, getFetchGroup(query));
533
            assertSame(managerFG, getFetchGroup(query));
495
534
496
        Employee emp = (Employee) query.getSingleResult();
535
            Employee emp = (Employee) query.getSingleResult();
497
536
498
        assertFetched(emp, managerFG);
537
            assertFetched(emp, managerFG);
499
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
538
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
500
        
539
            
501
        // manager (if not null) hasn't been instantiated yet.
540
            // manager (if not null) hasn't been instantiated yet.
502
        int nSqlToAdd = 0;
541
            int nSqlToAdd = 0;
503
        if (emp.getManager() != null) {
542
            if (emp.getManager() != null) {
504
            assertFetchedAttribute(emp, "manager");
543
                assertFetchedAttribute(emp, "manager");
505
            // additional sql to select the manager
544
                // additional sql to select the manager
506
            nSqlToAdd++;
545
                nSqlToAdd++;
507
        }
546
            }
508
        
547
            
509
        assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
548
            assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
510
549
511
        emp.getLastName();
550
            emp.getLastName();
512
551
513
        assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
552
            assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
514
        assertNoFetchGroup(emp);
553
            assertNoFetchGroup(emp);
515
554
516
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
555
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
517
            assertNoFetchGroup(phone);
556
                assertNoFetchGroup(phone);
518
            phone.getAreaCode();
557
                phone.getAreaCode();
558
            }
559
560
            assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
561
        } finally {
562
            if (isTransactionActive(em)){
563
                rollbackTransaction(em);
564
            }
565
            closeEntityManager(em);
519
        }
566
        }
520
521
        assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
522
    }
567
    }
523
568
524
    @Test
569
    @Test
525
    public void managerFetchGroupWithJoinFetch() throws Exception {
570
    public void managerFetchGroupWithJoinFetch() throws Exception {
526
        EntityManager em = createEntityManager();
571
        EntityManager em = createEntityManager();
572
        try {
573
            beginTransaction(em);
527
574
528
//        int minId = minimumEmployeeId(em);
575
            //int minId = minimumEmployeeId(em);
529
//        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
576
            //assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
530
577
531
        // Use q query since find will only use default fetch group
578
            // Use q query since find will only use default fetch group
532
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
579
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
533
//        query.setParameter("ID", minId);
580
            //query.setParameter("ID", minId);
534
581
535
        // Complex where clause used to avoid triggering employees and their departments:
582
            // Complex where clause used to avoid triggering employees and their departments:
536
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
583
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
537
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
584
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
538
        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");
585
            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");
539
586
540
        FetchGroup managerFG = new FetchGroup();
587
            FetchGroup managerFG = new FetchGroup();
541
        managerFG.addAttribute("manager");
588
            managerFG.addAttribute("manager");
542
589
543
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
590
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
544
        query.setHint(QueryHints.LEFT_FETCH, "e.manager");
591
            query.setHint(QueryHints.LEFT_FETCH, "e.manager");
545
592
546
        assertNotNull(getFetchGroup(query));
593
            assertNotNull(getFetchGroup(query));
547
        assertSame(managerFG, getFetchGroup(query));
594
            assertSame(managerFG, getFetchGroup(query));
548
595
549
        Employee emp = (Employee) query.getSingleResult();
596
            Employee emp = (Employee) query.getSingleResult();
550
597
551
        assertFetched(emp, managerFG);
598
            assertFetched(emp, managerFG);
552
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
599
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
553
        
600
            
554
        // manager has been already instantiated by the query.
601
            // manager has been already instantiated by the query.
555
        emp.getManager();
602
            emp.getManager();
556
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
603
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
557
        
604
            
558
        // instantiates the whiole object
605
            // instantiates the whiole object
559
        emp.getLastName();
606
            emp.getLastName();
560
607
561
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
608
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
562
        assertNoFetchGroup(emp);
609
            assertNoFetchGroup(emp);
563
610
564
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
611
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
565
            assertNoFetchGroup(phone);
612
                assertNoFetchGroup(phone);
566
            phone.getAreaCode();
613
                phone.getAreaCode();
614
            }
615
616
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
617
        } finally {
618
            if (isTransactionActive(em)){
619
                rollbackTransaction(em);
620
            }
621
            closeEntityManager(em);
567
        }
622
        }
568
569
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
570
    }
623
    }
571
624
572
    @Test
625
    @Test
573
    public void employeeNamesFetchGroup() throws Exception {
626
    public void employeeNamesFetchGroup() throws Exception {
574
        EntityManager em = createEntityManager();
627
        EntityManager em = createEntityManager();
628
        try {
629
            beginTransaction(em);
575
630
576
        int minId = minimumEmployeeId(em);
631
            int minId = minimumEmployeeId(em);
577
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
632
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
578
633
579
        // Use q query since find will only use default fetch group
634
            // Use q query since find will only use default fetch group
580
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
635
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
581
        query.setParameter("ID", minId);
636
            query.setParameter("ID", minId);
582
        FetchGroup namesFG = new FetchGroup();
637
            FetchGroup namesFG = new FetchGroup();
583
        namesFG.addAttribute("firstName");
638
            namesFG.addAttribute("firstName");
584
        namesFG.addAttribute("lastName");
639
            namesFG.addAttribute("lastName");
585
640
586
        query.setHint(QueryHints.FETCH_GROUP, namesFG);
641
            query.setHint(QueryHints.FETCH_GROUP, namesFG);
587
642
588
        assertNotNull(getFetchGroup(query));
643
            assertNotNull(getFetchGroup(query));
589
        assertSame(namesFG, getFetchGroup(query));
644
            assertSame(namesFG, getFetchGroup(query));
590
645
591
        Employee emp = (Employee) query.getSingleResult();
646
            Employee emp = (Employee) query.getSingleResult();
592
647
593
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
648
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
594
        assertFetched(emp, namesFG);
649
            assertFetched(emp, namesFG);
595
650
596
        emp.getId();
651
            emp.getId();
597
        emp.getFirstName();
652
            emp.getFirstName();
598
        emp.getLastName();
653
            emp.getLastName();
599
        emp.getVersion();
654
            emp.getVersion();
600
655
601
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
656
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
602
        assertFetched(emp, namesFG);
657
            assertFetched(emp, namesFG);
603
658
604
        emp.getGender();
659
            emp.getGender();
605
        emp.getSalary();
660
            emp.getSalary();
606
661
607
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
662
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
608
        assertNoFetchGroup(emp);
663
            assertNoFetchGroup(emp);
609
664
610
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
665
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
611
            assertNoFetchGroup(phone);
666
                assertNoFetchGroup(phone);
612
            phone.getAreaCode();
667
                phone.getAreaCode();
613
        }
668
            }
614
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
669
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
615
670
616
        if (emp.getManager() != null) {
671
            if (emp.getManager() != null) {
617
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
672
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
618
            assertNoFetchGroup(emp.getManager());
673
                assertNoFetchGroup(emp.getManager());
619
        } else {
674
            } else {
620
            // If manager_id field is null then getManager() does not trigger an sql.
675
                // If manager_id field is null then getManager() does not trigger an sql.
621
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
676
                assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
677
            }
678
        } finally {
679
            if (isTransactionActive(em)){
680
                rollbackTransaction(em);
681
            }
682
            closeEntityManager(em);
622
        }
683
        }
623
    }
684
    }
624
685
Lines 657-685 Link Here
657
    @Test
718
    @Test
658
    public void verifyUnfetchedAttributes() throws Exception {
719
    public void verifyUnfetchedAttributes() throws Exception {
659
        EntityManager em = createEntityManager();
720
        EntityManager em = createEntityManager();
721
        try {
722
            beginTransaction(em);
660
723
661
        TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class);
724
            TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class);
662
        FetchGroup fg = new FetchGroup("Employee.empty");
725
            FetchGroup fg = new FetchGroup("Employee.empty");
663
        q.setHint(QueryHints.FETCH_GROUP, fg);
726
            q.setHint(QueryHints.FETCH_GROUP, fg);
664
        Employee emp = q.getSingleResult();
727
            Employee emp = q.getSingleResult();
665
728
666
        assertNotNull(emp);
729
            assertNotNull(emp);
667
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
730
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
668
731
669
        // This check using the mapping returns a default (empty) IndirectList
732
            // This check using the mapping returns a default (empty) IndirectList
670
/*        OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers");
733
            /*OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers");
671
        IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp);
734
            IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp);
672
        assertNotNull(phones);
735
            assertNotNull(phones);
673
        assertTrue(phones.isInstantiated());
736
            assertTrue(phones.isInstantiated());
674
        assertEquals(0, phones.size());
737
            assertEquals(0, phones.size());
675
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/
738
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/
676
739
677
        IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers();
740
            IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers();
678
        assertFalse(phonesIL.isInstantiated());
741
            assertFalse(phonesIL.isInstantiated());
679
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
742
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
680
743
681
        assertTrue(emp.getPhoneNumbers().size() > 0);
744
            assertTrue(emp.getPhoneNumbers().size() > 0);
682
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
745
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
746
        } finally {
747
            if (isTransactionActive(em)){
748
                rollbackTransaction(em);
749
            }
750
            closeEntityManager(em);
751
        }
683
    }
752
    }
684
753
685
    @Test
754
    @Test
Lines 807-813 Link Here
807
        em.clear();
876
        em.clear();
808
        HashMap hints = new HashMap(2);
877
        HashMap hints = new HashMap(2);
809
        hints.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
878
        hints.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
810
//        hints.put(QueryHints.FETCH_GROUP, fetchGroup);
879
        //hints.put(QueryHints.FETCH_GROUP, fetchGroup);
811
        Employee empShared = em.find(Employee.class, id, hints);
880
        Employee empShared = em.find(Employee.class, id, hints);
812
        assertEquals("newFirstName", empShared.getFirstName());
881
        assertEquals("newFirstName", empShared.getFirstName());
813
        assertEquals("newLastName", empShared.getLastName());
882
        assertEquals("newLastName", empShared.getLastName());
Lines 855-861 Link Here
855
            closeEntityManager(em);
924
            closeEntityManager(em);
856
        }
925
        }
857
    }
926
    }
858
/*    public void simpleSerializeAndMerge() throws Exception {
927
    /*public void simpleSerializeAndMerge() throws Exception {
859
        EntityManager em = createEntityManager();
928
        EntityManager em = createEntityManager();
860
        int id = minimumEmployeeId(em);
929
        int id = minimumEmployeeId(em);
861
        // save the original Employee for clean up
930
        // save the original Employee for clean up
Lines 934-1053 Link Here
934
    public void partialMerge() throws Exception {
1003
    public void partialMerge() throws Exception {
935
        EntityManager em = createEntityManager();
1004
        EntityManager em = createEntityManager();
936
        // Search for an Employee with an Address and Phone Numbers 
1005
        // Search for an Employee with an Address and Phone Numbers 
937
        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);
1006
        try {
938
        
1007
            beginTransaction(em);
939
        // Load only its names and phone Numbers
1008
            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);
940
        FetchGroup fetchGroup = new FetchGroup();
1009
            
941
        fetchGroup.addAttribute("firstName");
1010
            // Load only its names and phone Numbers
942
        fetchGroup.addAttribute("lastName");
1011
            FetchGroup fetchGroup = new FetchGroup();
943
        FetchGroup phonesFG = phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
1012
            fetchGroup.addAttribute("firstName");
944
        // that ensures the owner is not instantiated
1013
            fetchGroup.addAttribute("lastName");
945
        phonesFG.addAttribute("owner.id");
1014
            FetchGroup phonesFG = phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
946
        phonesFG.removeAttribute("status");
1015
            // that ensures the owner is not instantiated
947
        phonesFG.setShouldLoad(true);
1016
            phonesFG.addAttribute("owner.id");
948
        fetchGroup.addAttribute("phoneNumbers", phonesFG);
1017
            phonesFG.removeAttribute("status");
949
        
1018
            phonesFG.setShouldLoad(true);
950
        // Make sure the FetchGroup also forces the relationships to be loaded
1019
            fetchGroup.addAttribute("phoneNumbers", phonesFG);
951
        fetchGroup.setShouldLoad(true);
1020
            
952
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
1021
            // Make sure the FetchGroup also forces the relationships to be loaded
953
        
1022
            fetchGroup.setShouldLoad(true);
954
        Employee emp = query.getSingleResult();
1023
            query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
955
        
1024
            
956
        // Detach Employee through Serialization
1025
            Employee emp = query.getSingleResult();
957
        Employee detachedEmp = (Employee) SerializationHelper.clone(emp);
1026
958
        // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
1027
            // Detach Employee through Serialization 
959
        detachedEmp.setFirstName(emp.getLastName());
1028
            Employee detachedEmp = (Employee)clone(emp);
960
        detachedEmp.setLastName(emp.getFirstName());
1029
961
        detachedEmp.addPhoneNumber(new PhoneNumber("TEST", "999", "999999"));
1030
            // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
962
        // NOte that salary was not part of the original FetchGroupdetachedEmp.setSalary(1);
1031
            detachedEmp.setFirstName(emp.getLastName());
963
        detachedEmp.setSalary(1);
1032
            detachedEmp.setLastName(emp.getFirstName());
964
        
1033
            detachedEmp.addPhoneNumber(new PhoneNumber("TEST", "999", "999999"));
965
        beginTransaction(em);
1034
            // NOte that salary was not part of the original FetchGroupdetachedEmp.setSalary(1);
966
        // Merge the detached employee
1035
            detachedEmp.setSalary(1);
967
        em.merge(detachedEmp);
1036
            
968
        // Flush the changes to the database
1037
            // Merge the detached employee
969
        em.flush();
1038
            em.merge(detachedEmp);
970
        rollbackTransaction(em);
1039
            // Flush the changes to the database
1040
            em.flush();
1041
        } finally {
1042
            rollbackTransaction(em);
1043
            closeEntityManager(em);
1044
        }
971
    }
1045
    }
972
1046
973
    public void copyGroupMerge() {
1047
    public void copyGroupMerge() {
974
        // Search for an Employee with an Address and Phone Numbers
1048
        // Search for an Employee with an Address and Phone Numbers
975
        EntityManager em = createEntityManager();
1049
        EntityManager em = createEntityManager();
976
        TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(ee.id) FROM Employee ee)", Employee.class);
1050
        try {
977
        Employee emp = query.getSingleResult();
1051
            beginTransaction(em);
978
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1052
            TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(ee.id) FROM Employee ee)", Employee.class);
979
        System.out.println(">>> Employee retrieved");
1053
            Employee emp = query.getSingleResult();
980
        
1054
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
981
        // Copy only its names and phone Numbers
1055
            System.out.println(">>> Employee retrieved");
982
        AttributeGroup group = new CopyGroup();
1056
            
983
        group.addAttribute("firstName");
1057
            // Copy only its names and phone Numbers
984
        group.addAttribute("lastName");
1058
            AttributeGroup group = new CopyGroup();
985
        group.addAttribute("address");
1059
            group.addAttribute("firstName");
986
        
1060
            group.addAttribute("lastName");
987
        Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);
1061
            group.addAttribute("address");
988
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1062
            
989
        System.out.println(">>> Employee copied");
1063
            Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);
990
        
1064
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
991
        // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
1065
            System.out.println(">>> Employee copied");
992
        empCopy.setFirstName(emp.getLastName());
1066
            
993
        empCopy.setLastName(emp.getFirstName());
1067
            // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
994
        
1068
            empCopy.setFirstName(emp.getLastName());
995
        // Note that salary was not part of the original FetchGroup
1069
            empCopy.setLastName(emp.getFirstName());
996
        //empCopy.setSalary(1);
1070
            
997
        
1071
            // Note that salary was not part of the original FetchGroup
998
        beginTransaction(em);
1072
            //empCopy.setSalary(1);
999
        // Merge the detached employee
1073
            
1000
        em.merge(empCopy);
1074
            // Merge the detached employee
1001
        System.out.println(">>> Sparse merge complete");
1075
            em.merge(empCopy);
1002
        
1076
            System.out.println(">>> Sparse merge complete");
1003
        // Flush the changes to the database
1077
            
1004
        em.flush();
1078
            // Flush the changes to the database
1005
        System.out.println(">>> Flush complete");
1079
            em.flush();
1006
        
1080
            System.out.println(">>> Flush complete");
1007
        rollbackTransaction(em);
1081
        } finally {
1082
            rollbackTransaction(em);
1083
            closeEntityManager(em);
1084
        }
1008
    }
1085
    }
1009
    
1086
    
1010
    public void copyGroupMerge2() {
1087
    public void copyGroupMerge2() {
1011
        // Search for an Employee with an Address and Phone Numbers
1088
        // Search for an Employee with an Address and Phone Numbers
1012
        EntityManager em = createEntityManager();
1089
        EntityManager em = createEntityManager();
1013
        TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e", Employee.class);
1090
        try {
1014
        query.setHint(QueryHints.BATCH, "e.address");
1091
            beginTransaction(em);
1015
        List<Employee> employees = query.getResultList();
1092
            TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e", Employee.class);
1016
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1093
            query.setHint(QueryHints.BATCH, "e.address");
1017
        System.out.println(">>> Employees retrieved");
1094
            List<Employee> employees = query.getResultList();
1018
        
1095
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1019
        // Copy only its names and phone Numbers
1096
            System.out.println(">>> Employees retrieved");
1020
        AttributeGroup group = new CopyGroup();
1021
        group.addAttribute("firstName");
1022
        group.addAttribute("lastName");
1023
        group.addAttribute("address");
1024
        
1025
        List<Employee> employeesCopy = (List<Employee>) em.unwrap(JpaEntityManager.class).copy(employees, group);
1026
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1027
        System.out.println(">>> Employees copied");
1028
        
1029
        beginTransaction(em);
1030
        for(Employee empCopy : employeesCopy) {
1031
            // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
1032
            String firstName = empCopy.getFirstName();
1033
            String lastName = empCopy.getLastName();
1034
            empCopy.setFirstName(lastName);
1035
            empCopy.setLastName(firstName);
1036
    
1037
            // Note that salary was not part of the original FetchGroup
1038
            //empCopy.setSalary(1);        
1039
            
1097
            
1040
            // Merge the detached employee
1098
            // Copy only its names and phone Numbers
1041
            em.merge(empCopy);
1099
            AttributeGroup group = new CopyGroup();
1100
            group.addAttribute("firstName");
1101
            group.addAttribute("lastName");
1102
            group.addAttribute("address");
1103
            
1104
            List<Employee> employeesCopy = (List<Employee>) em.unwrap(JpaEntityManager.class).copy(employees, group);
1105
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1106
            System.out.println(">>> Employees copied");
1107
            
1108
            for(Employee empCopy : employeesCopy) {
1109
                // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
1110
                String firstName = empCopy.getFirstName();
1111
                String lastName = empCopy.getLastName();
1112
                empCopy.setFirstName(lastName);
1113
                empCopy.setLastName(firstName);
1114
            
1115
                // Note that salary was not part of the original FetchGroup
1116
                //empCopy.setSalary(1);        
1117
                
1118
                // Merge the detached employee
1119
                em.merge(empCopy);
1120
            }
1121
            System.out.println(">>> Sparse merge complete");
1122
            
1123
            // Flush the changes to the database
1124
            em.flush();
1125
            System.out.println(">>> Flush complete");
1126
            
1127
        } finally {
1128
            rollbackTransaction(em);
1129
            closeEntityManager(em);
1042
        }
1130
        }
1043
        System.out.println(">>> Sparse merge complete");
1044
        
1045
        // Flush the changes to the database
1046
        em.flush();
1047
        System.out.println(">>> Flush complete");
1048
        
1049
        rollbackTransaction(em);
1050
    }
1131
    }
1132
1051
    
1133
    
1052
    @Test
1134
    @Test
1053
    public void copyWithPk() {
1135
    public void copyWithPk() {
Lines 1069-1075 Link Here
1069
        copyWithOrWithoutPk(true, true);
1151
        copyWithOrWithoutPk(true, true);
1070
    }
1152
    }
1071
1153
1072
    void copyWithOrWithoutPk(boolean noPk, boolean useFullGroup) {        
1154
    void copyWithOrWithoutPk(boolean noPk, boolean useFullGroup) {
1073
        CopyGroup group = new CopyGroup();
1155
        CopyGroup group = new CopyGroup();
1074
        if(noPk) {
1156
        if(noPk) {
1075
            // setShouldResetPrimaryKey set to true means that:
1157
            // setShouldResetPrimaryKey set to true means that:
Lines 1140-1150 Link Here
1140
        }
1222
        }
1141
        
1223
        
1142
        EntityManager em = createEntityManager();
1224
        EntityManager em = createEntityManager();
1143
        Employee emp = minimumEmployee(em);        
1144
        Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);
1145
        
1146
        beginTransaction(em);
1147
        try {
1225
        try {
1226
            beginTransaction(em);
1227
            Employee emp = minimumEmployee(em);
1228
            Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);
1229
            
1148
            if(noPk) {
1230
            if(noPk) {
1149
                assertNoFetchGroup(empCopy);
1231
                assertNoFetchGroup(empCopy);
1150
                assertNoFetchGroup(empCopy.getAddress());
1232
                assertNoFetchGroup(empCopy.getAddress());
Lines 1235-1388 Link Here
1235
    
1317
    
1236
    void copyCascade(int cascadeDepth) {
1318
    void copyCascade(int cascadeDepth) {
1237
        EntityManager em = createEntityManager();
1319
        EntityManager em = createEntityManager();
1238
        Query query = em.createQuery("SELECT e FROM Employee e");
1320
        try {
1239
        List<Employee> employees = query.getResultList();
1321
            beginTransaction(em);
1322
            Query query = em.createQuery("SELECT e FROM Employee e");
1323
            List<Employee> employees = query.getResultList();
1240
1324
1241
        CopyGroup group = new CopyGroup();
1325
            CopyGroup group = new CopyGroup();
1242
        if(cascadeDepth == CopyGroup.NO_CASCADE) {
1326
            if(cascadeDepth == CopyGroup.NO_CASCADE) {
1243
            group.dontCascade();
1327
                group.dontCascade();
1244
        } else if(cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1328
            } else if(cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1245
            // default cascade depth setting
1329
                // default cascade depth setting
1246
            group.cascadePrivateParts();
1330
                group.cascadePrivateParts();
1247
        } else if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) {
1331
            } else if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) {
1248
            group.cascadeAllParts();
1332
                group.cascadeAllParts();
1249
        } else {
1333
            } else {
1250
            fail("Invalid cascadeDepth = " + cascadeDepth);
1334
                fail("Invalid cascadeDepth = " + cascadeDepth);
1251
        }
1252
        group.setShouldResetPrimaryKey(true);
1253
        
1254
        List<Employee> employeesCopy;
1255
        if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1256
            // In this case the objects should be copied one by one - each one using a new CopyGroup.
1257
            // That ensures most referenced object are original ones (not copies) -
1258
            // the only exception is privately owned objects in CASCADE_PRIVATE_PARTS case.
1259
            employeesCopy = new ArrayList(employees.size());
1260
            for(Employee emp : employees) {
1261
                CopyGroup groupClone = group.clone();
1262
                employeesCopy.add((Employee)em.unwrap(JpaEntityManager.class).copy(emp, groupClone));
1263
            }
1335
            }
1264
        } else {
1336
            group.setShouldResetPrimaryKey(true);
1265
            // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1337
            
1266
            // In this case all objects should be copied using a single CopyGroup.
1338
            List<Employee> employeesCopy;
1267
            // That ensures identities of the copies:
1339
            if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1268
            // for instance if several employees referenced the same project,
1340
                // In this case the objects should be copied one by one - each one using a new CopyGroup.
1269
            // then all copies of these employees will reference the single copy of the project. 
1341
                // That ensures most referenced object are original ones (not copies) -
1270
            employeesCopy = (List)em.unwrap(JpaEntityManager.class).copy(employees, group);
1342
                // the only exception is privately owned objects in CASCADE_PRIVATE_PARTS case.
1271
        }
1343
                employeesCopy = new ArrayList(employees.size());
1272
        
1344
                for(Employee emp : employees) {
1273
        // IdentityHashSets will be used to verify copy identities
1345
                    CopyGroup groupClone = group.clone();
1274
        IdentityHashSet originalEmployees = new IdentityHashSet();
1346
                    employeesCopy.add((Employee)em.unwrap(JpaEntityManager.class).copy(emp, groupClone));
1275
        IdentityHashSet copyEmployees = new IdentityHashSet();
1347
                }
1276
        IdentityHashSet originalAddresses = new IdentityHashSet();
1277
        IdentityHashSet copyAddresses = new IdentityHashSet();
1278
        IdentityHashSet originalProjects = new IdentityHashSet();
1279
        IdentityHashSet copyProjects = new IdentityHashSet();
1280
        IdentityHashSet originalPhones = new IdentityHashSet();
1281
        IdentityHashSet copyPhones = new IdentityHashSet();
1282
        
1283
        int size = employees.size();
1284
        for(int i=0; i < size; i++) {
1285
            Employee emp = employees.get(i);
1286
            Employee empCopy = employeesCopy.get(i);
1287
            if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) {
1288
                originalEmployees.add(emp);
1289
                copyEmployees.add(empCopy);
1290
            } else {
1348
            } else {
1291
                // cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS
1349
                // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1292
                // In this case all Employees referenced by empCopyes are originals (manager and managed employees).
1350
                // In this case all objects should be copied using a single CopyGroup.
1293
                // Therefore if we add here each emp and empCopy to originalEmployees and copyEmployees respectively
1351
                // That ensures identities of the copies:
1294
                // then copyEmployees will always contain all original managers and managed + plus all copies.
1352
                // for instance if several employees referenced the same project,
1295
                // Therefore in this case originalEmployees and copyEmployees will contain only references (managers and managed employees).
1353
                // then all copies of these employees will reference the single copy of the project. 
1354
                employeesCopy = (List)em.unwrap(JpaEntityManager.class).copy(employees, group);
1296
            }
1355
            }
1356
            
1357
            // IdentityHashSets will be used to verify copy identities
1358
            IdentityHashSet originalEmployees = new IdentityHashSet();
1359
            IdentityHashSet copyEmployees = new IdentityHashSet();
1360
            IdentityHashSet originalAddresses = new IdentityHashSet();
1361
            IdentityHashSet copyAddresses = new IdentityHashSet();
1362
            IdentityHashSet originalProjects = new IdentityHashSet();
1363
            IdentityHashSet copyProjects = new IdentityHashSet();
1364
            IdentityHashSet originalPhones = new IdentityHashSet();
1365
            IdentityHashSet copyPhones = new IdentityHashSet();
1366
            
1367
            int size = employees.size();
1368
            for(int i=0; i < size; i++) {
1369
                Employee emp = employees.get(i);
1370
                Employee empCopy = employeesCopy.get(i);
1371
                if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) {
1372
                    originalEmployees.add(emp);
1373
                    copyEmployees.add(empCopy);
1374
                } else {
1375
                    // cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS
1376
                    // In this case all Employees referenced by empCopyes are originals (manager and managed employees).
1377
                    // Therefore if we add here each emp and empCopy to originalEmployees and copyEmployees respectively
1378
                    // then copyEmployees will always contain all original managers and managed + plus all copies.
1379
                    // Therefore in this case originalEmployees and copyEmployees will contain only references (managers and managed employees).
1380
                }
1297
1381
1298
            if(emp.getAddress() == null) {
1382
                if(emp.getAddress() == null) {
1299
                assertTrue("emp.getAddress() == null, but empCopy.getAddress() != null", empCopy.getAddress() == null);
1383
                    assertTrue("emp.getAddress() == null, but empCopy.getAddress() != null", empCopy.getAddress() == null);
1300
            } else {
1301
                originalAddresses.add(emp.getAddress());
1302
                copyAddresses.add(empCopy.getAddress());
1303
                if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1304
                    assertTrue("address has been copied", emp.getAddress() == empCopy.getAddress());
1305
                } else {
1384
                } else {
1306
                    // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1385
                    originalAddresses.add(emp.getAddress());
1307
                    assertFalse("address has not been copied", emp.getAddress() == empCopy.getAddress());
1386
                    copyAddresses.add(empCopy.getAddress());
1387
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1388
                        assertTrue("address has been copied", emp.getAddress() == empCopy.getAddress());
1389
                    } else {
1390
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1391
                        assertFalse("address has not been copied", emp.getAddress() == empCopy.getAddress());
1392
                    }
1308
                }
1393
                }
1309
            }
1310
1394
1311
            boolean same;
1395
                boolean same;
1312
            for(Project project : emp.getProjects()) {
1396
                for(Project project : emp.getProjects()) {
1313
                originalProjects.add(project);
1397
                    originalProjects.add(project);
1314
                same = false;
1398
                    same = false;
1315
                for(Project projectCopy : empCopy.getProjects()) {
1399
                    for(Project projectCopy : empCopy.getProjects()) {
1316
                    copyProjects.add(projectCopy);
1400
                        copyProjects.add(projectCopy);
1317
                    if(!same && project == projectCopy) {
1401
                        if(!same && project == projectCopy) {
1318
                        same = true;
1402
                            same = true;
1403
                        }
1319
                    }
1404
                    }
1405
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1406
                        assertTrue("project has been copied", same);
1407
                    } else {
1408
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1409
                        assertFalse("project has not been copied", same);
1410
                    }
1320
                }
1411
                }
1321
                if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1322
                    assertTrue("project has been copied", same);
1323
                } else {
1324
                    // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1325
                    assertFalse("project has not been copied", same);
1326
                }
1327
            }
1328
            
1412
            
1329
            for(Employee managedEmp : emp.getManagedEmployees()) {
1413
                for(Employee managedEmp : emp.getManagedEmployees()) {
1330
                originalEmployees.add(managedEmp);
1414
                    originalEmployees.add(managedEmp);
1331
                same = false;
1415
                    same = false;
1332
                for(Employee managedEmpCopy : empCopy.getManagedEmployees()) {
1416
                    for(Employee managedEmpCopy : empCopy.getManagedEmployees()) {
1333
                    copyEmployees.add(managedEmpCopy);
1417
                        copyEmployees.add(managedEmpCopy);
1334
                    if(!same && managedEmp == managedEmpCopy) {
1418
                        if(!same && managedEmp == managedEmpCopy) {
1335
                        same = true;
1419
                            same = true;
1420
                        }
1336
                    }
1421
                    }
1422
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1423
                        assertTrue("managedEmployee has been copied", same);
1424
                    } else {
1425
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1426
                        assertFalse("managedEmployee has not been copied", same);
1427
                    }
1337
                }
1428
                }
1338
                if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1429
                
1339
                    assertTrue("managedEmployee has been copied", same);
1430
                if(emp.getManager() == null) {
1431
                    assertTrue("emp.getManager() == null, but empCopy.getManager() != null", empCopy.getManager() == null);
1340
                } else {
1432
                } else {
1341
                    // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1433
                    originalEmployees.add(emp.getManager());
1342
                    assertFalse("managedEmployee has not been copied", same);
1434
                    copyEmployees.add(empCopy.getManager());
1435
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1436
                        assertTrue("manager has been copied", emp.getManager() == empCopy.getManager());
1437
                    } else {
1438
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1439
                        assertFalse("manager has not been copied", emp.getManager() == empCopy.getManager());
1440
                    }
1343
                }
1441
                }
1344
            }
1345
            
1346
            if(emp.getManager() == null) {
1347
                assertTrue("emp.getManager() == null, but empCopy.getManager() != null", empCopy.getManager() == null);
1348
            } else {
1349
                originalEmployees.add(emp.getManager());
1350
                copyEmployees.add(empCopy.getManager());
1351
                if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1352
                    assertTrue("manager has been copied", emp.getManager() == empCopy.getManager());
1353
                } else {
1354
                    // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1355
                    assertFalse("manager has not been copied", emp.getManager() == empCopy.getManager());
1356
                }
1357
            }
1358
1442
1359
            // phoneNumbers is privately owned
1443
                // phoneNumbers is privately owned
1360
            for(PhoneNumber phone : emp.getPhoneNumbers()) {
1444
                for(PhoneNumber phone : emp.getPhoneNumbers()) {
1361
                originalPhones.add(phone);
1445
                    originalPhones.add(phone);
1362
                same = false;
1446
                    same = false;
1363
                for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) {
1447
                    for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) {
1364
                    copyPhones.add(phoneCopy);
1448
                        copyPhones.add(phoneCopy);
1365
                    if(!same && phone == phoneCopy) {
1449
                        if(!same && phone == phoneCopy) {
1366
                        same = true;
1450
                            same = true;
1451
                        }
1367
                    }
1452
                    }
1453
                    if(cascadeDepth == CopyGroup.NO_CASCADE) {
1454
                        assertTrue("phone has been copied", same);
1455
                    } else {
1456
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS
1457
                        assertFalse("phone has not been copied", same);
1458
                    }
1368
                }
1459
                }
1369
                if(cascadeDepth == CopyGroup.NO_CASCADE) {
1370
                    assertTrue("phone has been copied", same);
1371
                } else {
1372
                    // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS
1373
                    assertFalse("phone has not been copied", same);
1374
                }
1375
            }
1460
            }
1461
            
1462
            assertTrue("copyEmployees.size() == " + copyEmployees.size() + "; was expected " + originalEmployees.size(), originalEmployees.size() == copyEmployees.size());
1463
            assertTrue("copyAddresses.size() == " + copyAddresses.size() + "; was expected " + originalAddresses.size(), originalAddresses.size() == copyAddresses.size());
1464
            assertTrue("copyProjects.size() == " + copyProjects.size() + "; was expected " + originalProjects.size(), originalProjects.size() == copyProjects.size());
1465
            assertTrue("copyPhones.size() == " + copyPhones.size() + "; was expected " + originalPhones.size(), originalPhones.size() == copyPhones.size());
1466
        } finally {
1467
            if(isTransactionActive(em)) {
1468
                rollbackTransaction(em);
1469
            }
1376
        }
1470
        }
1377
        
1378
        assertTrue("copyEmployees.size() == " + copyEmployees.size() + "; was expected " + originalEmployees.size(), originalEmployees.size() == copyEmployees.size());
1379
        assertTrue("copyAddresses.size() == " + copyAddresses.size() + "; was expected " + originalAddresses.size(), originalAddresses.size() == copyAddresses.size());
1380
        assertTrue("copyProjects.size() == " + copyProjects.size() + "; was expected " + originalProjects.size(), originalProjects.size() == copyProjects.size());
1381
        assertTrue("copyPhones.size() == " + copyPhones.size() + "; was expected " + originalPhones.size(), originalPhones.size() == copyPhones.size());
1382
    }
1471
    }
1383
    
1472
    
1384
    private <T> T serialize(Serializable entity) throws IOException, ClassNotFoundException {
1473
    private <T> T serialize(Serializable entity) throws IOException, ClassNotFoundException {
1385
        byte[] bytes = SerializationHelper.serialize(entity);
1474
        byte[] bytes = SerializationHelper.serialize(entity);
1386
        return (T) SerializationHelper.deserialize(bytes);
1475
        ObjectInputStream inStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
1476
        return (T) inStream.readObject();
1387
    }
1477
    }
1478
1479
    private Object clone(Serializable object) throws IOException, ClassNotFoundException {
1480
        byte[] bytes = SerializationHelper.serialize(object);
1481
        ObjectInputStream inStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
1482
        return inStream.readObject();
1483
    }
1388
}
1484
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/BaseFetchGroupTests.java (-3 / +6 lines)
Lines 74-81 Link Here
74
     * Fetch Group tests require weaving.
74
     * Fetch Group tests require weaving.
75
     */
75
     */
76
    public void runBare() throws Throwable {
76
    public void runBare() throws Throwable {
77
        if (isWeavingEnabled("fieldaccess")) {
77
        if (this.shouldRunTestOnServer()) {
78
            super.runBare();
78
            super.runBare();
79
        } else {
80
           if (isWeavingEnabled("fieldaccess")) {
81
                super.runBare();
82
            }
79
        }
83
        }
80
    }
84
    }
81
85
Lines 448-455 Link Here
448
    }
452
    }
449
    
453
    
450
    protected QuerySQLTracker getQuerySQLTracker(EntityManager em) {
454
    protected QuerySQLTracker getQuerySQLTracker(EntityManager em) {
451
        return QuerySQLTracker.getTracker(JpaHelper.getEntityManager(em)
455
        return QuerySQLTracker.getTracker(getServerSession("fieldaccess"));
452
                .getActiveSession());
453
    }
456
    }
454
457
455
    ClassDescriptor getDescriptor(String entityName) {
458
    ClassDescriptor getDescriptor(String entityName) {
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FAServerTestSuite.java (+37 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     Oracle - initial API and implementation from Oracle TopLink
12
 ******************************************************************************/  
13
package org.eclipse.persistence.testing.tests.jpa.fieldaccess.fetchgroups;
14
15
import junit.framework.TestSuite;
16
import junit.framework.Test;
17
18
/**
19
 * <p><b>Purpose</b>: To collect the tests that will run against Application Server only.
20
 */
21
public class FAServerTestSuite extends TestSuite {
22
    
23
    public static Test suite() {
24
        TestSuite suite = new TestSuite();
25
        suite.setName("FieldAccess FetchGroups ServerTestSuite");
26
        suite.addTest(FetchGroupMergeWithCacheTests.suite());
27
        suite.addTest(FetchGroupTrackerWeavingTests.suite());
28
        suite.addTest(NestedDefaultFetchGroupTests.suite());
29
        suite.addTest(NestedFetchGroupTests.suite());
30
        suite.addTest(NestedNamedFetchGroupTests.suite());
31
        suite.addTest(SimpleDefaultFetchGroupTests.suite()); 
32
        suite.addTest(SimpleFetchGroupTests.suite());
33
        suite.addTest(SimpleNamedFetchGroupTests.suite());
34
        suite.addTest(SimpleSerializeFetchGroupTests.suite());
35
        return suite;
36
    }
37
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FetchGroupMergeWithCacheTests.java (-2 / +3 lines)
Lines 40-47 Link Here
40
        
40
        
41
        suite.addTest(new FetchGroupMergeWithCacheTests("testSetup"));
41
        suite.addTest(new FetchGroupMergeWithCacheTests("testSetup"));
42
        suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_QueryWithFetchGroup_Simple"));
42
        suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_QueryWithFetchGroup_Simple"));
43
        suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_FindWithFetchGroup_Simple"));
43
        if (!isJPA10()) {
44
        
44
            suite.addTest(new FetchGroupMergeWithCacheTests("cacheFull_FindWithFetchGroup_Simple"));
45
        }
45
        return suite;
46
        return suite;
46
    }
47
    }
47
48
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/FetchGroupTrackerWeavingTests.java (-2 / +6 lines)
Lines 56-66 Link Here
56
     * Fetch Group tests require weaving.
56
     * Fetch Group tests require weaving.
57
     */
57
     */
58
    public void runBare() throws Throwable {
58
    public void runBare() throws Throwable {
59
        if (isWeavingEnabled("fieldaccess")) {
59
        if (this.shouldRunTestOnServer()) {
60
            super.runBare();
60
            super.runBare();
61
        } else {
62
           if (isWeavingEnabled("fieldaccess")) {
63
                super.runBare();
64
            }
61
        }
65
        }
62
    }
66
    }
63
67
    
64
    public static junit.framework.Test suite() {
68
    public static junit.framework.Test suite() {
65
        TestSuite suite = new TestSuite();
69
        TestSuite suite = new TestSuite();
66
        suite.setName("FetchGroupTrackerWeavingTests");
70
        suite.setName("FetchGroupTrackerWeavingTests");
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedDefaultFetchGroupTests.java (-8 / +15 lines)
Lines 56-70 Link Here
56
        
56
        
57
        suite.addTest(new NestedDefaultFetchGroupTests("testSetup"));
57
        suite.addTest(new NestedDefaultFetchGroupTests("testSetup"));
58
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployee"));
58
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployee"));
59
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddress"));
60
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadPhones"));
61
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhones"));
62
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhoneUsingFetchGroup"));
59
        suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhoneUsingFetchGroup"));
63
        suite.addTest(new NestedDefaultFetchGroupTests("allAddress"));
60
        if (!isJPA10()) {
64
        suite.addTest(new NestedDefaultFetchGroupTests("allPhone"));
61
            suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddress"));
65
        suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddress"));
62
            suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadPhones"));
66
        suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddressLoad"));
63
            suite.addTest(new NestedDefaultFetchGroupTests("findMinEmployeeLoadAddressAndPhones"));
67
        
64
            suite.addTest(new NestedDefaultFetchGroupTests("allAddress"));
65
            suite.addTest(new NestedDefaultFetchGroupTests("allPhone"));
66
            suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddress"));
67
            suite.addTest(new NestedDefaultFetchGroupTests("singleResultMinEmployeeFetchJoinAddressLoad"));
68
        }
68
        return suite;
69
        return suite;
69
    }
70
    }
70
    
71
    
Lines 117-122 Link Here
117
118
118
    void internalFindMinEmployee(boolean loadAddress, boolean loadPhones, boolean useLoadGroup) {        
119
    void internalFindMinEmployee(boolean loadAddress, boolean loadPhones, boolean useLoadGroup) {        
119
        EntityManager em = createEntityManager("fieldaccess");
120
        EntityManager em = createEntityManager("fieldaccess");
121
        beginTransaction(em);
122
120
        int minId = minEmployeeIdWithAddressAndPhones(em);
123
        int minId = minEmployeeIdWithAddressAndPhones(em);
121
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
124
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
122
125
Lines 188-193 Link Here
188
                    defaultEmployeeFG.setShouldLoad(originalLoad);
191
                    defaultEmployeeFG.setShouldLoad(originalLoad);
189
                }
192
                }
190
            }
193
            }
194
            if (isTransactionActive(em)){
195
                rollbackTransaction(em);
196
            }
197
            closeEntityManager(em);
191
        }
198
        }
192
    }
199
    }
193
/*    void internalFindMinEmployee(boolean loadAddress, boolean loadPhones) {
200
/*    void internalFindMinEmployee(boolean loadAddress, boolean loadPhones) {
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedFetchGroupTests.java (-548 / +620 lines)
Lines 97-294 Link Here
97
    @Test
97
    @Test
98
    public void dynamicFetchGroup_EmployeeAddress() throws Exception {
98
    public void dynamicFetchGroup_EmployeeAddress() throws Exception {
99
        EntityManager em = createEntityManager("fieldaccess");
99
        EntityManager em = createEntityManager("fieldaccess");
100
        try {
101
            beginTransaction(em);
100
102
101
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
103
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
102
        query.setParameter("GENDER", Gender.Male);
104
            query.setParameter("GENDER", Gender.Male);
103
105
104
        // Define the fields to be fetched on Employee
106
            // Define the fields to be fetched on Employee
105
        FetchGroup fg = new FetchGroup();
107
            FetchGroup fg = new FetchGroup();
106
        fg.addAttribute("id");
108
            fg.addAttribute("id");
107
        fg.addAttribute("version");
109
            fg.addAttribute("version");
108
        fg.addAttribute("firstName");
110
            fg.addAttribute("firstName");
109
        fg.addAttribute("lastName");
111
            fg.addAttribute("lastName");
110
        fg.addAttribute("address.city");
112
            fg.addAttribute("address.city");
111
        fg.addAttribute("address.postalCode");
113
            fg.addAttribute("address.postalCode");
112
114
113
        // Configure the dynamic FetchGroup
115
            // Configure the dynamic FetchGroup
114
        query.setHint(QueryHints.FETCH_GROUP, fg);
116
            query.setHint(QueryHints.FETCH_GROUP, fg);
115
117
116
        List<Employee> emps = query.getResultList();
118
            List<Employee> emps = query.getResultList();
117
119
118
        assertNotNull(emps);
120
            assertNotNull(emps);
119
        for (Employee emp : emps) {
121
            for (Employee emp : emps) {
120
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
122
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
121
123
122
            assertNotNull(tracker._persistence_getFetchGroup());
124
                assertNotNull(tracker._persistence_getFetchGroup());
123
125
124
            // Verify specified fields plus mandatory ones are loaded
126
                // Verify specified fields plus mandatory ones are loaded
125
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
127
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
126
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
128
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
127
            assertTrue(tracker._persistence_isAttributeFetched("address"));
129
                assertTrue(tracker._persistence_isAttributeFetched("address"));
128
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
130
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
129
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
131
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
130
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
132
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
131
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
133
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
132
134
133
            // Verify the other fields are not loaded
135
                // Verify the other fields are not loaded
134
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
136
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
135
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
137
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
136
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
138
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
137
139
138
            // Force the loading of lazy fields and verify
140
                // Force the loading of lazy fields and verify
139
            emp.getSalary();
141
                emp.getSalary();
140
142
141
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
143
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
142
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
144
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
143
            assertTrue(tracker._persistence_isAttributeFetched("address"));
145
                assertTrue(tracker._persistence_isAttributeFetched("address"));
144
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
146
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
145
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
147
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
146
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
148
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
147
149
148
            // Now we'll check the address uses the provided dynamic fetch-group
150
                // Now we'll check the address uses the provided dynamic fetch-group
149
            addrTracker = (FetchGroupTracker) emp.getAddress();
151
                addrTracker = (FetchGroupTracker) emp.getAddress();
150
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
152
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
151
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
153
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
152
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
154
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
153
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
155
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
154
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
156
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
155
157
156
            // Now we'll check the phoneNumbers use of the default fetch group
158
                // Now we'll check the phoneNumbers use of the default fetch group
157
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
159
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
158
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
160
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
159
                assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
161
                    assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
160
                assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
162
                    assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
161
                assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
163
                    assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
164
                }
162
            }
165
            }
166
        } finally {
167
            if (isTransactionActive(em)){
168
                rollbackTransaction(em);
169
            }
170
            closeEntityManager(em);
163
        }
171
        }
164
    }
172
    }
165
173
166
    @Test
174
    @Test
167
    public void dynamicFetchGroup_Employee_NullAddress() throws Exception {
175
    public void dynamicFetchGroup_Employee_NullAddress() throws Exception {
168
        EntityManager em = createEntityManager("fieldaccess");
176
        EntityManager em = createEntityManager("fieldaccess");
177
        try {
178
            beginTransaction(em);
169
179
170
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
180
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
171
        query.setParameter("GENDER", Gender.Male);
181
            query.setParameter("GENDER", Gender.Male);
172
182
173
        // Define the fields to be fetched on Employee
183
            // Define the fields to be fetched on Employee
174
        FetchGroup empGroup = new FetchGroup();
184
            FetchGroup empGroup = new FetchGroup();
175
        empGroup.addAttribute("firstName");
185
            empGroup.addAttribute("firstName");
176
        empGroup.addAttribute("lastName");
186
            empGroup.addAttribute("lastName");
177
        empGroup.addAttribute("address");
187
            empGroup.addAttribute("address");
178
188
179
        // Define the fields to be fetched on Address
189
            // Define the fields to be fetched on Address
180
        FetchGroup addressGroup = new FetchGroup();
190
            FetchGroup addressGroup = new FetchGroup();
181
        addressGroup.addAttribute("city");
191
            addressGroup.addAttribute("city");
182
        addressGroup.addAttribute("postalCode");
192
            addressGroup.addAttribute("postalCode");
183
193
184
        empGroup.addAttribute("address");
194
            empGroup.addAttribute("address");
185
195
186
        // Configure the dynamic FetchGroup
196
            // Configure the dynamic FetchGroup
187
        query.setHint(QueryHints.FETCH_GROUP, empGroup);
197
            query.setHint(QueryHints.FETCH_GROUP, empGroup);
188
198
189
        List<Employee> emps = query.getResultList();
199
            List<Employee> emps = query.getResultList();
190
200
191
        assertNotNull(emps);
201
            assertNotNull(emps);
192
        for (Employee emp : emps) {
202
            for (Employee emp : emps) {
193
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
203
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
194
204
195
            assertNotNull(tracker._persistence_getFetchGroup());
205
                assertNotNull(tracker._persistence_getFetchGroup());
196
206
197
            // Verify specified fields plus mandatory ones are loaded
207
                // Verify specified fields plus mandatory ones are loaded
198
            assertTrue(tracker._persistence_isAttributeFetched("id"));
208
                assertTrue(tracker._persistence_isAttributeFetched("id"));
199
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
209
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
200
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
210
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
201
            assertTrue(tracker._persistence_isAttributeFetched("version"));
211
                assertTrue(tracker._persistence_isAttributeFetched("version"));
202
212
203
            // Verify the other fields are not loaded
213
                // Verify the other fields are not loaded
204
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
214
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
205
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
215
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
206
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
216
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
207
217
208
            // Force the loading of lazy fields and verify
218
                // Force the loading of lazy fields and verify
209
            emp.getSalary();
219
                emp.getSalary();
210
220
211
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
221
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
212
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
222
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
213
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
223
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
214
224
215
            // Now we'll check the address uses the provided dynamic fetch-group
225
                // Now we'll check the address uses the provided dynamic fetch-group
216
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
226
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
217
            assertNull("Address has an unexpected FetchGroup", addrTracker._persistence_getFetchGroup());
227
                assertNull("Address has an unexpected FetchGroup", addrTracker._persistence_getFetchGroup());
218
228
219
            // Now we'll check the phoneNumbers use of the default fetch group
229
                // Now we'll check the phoneNumbers use of the default fetch group
220
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
230
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
221
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
231
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
222
                assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
232
                    assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
223
                assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
233
                    assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
224
                assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
234
                    assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
235
                }
225
            }
236
            }
237
        } finally {
238
            if (isTransactionActive(em)){
239
                rollbackTransaction(em);
240
            }
241
            closeEntityManager(em);
226
        }
242
        }
227
    }
243
    }
228
244
229
    @Test
245
    @Test
230
    public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception {
246
    public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception {
231
        EntityManager em = createEntityManager("fieldaccess");
247
        EntityManager em = createEntityManager("fieldaccess");
248
        try {
249
            beginTransaction(em);
232
250
233
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
251
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
234
        query.setParameter("GENDER", Gender.Male);
252
            query.setParameter("GENDER", Gender.Male);
235
253
236
        // Define the fields to be fetched on Employee
254
            // Define the fields to be fetched on Employee
237
        FetchGroup empGroup = new FetchGroup();
255
            FetchGroup empGroup = new FetchGroup();
238
        empGroup.addAttribute("firstName");
256
            empGroup.addAttribute("firstName");
239
        empGroup.addAttribute("lastName");
257
            empGroup.addAttribute("lastName");
240
        empGroup.addAttribute("address");
258
            empGroup.addAttribute("address");
241
        empGroup.addAttribute("address.city");
259
            empGroup.addAttribute("address.city");
242
        empGroup.addAttribute("address.postalCode");
260
            empGroup.addAttribute("address.postalCode");
243
261
244
//        empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false);
262
            //empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false);
245
        FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
263
            FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
246
        // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
264
            // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
247
        fullPhone.addAttribute("owner.id");
265
            fullPhone.addAttribute("owner.id");
248
        empGroup.addAttribute("phoneNumbers", fullPhone);
266
            empGroup.addAttribute("phoneNumbers", fullPhone);
249
267
250
        // Configure the dynamic FetchGroup
268
            // Configure the dynamic FetchGroup
251
        query.setHint(QueryHints.FETCH_GROUP, empGroup);
269
            query.setHint(QueryHints.FETCH_GROUP, empGroup);
252
270
253
        List<Employee> emps = query.getResultList();
271
            List<Employee> emps = query.getResultList();
254
272
255
        assertNotNull(emps);
273
            assertNotNull(emps);
256
        for (Employee emp : emps) {
274
            for (Employee emp : emps) {
257
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
275
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
258
276
259
            assertNotNull(tracker._persistence_getFetchGroup());
277
                assertNotNull(tracker._persistence_getFetchGroup());
260
278
261
            // Verify specified fields plus mandatory ones are loaded
279
                // Verify specified fields plus mandatory ones are loaded
262
            assertTrue(tracker._persistence_isAttributeFetched("id"));
280
                assertTrue(tracker._persistence_isAttributeFetched("id"));
263
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
281
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
264
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
282
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
265
            assertTrue(tracker._persistence_isAttributeFetched("version"));
283
                assertTrue(tracker._persistence_isAttributeFetched("version"));
266
284
267
            // Verify the other fields are not loaded
285
                // Verify the other fields are not loaded
268
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
286
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
269
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
287
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
270
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
288
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
271
289
272
            // Force the loading of lazy fields and verify
290
                // Force the loading of lazy fields and verify
273
            emp.getSalary();
291
                emp.getSalary();
274
292
275
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
293
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
276
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
294
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
277
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
295
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
278
296
279
            // Now we'll check the address uses the provided dynamic fetch-group
297
                // Now we'll check the address uses the provided dynamic fetch-group
280
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
298
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
281
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
299
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
282
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
300
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
283
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
301
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
284
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
302
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
285
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
303
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
286
304
287
            // Now we'll check the phoneNumbers use of the default fetch group
305
                // Now we'll check the phoneNumbers use of the default fetch group
288
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
306
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
289
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
307
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
290
                assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup());
308
                    assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup());
309
                }
291
            }
310
            }
311
        } finally {
312
            if (isTransactionActive(em)){
313
                rollbackTransaction(em);
314
            }
315
            closeEntityManager(em);
292
        }
316
        }
293
    }
317
    }
294
318
Lines 301-376 Link Here
301
    }
325
    }
302
    void internal_dynamicFetchGroup_EmployeeAddressEmptyPhone(boolean shouldLoad) {
326
    void internal_dynamicFetchGroup_EmployeeAddressEmptyPhone(boolean shouldLoad) {
303
        EntityManager em = createEntityManager("fieldaccess");
327
        EntityManager em = createEntityManager("fieldaccess");
328
        try {
329
            beginTransaction(em);
304
330
305
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
331
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
306
        query.setParameter("GENDER", Gender.Male);
332
            query.setParameter("GENDER", Gender.Male);
307
333
308
        // Define the fields to be fetched on Employee
334
            // Define the fields to be fetched on Employee
309
        FetchGroup fg = new FetchGroup();
335
            FetchGroup fg = new FetchGroup();
310
        fg.addAttribute("firstName");
336
            fg.addAttribute("firstName");
311
        fg.addAttribute("lastName");
337
            fg.addAttribute("lastName");
312
        fg.addAttribute("address.city");
338
            fg.addAttribute("address.city");
313
        fg.addAttribute("address.postalCode");
339
            fg.addAttribute("address.postalCode");
314
        // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
340
            // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
315
        FetchGroup ownerId = new FetchGroup();
341
            FetchGroup ownerId = new FetchGroup();
316
        ownerId.addAttribute("owner.id");
342
            ownerId.addAttribute("owner.id");
317
        fg.addAttribute("phoneNumbers", ownerId);
343
            fg.addAttribute("phoneNumbers", ownerId);
318
        
344
            
319
        if(shouldLoad) {
345
            if(shouldLoad) {
320
            fg.setShouldLoad(true);
346
                fg.setShouldLoad(true);
321
        }
347
            }
322
348
323
        // Configure the dynamic FetchGroup
349
            // Configure the dynamic FetchGroup
324
        query.setHint(QueryHints.FETCH_GROUP, fg);
350
            query.setHint(QueryHints.FETCH_GROUP, fg);
325
351
326
        List<Employee> emps = query.getResultList();
352
            List<Employee> emps = query.getResultList();
327
353
328
        assertNotNull(emps);
354
            assertNotNull(emps);
329
        assertEquals(1 + (shouldLoad ? 0 : (emps.size() * 2)), getQuerySQLTracker(em).getTotalSQLSELECTCalls());
355
            assertEquals(1 + (shouldLoad ? 0 : (emps.size() * 2)), getQuerySQLTracker(em).getTotalSQLSELECTCalls());
330
        
356
            
331
        for (Employee emp : emps) {
357
            for (Employee emp : emps) {
332
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
358
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
333
359
334
            assertNotNull(tracker._persistence_getFetchGroup());
360
                assertNotNull(tracker._persistence_getFetchGroup());
335
361
336
            // Verify specified fields plus mandatory ones are loaded
362
                // Verify specified fields plus mandatory ones are loaded
337
            assertTrue(tracker._persistence_isAttributeFetched("id"));
363
                assertTrue(tracker._persistence_isAttributeFetched("id"));
338
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
364
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
339
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
365
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
340
            assertTrue(tracker._persistence_isAttributeFetched("version"));
366
                assertTrue(tracker._persistence_isAttributeFetched("version"));
341
367
342
            // Verify the other fields are not loaded
368
                // Verify the other fields are not loaded
343
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
369
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
344
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
370
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
345
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
371
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
346
372
347
            // Force the loading of lazy fields and verify
373
                // Force the loading of lazy fields and verify
348
            emp.getSalary();
374
                emp.getSalary();
349
375
350
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
376
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
351
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
377
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
352
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
378
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
353
379
354
            // Now we'll check the address uses the provided dynamic fetch-group
380
                // Now we'll check the address uses the provided dynamic fetch-group
355
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
381
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
356
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
382
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
357
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
383
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
358
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
384
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
359
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
385
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
360
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
386
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
361
387
362
            // Now we'll check the phoneNumbers use of the default fetch group
388
                // Now we'll check the phoneNumbers use of the default fetch group
363
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
389
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
364
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
390
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
365
                assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
391
                    assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
366
                assertFalse(phoneTracker._persistence_isAttributeFetched("number"));
392
                    assertFalse(phoneTracker._persistence_isAttributeFetched("number"));
367
                assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
393
                    assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
368
394
369
                phone.getNumber();
395
                    phone.getNumber();
370
396
371
                assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
397
                    assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
372
                assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode"));
398
                    assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode"));
399
                }
373
            }
400
            }
401
        } finally {
402
            if (isTransactionActive(em)){
403
                rollbackTransaction(em);
404
            }
405
            closeEntityManager(em);
374
        }
406
        }
375
    }
407
    }
376
408
Lines 421-552 Link Here
421
    void internalDynamicHierarchicalFetchGroup_JOIN_FETCH(boolean useCopy) throws Exception {
453
    void internalDynamicHierarchicalFetchGroup_JOIN_FETCH(boolean useCopy) throws Exception {
422
454
423
        EntityManager em = createEntityManager("fieldaccess");
455
        EntityManager em = createEntityManager("fieldaccess");
424
        
456
        try {
425
        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.manager WHERE e.lastName LIKE :LNAME AND e.manager.lastName <> e.lastName");
457
            beginTransaction(em);
426
        query.setParameter("LNAME", "%");
427
458
428
        // Define the fields to be fetched on Employee
459
            Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.manager WHERE e.lastName LIKE :LNAME AND e.manager.lastName <> e.lastName");
429
        FetchGroup fg = new FetchGroup();
460
            query.setParameter("LNAME", "%");
430
        fg.addAttribute("firstName");
431
        fg.addAttribute("lastName");
432
        fg.addAttribute("manager.firstName");
433
        fg.addAttribute("manager.salary");
434
        fg.addAttribute("manager.manager");
435
        query.setHint(QueryHints.FETCH_GROUP, fg);
436
        
437
        // applied to the selected Employee who is not a manager of some other selected Employee
438
        FetchGroup employeeFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "lastName", "manager"}); 
439
        // applied to the manager of a selected Employee who is not selected as an Employee
440
        FetchGroup managerFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "salary", "manager"});
441
        // applied to the object which is both selected as an Employee and the manager of another selected Employee
442
        FetchGroup employeeManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(employeeFG, managerFG); 
443
        
444
        // used in useCopy case only
445
        FetchGroup employeeManagerManagerFG = null;
446
        if(useCopy) {
447
            employeeManagerManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(new EntityFetchGroup("manager"), employeeDescriptor.getFetchGroupManager().getNonReferenceEntityFetchGroup()); 
448
        }
449
        
450
        /*
451
         * These are the first names of Employees involved; --> means "managed by".
452
         * All the employees here are returned by the query except Jill and Sarah-loo (they got no manager).
453
         * 
454
         * Sarah ------>Bob -------> John ----> Jim-bob ---> Jill ---> null
455
         * Charles -----^   Marius ----^
456
         * 
457
         * Nancy ------> Sarah-loo ---> null
458
         * 
459
         * Sarah, Charles, Nancy should have employeeFG;
460
         * Sarah-loo - managerFG;
461
         * Bob, Marius - employeeManagerFG;
462
         * John, Jim-bob should have a union of three fetch groups: {firstName,lastName,manager}, {firstName,salary,manager}, {manager}
463
         * Jill should have a union of two groups:  {firstName,salary,manager}, {manager}
464
         * The result for all three of them is the same:
465
         *   in read case (useCopy == false) it should be null (no fetch group), because defaultFetchGroup is null;
466
         *   in copy case (useCopy == true) it should be a union of "manager" and all non relational attributes (NonReferenceEntityFetchGroup).
467
         * That's how leaf reference attribute is treated: 
468
         *   default fetch group for read;
469
         *   NonReferenceEntityFetchGroup (see FetchGroupManager) for copy.
470
         * In this test defaultFetchGroup (null) / NonReferenceEntityFetchGroup comes from {manager},
471
         *   in useCopy == true case additional manager comes from another fetch group (they all contain manager).
472
         */
473
        
474
        List<Employee> emps = query.getResultList();
475
        
476
        if(useCopy) {
477
/*            for(Employee emp : emps) {
478
                int idHashCode =  System.identityHashCode(emp);
479
                System.out.println(emp.getFirstName() + '\t' + idHashCode);
480
            }*/
481
            emps = (List)JpaHelper.getEntityManager(em).copy(emps, fg);
482
        }
483
461
484
        // Sets of managed Employees keyed by their manager
462
            // Define the fields to be fetched on Employee
485
        Map<Employee, Set<Employee>> managedEmployeesByManager = new IdentityHashMap();
463
            FetchGroup fg = new FetchGroup();
486
        for (Employee emp : emps) {
464
            fg.addAttribute("firstName");
487
            Employee manager = emp.getManager(); 
465
            fg.addAttribute("lastName");
488
            Set<Employee> managedEmployees = managedEmployeesByManager.get(manager);
466
            fg.addAttribute("manager.firstName");
489
            if(managedEmployees == null) {
467
            fg.addAttribute("manager.salary");
490
                managedEmployees = new IdentityHashSet();
468
            fg.addAttribute("manager.manager");
491
                managedEmployeesByManager.put(manager, managedEmployees);
469
            query.setHint(QueryHints.FETCH_GROUP, fg);
470
            
471
            // applied to the selected Employee who is not a manager of some other selected Employee
472
            FetchGroup employeeFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "lastName", "manager"}); 
473
            // applied to the manager of a selected Employee who is not selected as an Employee
474
            FetchGroup managerFG = new EntityFetchGroup(new String[]{"id", "version", "firstName", "salary", "manager"});
475
            // applied to the object which is both selected as an Employee and the manager of another selected Employee
476
            FetchGroup employeeManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(employeeFG, managerFG); 
477
            
478
            // used in useCopy case only
479
            FetchGroup employeeManagerManagerFG = null;
480
            if(useCopy) {
481
                employeeManagerManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(new EntityFetchGroup("manager"), employeeDescriptor.getFetchGroupManager().getNonReferenceEntityFetchGroup()); 
492
            }
482
            }
493
            managedEmployees.add(emp);
483
            
494
        }
484
            /*
485
             * These are the first names of Employees involved; --> means "managed by".
486
             * All the employees here are returned by the query except Jill and Sarah-loo (they got no manager).
487
             * 
488
             * Sarah ------>Bob -------> John ----> Jim-bob ---> Jill ---> null
489
             * Charles -----^   Marius ----^
490
             * 
491
             * Nancy ------> Sarah-loo ---> null
492
             * 
493
             * Sarah, Charles, Nancy should have employeeFG;
494
             * Sarah-loo - managerFG;
495
             * Bob, Marius - employeeManagerFG;
496
             * John, Jim-bob should have a union of three fetch groups: {firstName,lastName,manager}, {firstName,salary,manager}, {manager}
497
             * Jill should have a union of two groups:  {firstName,salary,manager}, {manager}
498
             * The result for all three of them is the same:
499
             *   in read case (useCopy == false) it should be null (no fetch group), because defaultFetchGroup is null;
500
             *   in copy case (useCopy == true) it should be a union of "manager" and all non relational attributes (NonReferenceEntityFetchGroup).
501
             * That's how leaf reference attribute is treated: 
502
             *   default fetch group for read;
503
             *   NonReferenceEntityFetchGroup (see FetchGroupManager) for copy.
504
             * In this test defaultFetchGroup (null) / NonReferenceEntityFetchGroup comes from {manager},
505
             *   in useCopy == true case additional manager comes from another fetch group (they all contain manager).
506
             */
507
            
508
            List<Employee> emps = query.getResultList();
509
            
510
            if(useCopy) {
511
                /*for(Employee emp : emps) {
512
                    int idHashCode =  System.identityHashCode(emp);
513
                    System.out.println(emp.getFirstName() + '\t' + idHashCode);
514
                }*/
515
                emps = (List)JpaHelper.getEntityManager(em).copy(emps, fg);
516
            }
495
517
496
        for (Employee emp : emps) {
518
            // Sets of managed Employees keyed by their manager
497
            Set<Employee> managedEmployees = managedEmployeesByManager.get(emp);
519
            Map<Employee, Set<Employee>> managedEmployeesByManager = new IdentityHashMap();
498
            Employee manager = emp.getManager();
520
            for (Employee emp : emps) {
499
            if(managedEmployees == null) {
521
                Employee manager = emp.getManager(); 
500
                // employee is NOT a manager of any of the selected employees:
522
                Set<Employee> managedEmployees = managedEmployeesByManager.get(manager);
501
                assertFetched(emp, employeeFG);
523
                if(managedEmployees == null) {
524
                    managedEmployees = new IdentityHashSet();
525
                    managedEmployeesByManager.put(manager, managedEmployees);
526
                }
527
                managedEmployees.add(emp);
528
            }
502
529
503
                Set<Employee> managedByManagerEmployees = managedEmployeesByManager.get(manager); 
530
            for (Employee emp : emps) {
504
                // indicates whether one of manager's managed employees is a manager itself
531
                Set<Employee> managedEmployees = managedEmployeesByManager.get(emp);
505
                boolean isManagersManager = false;
532
                Employee manager = emp.getManager();
506
                for(Employee managedEmp : managedByManagerEmployees) {
533
                if(managedEmployees == null) {
507
                    if(managedEmployeesByManager.containsKey(managedEmp)) {
534
                    // employee is NOT a manager of any of the selected employees:
508
                        isManagersManager = true;
535
                    assertFetched(emp, employeeFG);
509
                        break;
536
537
                    Set<Employee> managedByManagerEmployees = managedEmployeesByManager.get(manager); 
538
                    // indicates whether one of manager's managed employees is a manager itself
539
                    boolean isManagersManager = false;
540
                    for(Employee managedEmp : managedByManagerEmployees) {
541
                        if(managedEmployeesByManager.containsKey(managedEmp)) {
542
                            isManagersManager = true;
543
                            break;
544
                        }
510
                    }
545
                    }
511
                }
546
                    if(isManagersManager) {
512
                if(isManagersManager) {
547
                        if(useCopy) {
513
                    if(useCopy) {
548
                            // for at least one of the selected employees manager is manager's manager:
514
                        // for at least one of the selected employees manager is manager's manager:
549
                            //   someSelectedEmp.getManager().getManager() == manager
515
                        //   someSelectedEmp.getManager().getManager() == manager
550
                            // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
516
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
551
                            // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
517
                        // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
552
                            // for another employee it's just a manager - which means it should include "manager":
518
                        // for another employee it's just a manager - which means it should include "manager":
553
                            // employeeManagerManagerFG is the union of these two EntityFetchGroups.
519
                        // employeeManagerManagerFG is the union of these two EntityFetchGroups.
554
                            assertFetched(manager, employeeManagerManagerFG);
520
                        assertFetched(manager, employeeManagerManagerFG);
555
                        } else {
556
                            // for at least one of the selected employees manager is manager's manager:
557
                            //   someSelectedEmp.getManager().getManager() == manager
558
                            // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
559
                            // which means no fetch group should be used. 
560
                            assertNoFetchGroup(manager);
561
                        }
521
                    } else {
562
                    } else {
522
                        // for at least one of the selected employees manager is manager's manager:
563
                        // it's not manager's manager
523
                        //   someSelectedEmp.getManager().getManager() == manager
564
                        if(emps.contains(manager)) {
524
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
565
                            // it's a manager of one of the selected Employees, and selected itself.
525
                        // which means no fetch group should be used. 
566
                            assertFetched(manager, employeeManagerFG);
526
                        assertNoFetchGroup(manager);
567
                        } else {
568
                            // it's a manager of one of the selected Employees, but not selected itself.
569
                            assertFetched(manager, managerFG);
570
                        }
527
                    }
571
                    }
528
                } else {
572
                } else {
529
                    // it's not manager's manager
573
                    // employee is a manager of at least one of the selected employees
530
                    if(emps.contains(manager)) {
574
                    // indicates whether one of emp's managed employees is a manager itself
531
                        // it's a manager of one of the selected Employees, and selected itself.
575
                    boolean isManagersManager = false;
532
                        assertFetched(manager, employeeManagerFG);
576
                    for(Employee managedEmp : managedEmployees) {
577
                        if(managedEmployeesByManager.containsKey(managedEmp)) {
578
                            isManagersManager = true;
579
                            break;
580
                        }
581
                    }
582
                    
583
                    if(isManagersManager) {
584
                        if(useCopy) {
585
                            // for at least one of the selected employees manager is manager's manager:
586
                            //   someSelectedEmp.getManager().getManager() == manager
587
                            // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
588
                            // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
589
                            // for another employee it's just a manager - which means it should include "manager":
590
                            // employeeManagerManagerFG is the union of these two EntityFetchGroups.
591
                            assertFetched(emp, employeeManagerManagerFG);
592
                        } else {
593
                            // for at least one of the selected employees emp is manager's manager:
594
                            //   someSelectedEmp.getManager().getManager() == emp
595
                            // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
596
                            // which means no fetch group should be used. 
597
                            assertNoFetchGroup(emp);
598
                        }
533
                    } else {
599
                    } else {
534
                        // it's a manager of one of the selected Employees, but not selected itself.
600
                        // it's selected employee, manager of some selected employee, but not manager's manager
535
                        assertFetched(manager, managerFG);
601
                        assertFetched(emp, employeeManagerFG);
536
                    }
602
                    }
537
                }
603
                    
538
            } else {
539
                // employee is a manager of at least one of the selected employees
540
                // indicates whether one of emp's managed employees is a manager itself
541
                boolean isManagersManager = false;
542
                for(Employee managedEmp : managedEmployees) {
543
                    if(managedEmployeesByManager.containsKey(managedEmp)) {
544
                        isManagersManager = true;
545
                        break;
546
                    }
547
                }
548
                
549
                if(isManagersManager) {
550
                    if(useCopy) {
604
                    if(useCopy) {
551
                        // for at least one of the selected employees manager is manager's manager:
605
                        // for at least one of the selected employees manager is manager's manager:
552
                        //   someSelectedEmp.getManager().getManager() == manager
606
                        //   someSelectedEmp.getManager().getManager() == manager
Lines 554-588 Link Here
554
                        // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
608
                        // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
555
                        // for another employee it's just a manager - which means it should include "manager":
609
                        // for another employee it's just a manager - which means it should include "manager":
556
                        // employeeManagerManagerFG is the union of these two EntityFetchGroups.
610
                        // employeeManagerManagerFG is the union of these two EntityFetchGroups.
557
                        assertFetched(emp, employeeManagerManagerFG);
611
                        assertFetched(manager, employeeManagerManagerFG);
558
                    } else {
612
                    } else {
559
                        // for at least one of the selected employees emp is manager's manager:
613
                        // for at least one of the selected employees manager is manager's manager:
560
                        //   someSelectedEmp.getManager().getManager() == emp
614
                        //   someSelectedEmp.getManager().getManager() == manager
561
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
615
                        // That means for someSelectedEmp emp.getManager() is defined by {manager.manager} FetchGroup's item,
562
                        // which means no fetch group should be used. 
616
                        // which means no fetch group should be used. 
563
                        assertNoFetchGroup(emp);
617
                        assertNoFetchGroup(manager);
564
                    }
618
                    }
565
                } else {
566
                    // it's selected employee, manager of some selected employee, but not manager's manager
567
                    assertFetched(emp, employeeManagerFG);
568
                }
619
                }
569
                
620
            }
570
                if(useCopy) {
621
        } finally {
571
                    // for at least one of the selected employees manager is manager's manager:
622
            if (isTransactionActive(em)){
572
                    //   someSelectedEmp.getManager().getManager() == manager
623
                rollbackTransaction(em);
573
                    // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
624
            }
574
                    // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
625
            closeEntityManager(em);
575
                    // for another employee it's just a manager - which means it should include "manager":
576
                    // employeeManagerManagerFG is the union of these two EntityFetchGroups.
577
                    assertFetched(manager, employeeManagerManagerFG);
578
                } else {
579
                    // for at least one of the selected employees manager is manager's manager:
580
                    //   someSelectedEmp.getManager().getManager() == manager
581
                    // That means for someSelectedEmp emp.getManager() is defined by {manager.manager} FetchGroup's item,
582
                    // which means no fetch group should be used. 
583
                    assertNoFetchGroup(manager);
584
                }
585
            }            
586
        }
626
        }
587
    }
627
    }
588
    
628
    
Lines 598-754 Link Here
598
638
599
   void managerNestedFetchGroupWithJoinFetch(boolean isDouble) {
639
   void managerNestedFetchGroupWithJoinFetch(boolean isDouble) {
600
        EntityManager em = createEntityManager("fieldaccess");
640
        EntityManager em = createEntityManager("fieldaccess");
641
        try {
642
            beginTransaction(em);
601
643
602
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager.manager IS NOT NULL");
644
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager.manager IS NOT NULL");
603
        FetchGroup managerFG = new FetchGroup();
645
            FetchGroup managerFG = new FetchGroup();
604
        if(isDouble) {
646
            if(isDouble) {
605
            // Double
647
                // Double
606
            managerFG.addAttribute("manager.manager");
648
                managerFG.addAttribute("manager.manager");
607
        } else {
649
            } else {
608
            // Triple
650
                // Triple
609
            managerFG.addAttribute("manager.manager.manager");
651
                managerFG.addAttribute("manager.manager.manager");
610
        }
652
            }
611
653
612
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
654
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
613
        query.setHint(QueryHints.LEFT_FETCH, "e.manager");
655
            query.setHint(QueryHints.LEFT_FETCH, "e.manager");
614
656
615
        assertNotNull(getFetchGroup(query));
657
            assertNotNull(getFetchGroup(query));
616
        assertSame(managerFG, getFetchGroup(query));
658
            assertSame(managerFG, getFetchGroup(query));
617
659
618
        List<Employee> employees = query.getResultList();
660
            List<Employee> employees = query.getResultList();
619
661
620
        int nSql;
662
            int nSql;
621
        if(isDouble) {
663
            if(isDouble) {
622
            // In this case the number of generated sqls is unpredictable.
664
                // In this case the number of generated sqls is unpredictable.
623
            // Additional sql generated for every object that 
665
                // Additional sql generated for every object that 
624
            // has been first fetched as manager.manager
666
                // has been first fetched as manager.manager
625
            // and then is selected as an employee - getting its manger
667
                // and then is selected as an employee - getting its manger
626
            // performed without fetch group therefore triggering reading of the whole object
668
                // performed without fetch group therefore triggering reading of the whole object
627
            nSql = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
669
                nSql = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
628
        } else {
670
            } else {
629
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
671
                assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
630
            nSql = 1;
672
                nSql = 1;
631
        }
673
            }
632
        
674
            
633
        Employee emp = employees.get(0);
675
            Employee emp = employees.get(0);
634
        assertFetched(emp, managerFG);
676
            assertFetched(emp, managerFG);
635
        
677
            
636
        // manager (if not null) is instantiated by the fetch group, before emp.getManager call.
678
            // manager (if not null) is instantiated by the fetch group, before emp.getManager call.
637
        Employee manager = emp.getManager();
679
            Employee manager = emp.getManager();
638
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
680
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
639
        assertFetched(manager, managerFG);
681
            assertFetched(manager, managerFG);
640
        
682
            
641
        // instantiates the whole object
683
            // instantiates the whole object
642
        emp.getLastName();
684
            emp.getLastName();
643
        nSql++;
685
            nSql++;
644
        assertNoFetchGroup(emp);
686
            assertNoFetchGroup(emp);
645
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
687
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
646
        
688
            
647
        assertFetched(manager, managerFG);
689
            assertFetched(manager, managerFG);
648
        // instantiates the whole object
690
            // instantiates the whole object
649
        manager.getLastName();
691
            manager.getLastName();
650
        nSql++;
692
            nSql++;
651
        assertNoFetchGroup(manager);
693
            assertNoFetchGroup(manager);
652
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
694
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
653
695
654
        nSql++;
655
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
656
            assertFetched(phone, this.defaultPhoneFG);
657
            phone.getAreaCode();
658
            nSql++;
696
            nSql++;
659
            assertNoFetchGroup(phone);
697
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
660
        }
698
                assertFetched(phone, this.defaultPhoneFG);
661
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
699
                phone.getAreaCode();
700
                nSql++;
701
                assertNoFetchGroup(phone);
702
            }
703
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
662
704
663
        nSql++;
664
        for (PhoneNumber phone : manager.getPhoneNumbers()) {
665
            assertFetched(phone, this.defaultPhoneFG);
666
            phone.getAreaCode();
667
            nSql++;
705
            nSql++;
668
            assertNoFetchGroup(phone);
706
            for (PhoneNumber phone : manager.getPhoneNumbers()) {
707
                assertFetched(phone, this.defaultPhoneFG);
708
                phone.getAreaCode();
709
                nSql++;
710
                assertNoFetchGroup(phone);
711
            }
712
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
713
        } finally {
714
            if (isTransactionActive(em)){
715
                rollbackTransaction(em);
716
            }
717
            closeEntityManager(em);
669
        }
718
        }
670
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
671
    }
719
    }
672
720
673
   @Test
721
   @Test
674
   public void allNestedFetchGroupWithJoinFetch() {
722
   public void allNestedFetchGroupWithJoinFetch() {
675
        EntityManager em = createEntityManager("fieldaccess");
723
        EntityManager em = createEntityManager("fieldaccess");
724
        try {
725
            beginTransaction(em);
676
726
677
        // select employees who are neither managers nor team leaders
727
            // select employees who are neither managers nor team leaders
678
        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)");
728
            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)");
679
        FetchGroup employeeFG = new FetchGroup("employee");
729
            FetchGroup employeeFG = new FetchGroup("employee");
680
        employeeFG.addAttribute("lastName");
730
            employeeFG.addAttribute("lastName");
681
        
731
            
682
        employeeFG.addAttribute("address.country");
732
            employeeFG.addAttribute("address.country");
683
        employeeFG.addAttribute("address.city");
733
            employeeFG.addAttribute("address.city");
684
        query.setHint(QueryHints.LEFT_FETCH, "e.address");
734
            query.setHint(QueryHints.LEFT_FETCH, "e.address");
685
        
735
            
686
        employeeFG.addAttribute("phoneNumbers");
736
            employeeFG.addAttribute("phoneNumbers");
687
        query.setHint(QueryHints.LEFT_FETCH, "e.phoneNumbers");
737
            query.setHint(QueryHints.LEFT_FETCH, "e.phoneNumbers");
688
        
738
            
689
        employeeFG.addAttribute("projects.name");
739
            employeeFG.addAttribute("projects.name");
690
740
691
        employeeFG.addAttribute("projects.teamLeader.firstName");
741
            employeeFG.addAttribute("projects.teamLeader.firstName");
692
//        employeeFG.addAttribute("projects.teamLeader.address.street");
742
            //employeeFG.addAttribute("projects.teamLeader.address.street");
693
//        employeeFG.addAttribute("projects.teamLeader.address.postalCode");
743
            //employeeFG.addAttribute("projects.teamLeader.address.postalCode");
694
        employeeFG.addAttribute("projects.teamLeader.phoneNumbers.owner");
744
            employeeFG.addAttribute("projects.teamLeader.phoneNumbers.owner");
695
        employeeFG.addAttribute("projects.teamLeader.phoneNumbers.type");
745
            employeeFG.addAttribute("projects.teamLeader.phoneNumbers.type");
696
        employeeFG.addAttribute("projects.teamLeader.phoneNumbers.areaCode");
746
            employeeFG.addAttribute("projects.teamLeader.phoneNumbers.areaCode");
697
        query.setHint(QueryHints.LEFT_FETCH, "e.projects.teamLeader.phoneNumbers");
747
            query.setHint(QueryHints.LEFT_FETCH, "e.projects.teamLeader.phoneNumbers");
698
        
748
            
699
        employeeFG.addAttribute("manager.firstName");
749
            employeeFG.addAttribute("manager.firstName");
700
//        employeeFG.addAttribute("manager.address.street");
750
            //employeeFG.addAttribute("manager.address.street");
701
//        employeeFG.addAttribute("manager.address.postalCode");
751
            //employeeFG.addAttribute("manager.address.postalCode");
702
        employeeFG.addAttribute("manager.phoneNumbers.owner");
752
            employeeFG.addAttribute("manager.phoneNumbers.owner");
703
        employeeFG.addAttribute("manager.phoneNumbers.type");
753
            employeeFG.addAttribute("manager.phoneNumbers.type");
704
        employeeFG.addAttribute("manager.phoneNumbers.areaCode");
754
            employeeFG.addAttribute("manager.phoneNumbers.areaCode");
705
        query.setHint(QueryHints.LEFT_FETCH, "e.manager.phoneNumbers");
755
            query.setHint(QueryHints.LEFT_FETCH, "e.manager.phoneNumbers");
706
756
707
        // department attribute defined with JoinFetchType.OUTER
757
            // department attribute defined with JoinFetchType.OUTER
708
        employeeFG.addAttribute("department.name");
758
            employeeFG.addAttribute("department.name");
709
        
759
            
710
        query.setHint(QueryHints.FETCH_GROUP, employeeFG);
760
            query.setHint(QueryHints.FETCH_GROUP, employeeFG);
711
761
712
        List<Employee> employees = query.getResultList();
762
            List<Employee> employees = query.getResultList();
713
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
763
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
714
        
715
        for(Employee emp :employees) {
716
            assertFetched(emp, employeeFG);
717
            
764
            
718
            Address address = emp.getAddress();
765
            for(Employee emp :employees) {
719
            if(address != null) {
766
                assertFetched(emp, employeeFG);
720
                assertFetched(address, employeeFG.getGroup("address"));
767
                
721
            }
768
                Address address = emp.getAddress();
769
                if(address != null) {
770
                    assertFetched(address, employeeFG.getGroup("address"));
771
                }
722
772
723
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
773
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
724
                assertFetched(phone, defaultPhoneFG);
774
                    assertFetched(phone, defaultPhoneFG);
725
            }
775
                }
726
            
776
                
727
            for (Project project : emp.getProjects()) {
777
                for (Project project : emp.getProjects()) {
728
                assertFetched(project, employeeFG.getGroup("projects"));
778
                    assertFetched(project, employeeFG.getGroup("projects"));
729
                Employee teamLeader = project.getTeamLeader();
779
                    Employee teamLeader = project.getTeamLeader();
730
                if(teamLeader != null) {
780
                    if(teamLeader != null) {
731
                    assertFetched(teamLeader, employeeFG.getGroup("projects.teamLeader"));
781
                        assertFetched(teamLeader, employeeFG.getGroup("projects.teamLeader"));
732
                    for (PhoneNumber phone : teamLeader.getPhoneNumbers()) {
782
                        for (PhoneNumber phone : teamLeader.getPhoneNumbers()) {
733
                        assertFetched(phone, employeeFG.getGroup("projects.teamLeader.phoneNumbers"));
783
                            assertFetched(phone, employeeFG.getGroup("projects.teamLeader.phoneNumbers"));
784
                        }
734
                    }
785
                    }
735
                }
786
                }
736
            }
787
                
737
            
788
                Employee manager = emp.getManager();
738
            Employee manager = emp.getManager();
789
                if(manager != null) {
739
            if(manager != null) {
790
                    assertFetched(manager, employeeFG.getGroup("manager"));
740
                assertFetched(manager, employeeFG.getGroup("manager"));
791
                    for (PhoneNumber phone : manager.getPhoneNumbers()) {
741
                for (PhoneNumber phone : manager.getPhoneNumbers()) {
792
                        assertFetched(phone, employeeFG.getGroup("manager.phoneNumbers"));
742
                    assertFetched(phone, employeeFG.getGroup("manager.phoneNumbers"));
793
                    }
743
                }
794
                }
795
                
796
                Department department = emp.getDepartment();
797
                if(department != null) {
798
                    assertFetched(department, employeeFG.getGroup("department"));
799
                }
744
            }
800
            }
745
            
801
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
746
            Department department = emp.getDepartment();
802
        } finally {
747
            if(department != null) {
803
            if (isTransactionActive(em)){
748
                assertFetched(department, employeeFG.getGroup("department"));
804
                rollbackTransaction(em);
749
            }
805
            }
806
            closeEntityManager(em);
750
        }
807
        }
751
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
752
    }
808
    }
753
809
754
   @Test
810
   @Test
Lines 786-899 Link Here
786
   @Test
842
   @Test
787
   public void simpleNestedFetchGroupWithBatch() {
843
   public void simpleNestedFetchGroupWithBatch() {
788
       EntityManager em = createEntityManager("fieldaccess");
844
       EntityManager em = createEntityManager("fieldaccess");
845
        try {
846
            beginTransaction(em);
789
847
790
       Query query = em.createQuery("SELECT e FROM Employee e");
848
            Query query = em.createQuery("SELECT e FROM Employee e");
791
849
792
       // Define the fields to be fetched on Employee
850
            // Define the fields to be fetched on Employee
793
       FetchGroup employeeFG = new FetchGroup();
851
            FetchGroup employeeFG = new FetchGroup();
794
       employeeFG.setShouldLoad(true);
852
            employeeFG.setShouldLoad(true);
795
       employeeFG.addAttribute("firstName");
853
            employeeFG.addAttribute("firstName");
796
       employeeFG.addAttribute("lastName");
854
            employeeFG.addAttribute("lastName");
797
       employeeFG.addAttribute("address.country");
855
            employeeFG.addAttribute("address.country");
798
       employeeFG.addAttribute("address.city");
856
            employeeFG.addAttribute("address.city");
799
       
857
            
800
       FetchGroup phonesFG = defaultPhoneFG.clone();
858
            FetchGroup phonesFG = defaultPhoneFG.clone();
801
       // to preclude PhoneNumber from triggering owner's full read
859
            // to preclude PhoneNumber from triggering owner's full read
802
       phonesFG.addAttribute("owner.id");
860
            phonesFG.addAttribute("owner.id");
803
       employeeFG.addAttribute("phoneNumbers", phonesFG);
861
            employeeFG.addAttribute("phoneNumbers", phonesFG);
804
       
862
            
805
       FetchGroup projectsFG = new FetchGroup("projects");
863
            FetchGroup projectsFG = new FetchGroup("projects");
806
       projectsFG.addAttribute("name");
864
            projectsFG.addAttribute("name");
807
       projectsFG.addAttribute("name");
865
            projectsFG.addAttribute("name");
808
       // to preclude Project from triggering full read of the referenced Employee(s)
866
            // to preclude Project from triggering full read of the referenced Employee(s)
809
       projectsFG.addAttribute("teamMembers.id");
867
            projectsFG.addAttribute("teamMembers.id");
810
       projectsFG.addAttribute("teamLeader.id");
868
            projectsFG.addAttribute("teamLeader.id");
811
       employeeFG.addAttribute("projects", projectsFG);
869
            employeeFG.addAttribute("projects", projectsFG);
812
870
813
       query.setHint(QueryHints.FETCH_GROUP, employeeFG);
871
            query.setHint(QueryHints.FETCH_GROUP, employeeFG);
814
       
872
            
815
       query.setHint(QueryHints.BATCH, "e.address");
873
            query.setHint(QueryHints.BATCH, "e.address");
816
       query.setHint(QueryHints.BATCH, "e.phoneNumbers");
874
            query.setHint(QueryHints.BATCH, "e.phoneNumbers");
817
       query.setHint(QueryHints.BATCH, "e.projects");
875
            query.setHint(QueryHints.BATCH, "e.projects");
818
       
876
            
819
       // A single sql will be used to read all Project subclasses.
877
            // A single sql will be used to read all Project subclasses.
820
       query.setHint(QueryHints.INHERITANCE_OUTER_JOIN, "true");
878
            query.setHint(QueryHints.INHERITANCE_OUTER_JOIN, "true");
821
879
822
       List<Employee> employees = query.getResultList();
880
            List<Employee> employees = query.getResultList();
823
881
824
       // Employee, Address, PhoneNumbers, Projects - an sql per class.
882
            // Employee, Address, PhoneNumbers, Projects - an sql per class.
825
       // Address, PhoneNumbers and Projects are already loaded because
883
            // Address, PhoneNumbers and Projects are already loaded because
826
       // employeeFG.shouldLoad is set to true.
884
            // employeeFG.shouldLoad is set to true.
827
       assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
885
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
828
       
886
            
829
       // verify fetch groups
887
            // verify fetch groups
830
       for(Employee emp : employees) {
888
            for(Employee emp : employees) {
831
           assertFetched(emp, employeeFG);
889
                assertFetched(emp, employeeFG);
832
890
833
           Address address = emp.getAddress();
891
                Address address = emp.getAddress();
834
           if(address != null) {
892
                if(address != null) {
835
               assertFetched(address, employeeFG.getGroup("address"));
893
                         assertFetched(address, employeeFG.getGroup("address"));
836
           }
894
                }
837
895
838
           for (PhoneNumber phone : emp.getPhoneNumbers()) {
896
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
839
               assertFetched(phone, phonesFG);
897
                         assertFetched(phone, phonesFG);
840
           }
898
                }
841
           
899
                
842
           for (Project project : emp.getProjects()) {
900
                for (Project project : emp.getProjects()) {
843
               assertFetched(project, projectsFG);
901
                         assertFetched(project, projectsFG);
844
           }
902
                }
845
       }
903
            }
846
904
847
       // Now let's access an attribute outside of the fetch group.
905
            // Now let's access an attribute outside of the fetch group.
848
       // That triggers loading of the whole object.
906
            // That triggers loading of the whole object.
849
       for(Employee emp : employees) {
907
            for(Employee emp : employees) {
850
           emp.getSalary();
908
                emp.getSalary();
851
           assertNoFetchGroup(emp);
909
                assertNoFetchGroup(emp);
852
910
853
           Address address = emp.getAddress();
911
                Address address = emp.getAddress();
854
           if(address != null) {
912
                if(address != null) {
855
               address.getStreet();
913
                   address.getStreet();
856
               assertNoFetchGroup(address);
914
                   assertNoFetchGroup(address);
857
           }
915
                }
858
916
859
           for (PhoneNumber phone : emp.getPhoneNumbers()) {
917
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
860
               phone.getAreaCode();
918
                    phone.getAreaCode();
861
               assertNoFetchGroup(phone);
919
                    assertNoFetchGroup(phone);
862
           }
920
                }
863
           
921
                
864
           for (Project project : emp.getProjects()) {
922
                for (Project project : emp.getProjects()) {
865
               project.getDescription();
923
                    project.getDescription();
866
               assertNoFetchGroup(project);
924
                    assertNoFetchGroup(project);
867
           }
925
                }
868
       }
926
            }
927
        } finally {
928
            if (isTransactionActive(em)){
929
                rollbackTransaction(em);
930
            }
931
            closeEntityManager(em);
932
        }
869
   }
933
   }
870
   
934
   
871
   @Test
935
   @Test
872
    public void simpleLoadGroup() {
936
    public void simpleLoadGroup() {
873
        EntityManager em = createEntityManager("fieldaccess");
937
        EntityManager em = createEntityManager("fieldaccess");
874
        
938
        try {
875
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
939
            beginTransaction(em);
876
        query.setParameter("GENDER", Gender.Female);        
877
        List<Employee> employees = query.getResultList();
878
        
879
        LoadGroup group = new LoadGroup();
880
        group.addAttribute("address");
881
        group.addAttribute("phoneNumbers");
882
        group.addAttribute("manager.projects");
883
        ((AbstractSession)((EntityManagerImpl)em.getDelegate()).getActiveSession()).load(employees, group);
884
940
885
        int numSelectBefore = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
941
             Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
886
        
942
             query.setParameter("GENDER", Gender.Female);
887
        // All indirections specified in the plan should have been already triggered.
943
             List<Employee> employees = query.getResultList();
888
        for(Employee emp : employees) {
944
             
889
            emp.getAddress();
945
             LoadGroup group = new LoadGroup();
890
            emp.getPhoneNumbers().size();
946
             group.addAttribute("address");
891
            if(emp.getManager() != null) {
947
             group.addAttribute("phoneNumbers");
892
                emp.getManager().getProjects().size();
948
             group.addAttribute("manager.projects");
949
             ((AbstractSession)((EntityManagerImpl)em.getDelegate()).getActiveSession()).load(employees, group);
950
951
             int numSelectBefore = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
952
             
953
             // All indirections specified in the plan should have been already triggered.
954
             for(Employee emp : employees) {
955
                 emp.getAddress();
956
                 emp.getPhoneNumbers().size();
957
                 if(emp.getManager() != null) {
958
                     emp.getManager().getProjects().size();
959
                 }
960
             }
961
             
962
             int numSelectAfter = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
963
             assertEquals(numSelectBefore, numSelectAfter);
964
        } finally {
965
            if (isTransactionActive(em)){
966
                rollbackTransaction(em);
893
            }
967
            }
968
            closeEntityManager(em);
894
        }
969
        }
895
        
896
        int numSelectAfter = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
897
        assertEquals(numSelectBefore, numSelectAfter);
898
    }
970
    }
899
}
971
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/NestedNamedFetchGroupTests.java (-145 / +169 lines)
Lines 83-144 Link Here
83
    @Test
83
    @Test
84
    public void dynamicFetchGroup_EmployeeAddress() throws Exception {
84
    public void dynamicFetchGroup_EmployeeAddress() throws Exception {
85
        EntityManager em = createEntityManager("fieldaccess");
85
        EntityManager em = createEntityManager("fieldaccess");
86
        try {
87
            beginTransaction(em);
86
88
87
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
89
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
88
        query.setParameter("GENDER", Gender.Male);
90
            query.setParameter("GENDER", Gender.Male);
89
91
90
        // Define the fields to be fetched on Employee
92
            // Define the fields to be fetched on Employee
91
        FetchGroup fg = new FetchGroup();
93
            FetchGroup fg = new FetchGroup();
92
        fg.addAttribute("firstName");
94
            fg.addAttribute("firstName");
93
        fg.addAttribute("lastName");
95
            fg.addAttribute("lastName");
94
        fg.addAttribute("address");
96
            fg.addAttribute("address");
95
        fg.addAttribute("address.city");
97
            fg.addAttribute("address.city");
96
        fg.addAttribute("address.postalCode");
98
            fg.addAttribute("address.postalCode");
97
99
98
        // Configure the dynamic FetchGroup
100
            // Configure the dynamic FetchGroup
99
        query.setHint(QueryHints.FETCH_GROUP, fg);
101
            query.setHint(QueryHints.FETCH_GROUP, fg);
100
102
101
        List<Employee> emps = query.getResultList();
103
            List<Employee> emps = query.getResultList();
102
104
103
        assertNotNull(emps);
105
            assertNotNull(emps);
104
        for (Employee emp : emps) {
106
            for (Employee emp : emps) {
105
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
107
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
106
108
107
            assertNotNull(tracker._persistence_getFetchGroup());
109
                assertNotNull(tracker._persistence_getFetchGroup());
108
110
109
            // Verify specified fields plus mandatory ones are loaded
111
                // Verify specified fields plus mandatory ones are loaded
110
            assertTrue(tracker._persistence_isAttributeFetched("id"));
112
                assertTrue(tracker._persistence_isAttributeFetched("id"));
111
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
113
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
112
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
114
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
113
            assertTrue(tracker._persistence_isAttributeFetched("version"));
115
                assertTrue(tracker._persistence_isAttributeFetched("version"));
114
116
115
            // Verify the other fields are not loaded
117
                // Verify the other fields are not loaded
116
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
118
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
117
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
119
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
118
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
120
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
119
121
120
            // Force the loading of lazy fields and verify
122
                // Force the loading of lazy fields and verify
121
            emp.getSalary();
123
                emp.getSalary();
122
124
123
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
125
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
124
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
126
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
125
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
127
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
126
128
127
            // Now we'll check the address uses the provided dynamic fetch-group
129
                // Now we'll check the address uses the provided dynamic fetch-group
128
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
130
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
129
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
131
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
130
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
132
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
131
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
133
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
132
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
134
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
133
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
135
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
134
136
135
            // Now we'll check the phoneNumbers use of the default fetch group
137
                // Now we'll check the phoneNumbers use of the default fetch group
136
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
138
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
137
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
139
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
138
                assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
140
                    assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
139
                assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
141
                    assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
140
                assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
142
                    assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
143
                }
141
            }
144
            }
145
        } finally {
146
            if (isTransactionActive(em)){
147
                rollbackTransaction(em);
148
            }
149
            closeEntityManager(em);
142
        }
150
        }
143
    }
151
    }
144
152
Lines 208-354 Link Here
208
    @Test
216
    @Test
209
    public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception {
217
    public void dynamicFetchGroup_EmployeeAddressNullPhone() throws Exception {
210
        EntityManager em = createEntityManager("fieldaccess");
218
        EntityManager em = createEntityManager("fieldaccess");
219
        try {
220
            beginTransaction(em);
211
221
212
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
222
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
213
        query.setParameter("GENDER", Gender.Male);
223
            query.setParameter("GENDER", Gender.Male);
214
224
215
        // Define the fields to be fetched on Employee
225
            // Define the fields to be fetched on Employee
216
        FetchGroup empGroup = new FetchGroup();
226
            FetchGroup empGroup = new FetchGroup();
217
        empGroup.addAttribute("firstName");
227
            empGroup.addAttribute("firstName");
218
        empGroup.addAttribute("lastName");
228
            empGroup.addAttribute("lastName");
219
        empGroup.addAttribute("address");
229
            empGroup.addAttribute("address");
220
230
221
        // Define the fields to be fetched on Address
231
            // Define the fields to be fetched on Address
222
        FetchGroup addressGroup = new FetchGroup();
232
            FetchGroup addressGroup = new FetchGroup();
223
        addressGroup.addAttribute("city");
233
            addressGroup.addAttribute("city");
224
        addressGroup.addAttribute("postalCode");
234
            addressGroup.addAttribute("postalCode");
225
235
226
        empGroup.addAttribute("address", addressGroup);
236
            empGroup.addAttribute("address", addressGroup);
227
237
228
//        empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false);
238
            //empGroup.addAttribute("phoneNumbers").setUseDefaultFetchGroup(false);
229
        FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
239
            FetchGroup fullPhone = this.phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
230
        // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
240
            // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
231
        fullPhone.addAttribute("owner.id");
241
            fullPhone.addAttribute("owner.id");
232
        empGroup.addAttribute("phoneNumbers", fullPhone);
242
            empGroup.addAttribute("phoneNumbers", fullPhone);
233
243
234
        // Configure the dynamic FetchGroup
244
            // Configure the dynamic FetchGroup
235
        query.setHint(QueryHints.FETCH_GROUP, empGroup);
245
            query.setHint(QueryHints.FETCH_GROUP, empGroup);
236
246
237
        List<Employee> emps = query.getResultList();
247
            List<Employee> emps = query.getResultList();
238
248
239
        assertNotNull(emps);
249
            assertNotNull(emps);
240
        for (Employee emp : emps) {
250
            for (Employee emp : emps) {
241
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
251
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
242
252
243
            assertNotNull(tracker._persistence_getFetchGroup());
253
                assertNotNull(tracker._persistence_getFetchGroup());
244
254
245
            // Verify specified fields plus mandatory ones are loaded
255
                // Verify specified fields plus mandatory ones are loaded
246
            assertTrue(tracker._persistence_isAttributeFetched("id"));
256
                assertTrue(tracker._persistence_isAttributeFetched("id"));
247
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
257
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
248
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
258
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
249
            assertTrue(tracker._persistence_isAttributeFetched("version"));
259
                assertTrue(tracker._persistence_isAttributeFetched("version"));
250
260
251
            // Verify the other fields are not loaded
261
                // Verify the other fields are not loaded
252
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
262
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
253
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
263
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
254
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
264
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
255
265
256
            // Force the loading of lazy fields and verify
266
                // Force the loading of lazy fields and verify
257
            emp.getSalary();
267
                emp.getSalary();
258
268
259
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
269
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
260
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
270
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
261
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
271
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
262
272
263
            // Now we'll check the address uses the provided dynamic fetch-group
273
                // Now we'll check the address uses the provided dynamic fetch-group
264
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
274
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
265
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
275
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
266
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
276
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
267
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
277
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
268
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
278
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
269
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
279
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
270
280
271
            // Now we'll check the phoneNumbers use of the default fetch group
281
                // Now we'll check the phoneNumbers use of the default fetch group
272
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
282
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
273
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
283
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
274
                assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup());
284
                    assertNull("PhoneNumber has a FetchGroup", phoneTracker._persistence_getFetchGroup());
285
                }
275
            }
286
            }
287
        } finally {
288
            if (isTransactionActive(em)){
289
                rollbackTransaction(em);
290
            }
291
            closeEntityManager(em);
276
        }
292
        }
277
    }
293
    }
278
294
279
    @Test
295
    @Test
280
    public void dynamicFetchGroup_EmployeeAddressEmptyPhone() throws Exception {
296
    public void dynamicFetchGroup_EmployeeAddressEmptyPhone() throws Exception {
281
        EntityManager em = createEntityManager("fieldaccess");
297
        EntityManager em = createEntityManager("fieldaccess");
298
        try {
299
            beginTransaction(em);
282
300
283
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
301
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
284
        query.setParameter("GENDER", Gender.Male);
302
            query.setParameter("GENDER", Gender.Male);
285
303
286
        // Define the fields to be fetched on Employee
304
            // Define the fields to be fetched on Employee
287
        FetchGroup empGroup = new FetchGroup();
305
            FetchGroup empGroup = new FetchGroup();
288
        empGroup.addAttribute("firstName");
306
            empGroup.addAttribute("firstName");
289
        empGroup.addAttribute("lastName");
307
            empGroup.addAttribute("lastName");
290
        empGroup.addAttribute("address");
308
            empGroup.addAttribute("address");
291
309
292
        // Define the fields to be fetched on Address
310
            // Define the fields to be fetched on Address
293
        FetchGroup addressGroup = new FetchGroup();
311
            FetchGroup addressGroup = new FetchGroup();
294
        addressGroup.addAttribute("city");
312
            addressGroup.addAttribute("city");
295
        addressGroup.addAttribute("postalCode");
313
            addressGroup.addAttribute("postalCode");
296
314
297
        empGroup.addAttribute("address", addressGroup);
315
            empGroup.addAttribute("address", addressGroup);
298
        // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
316
            // to preclude Employee from being loaded by phoneNumber.owner add it to the fetch group
299
        FetchGroup ownerId = new FetchGroup();
317
            FetchGroup ownerId = new FetchGroup();
300
        ownerId.addAttribute("owner.id");
318
            ownerId.addAttribute("owner.id");
301
        empGroup.addAttribute("phoneNumbers", ownerId);
319
            empGroup.addAttribute("phoneNumbers", ownerId);
302
320
303
        // Configure the dynamic FetchGroup
321
            // Configure the dynamic FetchGroup
304
        query.setHint(QueryHints.FETCH_GROUP, empGroup);
322
            query.setHint(QueryHints.FETCH_GROUP, empGroup);
305
323
306
        List<Employee> emps = query.getResultList();
324
            List<Employee> emps = query.getResultList();
307
325
308
        assertNotNull(emps);
326
            assertNotNull(emps);
309
        for (Employee emp : emps) {
327
            for (Employee emp : emps) {
310
            FetchGroupTracker tracker = (FetchGroupTracker) emp;
328
                FetchGroupTracker tracker = (FetchGroupTracker) emp;
311
329
312
            assertNotNull(tracker._persistence_getFetchGroup());
330
                assertNotNull(tracker._persistence_getFetchGroup());
313
331
314
            // Verify specified fields plus mandatory ones are loaded
332
                // Verify specified fields plus mandatory ones are loaded
315
            assertTrue(tracker._persistence_isAttributeFetched("id"));
333
                assertTrue(tracker._persistence_isAttributeFetched("id"));
316
            assertTrue(tracker._persistence_isAttributeFetched("firstName"));
334
                assertTrue(tracker._persistence_isAttributeFetched("firstName"));
317
            assertTrue(tracker._persistence_isAttributeFetched("lastName"));
335
                assertTrue(tracker._persistence_isAttributeFetched("lastName"));
318
            assertTrue(tracker._persistence_isAttributeFetched("version"));
336
                assertTrue(tracker._persistence_isAttributeFetched("version"));
319
337
320
            // Verify the other fields are not loaded
338
                // Verify the other fields are not loaded
321
            assertFalse(tracker._persistence_isAttributeFetched("salary"));
339
                assertFalse(tracker._persistence_isAttributeFetched("salary"));
322
            assertFalse(tracker._persistence_isAttributeFetched("startTime"));
340
                assertFalse(tracker._persistence_isAttributeFetched("startTime"));
323
            assertFalse(tracker._persistence_isAttributeFetched("endTime"));
341
                assertFalse(tracker._persistence_isAttributeFetched("endTime"));
324
342
325
            // Force the loading of lazy fields and verify
343
                // Force the loading of lazy fields and verify
326
            emp.getSalary();
344
                emp.getSalary();
327
345
328
            assertTrue(tracker._persistence_isAttributeFetched("salary"));
346
                assertTrue(tracker._persistence_isAttributeFetched("salary"));
329
            assertTrue(tracker._persistence_isAttributeFetched("startTime"));
347
                assertTrue(tracker._persistence_isAttributeFetched("startTime"));
330
            assertTrue(tracker._persistence_isAttributeFetched("endTime"));
348
                assertTrue(tracker._persistence_isAttributeFetched("endTime"));
331
349
332
            // Now we'll check the address uses the provided dynamic fetch-group
350
                // Now we'll check the address uses the provided dynamic fetch-group
333
            FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
351
                FetchGroupTracker addrTracker = (FetchGroupTracker) emp.getAddress();
334
            assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
352
                assertNotNull("Address does not have a FetchGroup", addrTracker._persistence_getFetchGroup());
335
            assertTrue(addrTracker._persistence_isAttributeFetched("city"));
353
                assertTrue(addrTracker._persistence_isAttributeFetched("city"));
336
            assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
354
                assertTrue(addrTracker._persistence_isAttributeFetched("postalCode"));
337
            assertFalse(addrTracker._persistence_isAttributeFetched("street"));
355
                assertFalse(addrTracker._persistence_isAttributeFetched("street"));
338
            assertFalse(addrTracker._persistence_isAttributeFetched("country"));
356
                assertFalse(addrTracker._persistence_isAttributeFetched("country"));
339
357
340
            // Now we'll check the phoneNumbers use of the default fetch group
358
                // Now we'll check the phoneNumbers use of the default fetch group
341
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
359
                for (PhoneNumber phone : emp.getPhoneNumbers()) {
342
                FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
360
                    FetchGroupTracker phoneTracker = (FetchGroupTracker) phone;
343
                assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
361
                    assertNotNull("PhoneNumber does not have a FetchGroup", phoneTracker._persistence_getFetchGroup());
344
                assertFalse(phoneTracker._persistence_isAttributeFetched("number"));
362
                    assertFalse(phoneTracker._persistence_isAttributeFetched("number"));
345
                assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
363
                    assertFalse(phoneTracker._persistence_isAttributeFetched("areaCode"));
346
364
347
                phone.getNumber();
365
                    phone.getNumber();
348
366
349
                assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
367
                    assertTrue(phoneTracker._persistence_isAttributeFetched("number"));
350
                assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode"));
368
                    assertTrue(phoneTracker._persistence_isAttributeFetched("areaCode"));
369
                }
351
            }
370
            }
371
        } finally {
372
            if (isTransactionActive(em)){
373
                rollbackTransaction(em);
374
            }
375
            closeEntityManager(em);
352
        }
376
        }
353
    }
377
    }
354
378
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleDefaultFetchGroupTests.java (-246 / +322 lines)
Lines 101-216 Link Here
101
    @Test
101
    @Test
102
    public void findDefaultFetchGroup() throws Exception {
102
    public void findDefaultFetchGroup() throws Exception {
103
        EntityManager em = createEntityManager("fieldaccess");
103
        EntityManager em = createEntityManager("fieldaccess");
104
        try {
105
            beginTransaction(em);
104
106
105
        Employee emp = minimumEmployee(em);
107
            Employee emp = minimumEmployee(em);
108
            assertNotNull(emp);
109
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
110
            assertDefaultFetched(emp);
106
111
107
        assertNotNull(emp);
112
            assertNotFetchedAttribute(emp, "salary");
108
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
113
            emp.getSalary();
109
        assertDefaultFetched(emp);
110
114
111
        assertNotFetchedAttribute(emp, "salary");
115
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
112
        emp.getSalary();
116
            assertFetchedAttribute(emp, "salary");
113
117
114
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
118
            assertNoFetchGroup(emp.getAddress());
115
        assertFetchedAttribute(emp, "salary");
116
119
117
        assertNoFetchGroup(emp.getAddress());
120
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
118
121
119
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
122
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
123
                assertDefaultFetched(phone);
124
            }
120
125
121
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
126
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
122
            assertDefaultFetched(phone);
123
        }
124
127
125
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
128
            if (emp.getManager() != null) {
126
129
                assertDefaultFetched(emp.getManager());
127
        if (emp.getManager() != null) {
130
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
128
            assertDefaultFetched(emp.getManager());
131
            } else {
129
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
132
                // If manager_id field is null then getManager() does not trigger an sql.
130
        } else {
133
                assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
131
            // If manager_id field is null then getManager() does not trigger an sql.
134
            }
132
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
135
        } finally {
136
            if (isTransactionActive(em)){
137
                rollbackTransaction(em);
138
            }
139
            closeEntityManager(em);
133
        }
140
        }
134
    }
141
    }
135
142
136
    @Test
143
    @Test
137
    public void singleResultDefaultFetchGroup() throws Exception {
144
    public void singleResultDefaultFetchGroup() throws Exception {
138
        EntityManager em = createEntityManager("fieldaccess");
145
        EntityManager em = createEntityManager("fieldaccess");
146
        try {
147
            beginTransaction(em);
139
148
140
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
149
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
141
        query.setParameter("ID", minimumEmployeeId(em));
150
            query.setParameter("ID", minimumEmployeeId(em));
142
151
143
        Employee emp = (Employee) query.getSingleResult();
152
            Employee emp = (Employee) query.getSingleResult();
144
153
145
        assertNotNull(emp);
154
            assertNotNull(emp);
146
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
155
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
147
156
148
        assertDefaultFetched(emp);
157
            assertDefaultFetched(emp);
149
158
150
        emp.getSalary();
159
            emp.getSalary();
151
160
152
        assertFetchedAttribute(emp, "salary");
161
            assertFetchedAttribute(emp, "salary");
153
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
162
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
154
163
155
        assertNoFetchGroup(emp.getAddress());
164
            assertNoFetchGroup(emp.getAddress());
156
165
157
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
166
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
158
167
159
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
168
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
160
            assertDefaultFetched(phone);
169
                assertDefaultFetched(phone);
161
        }
170
            }
162
171
163
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
172
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
164
173
165
        if (emp.getManager() != null) {
174
            if (emp.getManager() != null) {
166
            assertDefaultFetched(emp.getManager());
175
                assertDefaultFetched(emp.getManager());
167
            assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
176
                assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
168
        } else {
177
            } else {
169
            // If manager_id field is null then getManager() does not trigger an sql.
178
                // If manager_id field is null then getManager() does not trigger an sql.
170
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
179
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
180
            }
181
        } finally {
182
            if (isTransactionActive(em)){
183
                rollbackTransaction(em);
184
            }
185
            closeEntityManager(em);
171
        }
186
        }
172
173
    }
187
    }
174
188
175
    @Test
189
    @Test
176
    public void resultListDefaultFetchGroup() throws Exception {
190
    public void resultListDefaultFetchGroup() throws Exception {
177
        EntityManager em = createEntityManager("fieldaccess");
191
        EntityManager em = createEntityManager("fieldaccess");
192
        try {
193
            beginTransaction(em);
194
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
195
            query.setParameter("ID", minimumEmployeeId(em));
178
196
179
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
197
            List<Employee> emps = query.getResultList();
180
        query.setParameter("ID", minimumEmployeeId(em));
181
198
182
        List<Employee> emps = query.getResultList();
199
            assertNotNull(emps);
200
            assertEquals(1, emps.size());
183
201
184
        assertNotNull(emps);
202
            Employee emp = emps.get(0);
185
        assertEquals(1, emps.size());
186
203
187
        Employee emp = emps.get(0);
204
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
205
            assertDefaultFetched(emp);
188
206
189
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
207
            emp.getSalary();
190
        assertDefaultFetched(emp);
191
208
192
        emp.getSalary();
209
            assertNoFetchGroup(emp);
210
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
193
211
194
        assertNoFetchGroup(emp);
212
            assertNoFetchGroup(emp.getAddress());
195
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
196
213
197
        assertNoFetchGroup(emp.getAddress());
214
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
198
215
199
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
216
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
217
                assertDefaultFetched(phone);
218
            }
219
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
200
220
201
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
221
            if (emp.getManager() != null) {
202
            assertDefaultFetched(phone);
222
                assertDefaultFetched(emp.getManager());
223
                assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
224
            } else {
225
                // If manager_id field is null then getManager() does not trigger an sql.
226
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
227
            }
228
        } finally {
229
            if (isTransactionActive(em)){
230
                rollbackTransaction(em);
231
            }
232
            closeEntityManager(em);
203
        }
233
        }
204
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
205
206
        if (emp.getManager() != null) {
207
            assertDefaultFetched(emp.getManager());
208
            assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
209
        } else {
210
            // If manager_id field is null then getManager() does not trigger an sql.
211
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
212
        }
213
214
    }
234
    }
215
235
216
    @Test
236
    @Test
Lines 224-471 Link Here
224
    }
244
    }
225
    void internalResultListWithJoinFetchAddress(boolean addAddressToFetchGroup) {
245
    void internalResultListWithJoinFetchAddress(boolean addAddressToFetchGroup) {
226
        EntityManager em = createEntityManager("fieldaccess");
246
        EntityManager em = createEntityManager("fieldaccess");
247
        try {
248
            beginTransaction(em);
249
            Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id = :ID");
250
            query.setParameter("ID", minimumEmployeeId(em));
251
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
227
252
228
        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id = :ID");
253
            FetchGroup fg = null;
229
        query.setParameter("ID", minimumEmployeeId(em));
254
            if(addAddressToFetchGroup) {
230
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
255
                // that returns clone of the default fetch group
256
                fg = employeeDescriptor.getFetchGroupManager().createDefaultFetchGroup();
257
                fg.addAttribute("address");
258
                query.setHint(QueryHints.FETCH_GROUP, fg);
259
            }
260
            Employee emp = (Employee)query.getSingleResult();
261
            int nSql = 2;
262
            if(!addAddressToFetchGroup) {
263
                // An extra sql to read employee's Address - 
264
                // because address attribute is not in the fetch group the Address object was not built
265
                // by join fetch - though the db row for address was read in.
266
                //
267
                // yet another extra sql generated when the whole employee object is read when address is set. 
268
                nSql = nSql + 2;
269
            }
231
270
232
        FetchGroup fg = null;
271
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
233
        if(addAddressToFetchGroup) {
272
            if(addAddressToFetchGroup) {
234
            // that returns clone of the default fetch group
273
                assertFetched(emp, fg);
235
            fg = employeeDescriptor.getFetchGroupManager().createDefaultFetchGroup();
274
            } else {
236
            fg.addAttribute("address");
275
                // the whole object has been instantiated when address has been set 
237
            query.setHint(QueryHints.FETCH_GROUP, fg);
276
                assertNoFetchGroup(emp);
238
        }
277
            }
239
        Employee emp = (Employee)query.getSingleResult();
240
        int nSql = 2;
241
        if(!addAddressToFetchGroup) {
242
            // An extra sql to read employee's Address - 
243
            // because address attribute is not in the fetch group the Address object was not built
244
            // by join fetch - though the db row for address was read in.
245
            //
246
            // yet another extra sql generated when the whole employee object is read when address is set. 
247
            nSql = nSql + 2;
248
        }
249
278
250
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
279
            // instantiates the whole object - unless already instantiated
251
        if(addAddressToFetchGroup) {
280
            emp.getSalary();
252
            assertFetched(emp, fg);
281
253
        } else {
254
            // the whole object has been instantiated when address has been set 
255
            assertNoFetchGroup(emp);
282
            assertNoFetchGroup(emp);
256
        }
283
            if(addAddressToFetchGroup) {
284
                nSql++;
285
            }
286
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
257
287
258
        // instantiates the whole object - unless already instantiated
288
            assertNoFetchGroup(emp.getAddress());
259
        emp.getSalary();
289
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
260
290
261
        assertNoFetchGroup(emp);
291
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
262
        if(addAddressToFetchGroup) {
292
                assertDefaultFetched(phone);
263
            nSql++;
293
            }
264
        }
294
            assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
265
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
266
295
267
        assertNoFetchGroup(emp.getAddress());
296
            if (emp.getManager() != null) {
268
        assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
297
                assertDefaultFetched(emp.getManager());
269
298
                assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
270
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
299
            } else {
271
            assertDefaultFetched(phone);
300
                // If manager_id field is null then getManager() does not trigger an sql.
301
                assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
302
            }
303
        } finally {
304
            if (isTransactionActive(em)){
305
                rollbackTransaction(em);
306
            }
307
            closeEntityManager(em);
272
        }
308
        }
273
        assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
274
275
        if (emp.getManager() != null) {
276
            assertDefaultFetched(emp.getManager());
277
            assertEquals(++nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
278
        } else {
279
            // If manager_id field is null then getManager() does not trigger an sql.
280
            assertEquals(nSql, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
281
        }
282
    }
309
    }
283
310
284
    @Test
311
    @Test
285
    public void singleResultNoFetchGroup() throws Exception {
312
    public void singleResultNoFetchGroup() throws Exception {
286
        EntityManager em = createEntityManager("fieldaccess");
313
        EntityManager em = createEntityManager("fieldaccess");
314
        try {
315
            beginTransaction(em);
287
316
288
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
317
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
289
        query.setParameter("ID", minimumEmployeeId(em));
318
            query.setParameter("ID", minimumEmployeeId(em));
290
319
291
        assertNull(getFetchGroup(query));
320
            assertNull(getFetchGroup(query));
292
        assertNotNull(employeeDescriptor.getFetchGroupManager().getDefaultFetchGroup());
321
            assertNotNull(employeeDescriptor.getFetchGroupManager().getDefaultFetchGroup());
293
322
294
        query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false");
323
            query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false");
295
        assertNull(getFetchGroup(query));
324
            assertNull(getFetchGroup(query));
296
325
297
        Employee emp = (Employee) query.getSingleResult();
326
            Employee emp = (Employee) query.getSingleResult();
298
327
299
        assertNotNull(emp);
328
            assertNotNull(emp);
300
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
329
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
301
        assertNoFetchGroup(emp);
330
            assertNoFetchGroup(emp);
302
        assertNoFetchGroup(emp.getAddress());
331
            assertNoFetchGroup(emp.getAddress());
303
332
304
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
333
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
305
334
306
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
335
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
307
            assertDefaultFetched(phone);
336
                assertDefaultFetched(phone);
337
            }
338
339
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
340
341
        } finally {
342
            if (isTransactionActive(em)){
343
                rollbackTransaction(em);
344
            }
345
            closeEntityManager(em);
308
        }
346
        }
309
310
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
311
    }
347
    }
312
348
313
    @Test
349
    @Test
314
    public void resultListNoFetchGroup() throws Exception {
350
    public void resultListNoFetchGroup() throws Exception {
315
        EntityManager em = createEntityManager("fieldaccess");
351
        EntityManager em = createEntityManager("fieldaccess");
352
        try {
353
            beginTransaction(em);
316
354
317
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
355
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
318
        query.setParameter("ID", minimumEmployeeId(em));
356
            query.setParameter("ID", minimumEmployeeId(em));
319
        query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false");
357
            query.setHint(QueryHints.FETCH_GROUP_DEFAULT, "false");
320
358
321
        List<Employee> emps = query.getResultList();
359
            List<Employee> emps = query.getResultList();
322
360
323
        assertNotNull(emps);
361
            assertNotNull(emps);
324
        assertEquals(1, emps.size());
362
            assertEquals(1, emps.size());
325
363
326
        Employee emp = emps.get(0);
364
            Employee emp = emps.get(0);
327
365
328
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
366
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
329
367
330
        assertNoFetchGroup(emp);
368
            assertNoFetchGroup(emp);
331
        assertNoFetchGroup(emp.getAddress());
369
            assertNoFetchGroup(emp.getAddress());
332
370
333
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
371
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
334
372
335
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
373
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
336
            assertDefaultFetched(phone);
374
                assertDefaultFetched(phone);
375
            }
376
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
377
        } finally {
378
            if (isTransactionActive(em)){
379
                rollbackTransaction(em);
380
            }
381
            closeEntityManager(em);
337
        }
382
        }
338
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
339
    }
383
    }
340
384
341
    @Test
385
    @Test
342
    public void emptyFetchGroup() throws Exception {
386
    public void emptyFetchGroup() throws Exception {
343
        EntityManager em = createEntityManager("fieldaccess");
387
        EntityManager em = createEntityManager("fieldaccess");
388
        try {
389
            beginTransaction(em);
344
390
345
        // Use q query since find will only use default fetch group
391
            // Use q query since find will only use default fetch group
346
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
392
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
347
        query.setParameter("ID", minimumEmployeeId(em));
393
            query.setParameter("ID", minimumEmployeeId(em));
348
        FetchGroup emptyFG = new FetchGroup("empty@" + System.currentTimeMillis());
394
            FetchGroup emptyFG = new FetchGroup("empty@" + System.currentTimeMillis());
349
        query.setHint(QueryHints.FETCH_GROUP, emptyFG);
395
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);
350
396
351
        assertEquals(emptyFG, getFetchGroup(query));
397
            assertEquals(emptyFG, getFetchGroup(query));
352
398
353
        Employee emp = (Employee) query.getSingleResult();
399
            Employee emp = (Employee) query.getSingleResult();
354
400
355
        assertFetched(emp, emptyFG);
401
            assertFetched(emp, emptyFG);
356
402
357
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
403
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
358
            assertDefaultFetched(phone);
404
                assertDefaultFetched(phone);
359
            phone.getAreaCode();
405
                phone.getAreaCode();
360
            assertNoFetchGroup(phone);
406
                assertNoFetchGroup(phone);
407
            }
408
        } finally {
409
            if (isTransactionActive(em)){
410
                rollbackTransaction(em);
411
            }
412
            closeEntityManager(em);
361
        }
413
        }
362
    }
414
    }
363
415
364
    @Test
416
    @Test
365
    public void managerFetchGroup() throws Exception {
417
    public void managerFetchGroup() throws Exception {
366
        EntityManager em = createEntityManager("fieldaccess");
418
        EntityManager em = createEntityManager("fieldaccess");
419
        try {
420
            beginTransaction(em);
367
421
368
        // Use q query since find will only use default fetch group
422
            //Use q query since find will only use default fetch group
369
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
423
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
370
//        query.setParameter("ID", minimumEmployeeId(em));
424
            //query.setParameter("ID", minimumEmployeeId(em));
371
        
425
            
372
        // Complex where clause used to avoid triggering employees and their departments:
426
            //Complex where clause used to avoid triggering employees and their departments:
373
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
427
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
374
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
428
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
375
        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");
429
            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");
376
        FetchGroup managerFG = new FetchGroup();
430
            FetchGroup managerFG = new FetchGroup();
377
        managerFG.addAttribute("manager");
431
            managerFG.addAttribute("manager");
378
432
379
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
433
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
380
        query.setHint(QueryHints.LEFT_FETCH, "e.manager");
434
            query.setHint(QueryHints.LEFT_FETCH, "e.manager");
381
435
382
        assertEquals(managerFG, getFetchGroup(query));
436
            assertEquals(managerFG, getFetchGroup(query));
383
437
384
        List employees = query.getResultList();
438
            List employees = query.getResultList();
385
        Employee emp = (Employee)employees.get(0);
439
            Employee emp = (Employee)employees.get(0);
386
440
387
        assertFetched(emp, managerFG);
441
            assertFetched(emp, managerFG);
388
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
442
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
389
443
390
        emp.getManager();
444
            emp.getManager();
391
445
392
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
446
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
393
        assertFetched(emp, managerFG);
447
            assertFetched(emp, managerFG);
394
448
395
        emp.getLastName();
449
            emp.getLastName();
396
450
397
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
451
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
398
        assertNoFetchGroup(emp);
452
            assertNoFetchGroup(emp);
399
453
400
        int numPhones = 0;
454
            int numPhones = 0;
401
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
455
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
402
            assertDefaultFetched(phone);
456
                assertDefaultFetched(phone);
403
457
404
            phone.getAreaCode();
458
                phone.getAreaCode();
405
459
406
            assertNoFetchGroup(phone);
460
                assertNoFetchGroup(phone);
407
            numPhones++;
461
                numPhones++;
462
            }
463
            // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group
464
            assertEquals(3 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
465
        } finally {
466
            if (isTransactionActive(em)){
467
                rollbackTransaction(em);
468
            }
469
            closeEntityManager(em);
408
        }
470
        }
409
        // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group
410
        assertEquals(3 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
411
    }
471
    }
412
472
413
    @Test
473
    @Test
414
    public void employeeNamesFetchGroup() throws Exception {
474
    public void employeeNamesFetchGroup() throws Exception {
415
        EntityManager em = createEntityManager("fieldaccess");
475
        EntityManager em = createEntityManager("fieldaccess");
476
        try {
477
            beginTransaction(em);
416
478
417
        int minId = minimumEmployeeId(em);
479
            int minId = minimumEmployeeId(em);
418
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
480
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
419
481
420
        // Use q query since find will only use default fetch group
482
            // Use q query since find will only use default fetch group
421
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
483
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
422
        query.setParameter("ID", minId);
484
            query.setParameter("ID", minId);
423
485
424
        FetchGroup namesFG = new FetchGroup();
486
            FetchGroup namesFG = new FetchGroup();
425
        namesFG.addAttribute("firstName");
487
            namesFG.addAttribute("firstName");
426
        namesFG.addAttribute("lastName");
488
            namesFG.addAttribute("lastName");
427
        query.setHint(QueryHints.FETCH_GROUP, namesFG);
489
            query.setHint(QueryHints.FETCH_GROUP, namesFG);
428
490
429
        assertNotNull(getFetchGroup(query));
491
            assertNotNull(getFetchGroup(query));
430
        assertSame(namesFG, getFetchGroup(query));
492
            assertSame(namesFG, getFetchGroup(query));
431
493
432
        Employee emp = (Employee) query.getSingleResult();
494
            Employee emp = (Employee) query.getSingleResult();
433
495
434
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
496
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
435
        assertFetched(emp, namesFG);
497
            assertFetched(emp, namesFG);
436
498
437
        emp.getId();
499
            emp.getId();
438
        emp.getFirstName();
500
            emp.getFirstName();
439
        emp.getLastName();
501
            emp.getLastName();
440
        emp.getVersion();
502
            emp.getVersion();
441
503
442
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
504
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
443
        assertFetched(emp, namesFG);
505
            assertFetched(emp, namesFG);
444
506
445
        emp.getGender();
507
            emp.getGender();
446
        emp.getSalary();
508
            emp.getSalary();
447
509
448
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
510
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
449
        assertNoFetchGroup(emp);
511
            assertNoFetchGroup(emp);
450
512
451
        int numPhones = 0;
513
            int numPhones = 0;
452
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
514
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
453
            assertDefaultFetched(phone);
515
                assertDefaultFetched(phone);
454
516
455
            phone.getAreaCode();
517
                phone.getAreaCode();
456
518
457
            assertNoFetchGroup(phone);
519
                assertNoFetchGroup(phone);
458
            numPhones++;
520
                numPhones++;
459
        }
521
            }
460
        // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group
522
            // 1 sql to read all the phones with a fetch group + 1 sql per phone to re-read each phone without fetch group
461
        assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
523
            assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
462
524
463
        if(emp.getManager() != null) {
525
            if(emp.getManager() != null) {
464
            assertEquals(5 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
526
                assertEquals(5 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
465
            assertDefaultFetched(emp.getManager());
527
                assertDefaultFetched(emp.getManager());
466
        } else {
528
            } else {
467
            // If manager_id field is null then getManager() does not trigger an sql.
529
                // If manager_id field is null then getManager() does not trigger an sql.
468
            assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
530
                assertEquals(4 + numPhones, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
531
            }
532
        } finally {
533
            if (isTransactionActive(em)){
534
                rollbackTransaction(em);
535
            }
536
            closeEntityManager(em);
469
        }
537
        }
470
    }
538
    }
471
539
Lines 553-585 Link Here
553
    }
621
    }
554
    void internalJoinFetchEmployeeAddressPhoneWithDynamicFetchGroup(boolean addAddressToFetchGroup) {
622
    void internalJoinFetchEmployeeAddressPhoneWithDynamicFetchGroup(boolean addAddressToFetchGroup) {
555
        EntityManager em = createEntityManager("fieldaccess");
623
        EntityManager em = createEntityManager("fieldaccess");
624
        try {
625
            beginTransaction(em);
556
626
557
        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.owner.id FROM PhoneNumber p)");
627
            Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.owner.id FROM PhoneNumber p)");
558
628
559
        FetchGroup fetchGroup = new FetchGroup("names");
629
            FetchGroup fetchGroup = new FetchGroup("names");
560
        fetchGroup.addAttribute("firstName");
630
            fetchGroup.addAttribute("firstName");
561
        fetchGroup.addAttribute("lastName");
631
            fetchGroup.addAttribute("lastName");
562
        if(addAddressToFetchGroup) {
632
            if(addAddressToFetchGroup) {
563
            fetchGroup.addAttribute("address");
633
                fetchGroup.addAttribute("address");
564
        }
634
            }
565
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
635
            query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
566
636
567
        List<Employee> emps = query.getResultList();
637
            List<Employee> emps = query.getResultList();
568
        assertNotNull(emps);
638
            assertNotNull(emps);
569
639
570
        if(addAddressToFetchGroup) {
571
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
572
        } else {
573
            assertEquals(1 + 2*emps.size(), getQuerySQLTracker(em).getTotalSQLSELECTCalls());
574
        }
575
        for (Employee emp : emps) {
576
            if(addAddressToFetchGroup) {
640
            if(addAddressToFetchGroup) {
577
                assertFetched(emp, fetchGroup);
641
                assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
578
            } else {
642
            } else {
579
                // the whole object has been instantiated when address has been set 
643
                assertEquals(1 + 2*emps.size(), getQuerySQLTracker(em).getTotalSQLSELECTCalls());
580
                assertNoFetchGroup(emp);
581
            }
644
            }
645
            for (Employee emp : emps) {
646
                if(addAddressToFetchGroup) {
647
                    assertFetched(emp, fetchGroup);
648
                } else {
649
                    // the whole object has been instantiated when address has been set 
650
                    assertNoFetchGroup(emp);
651
                }
582
        }
652
        }
653
        } finally {
654
            if (isTransactionActive(em)){
655
                rollbackTransaction(em);
656
            }
657
            closeEntityManager(em);
658
        }
583
    }
659
    }
584
660
585
    public static class EmployeeCustomizer implements DescriptorCustomizer {
661
    public static class EmployeeCustomizer implements DescriptorCustomizer {
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleFetchGroupTests.java (-337 / +418 lines)
Lines 55-62 Link Here
55
        suite.addTest(new SimpleFetchGroupTests("findNoFetchGroup"));
55
        suite.addTest(new SimpleFetchGroupTests("findNoFetchGroup"));
56
        suite.addTest(new SimpleFetchGroupTests("singleResultNoFetchGroup"));
56
        suite.addTest(new SimpleFetchGroupTests("singleResultNoFetchGroup"));
57
        suite.addTest(new SimpleFetchGroupTests("resultListNoFetchGroup"));
57
        suite.addTest(new SimpleFetchGroupTests("resultListNoFetchGroup"));
58
        suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup"));
59
        suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary"));
60
        suite.addTest(new SimpleFetchGroupTests("singleResultEmptyFetchGroup"));
58
        suite.addTest(new SimpleFetchGroupTests("singleResultEmptyFetchGroup"));
61
        suite.addTest(new SimpleFetchGroupTests("resultListEmptyFetchGroup"));
59
        suite.addTest(new SimpleFetchGroupTests("resultListEmptyFetchGroup"));
62
        suite.addTest(new SimpleFetchGroupTests("resultListPeriodFetchGroup"));
60
        suite.addTest(new SimpleFetchGroupTests("resultListPeriodFetchGroup"));
Lines 65-75 Link Here
65
        suite.addTest(new SimpleFetchGroupTests("employeeNamesFetchGroup"));
63
        suite.addTest(new SimpleFetchGroupTests("employeeNamesFetchGroup"));
66
        suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
64
        suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
67
        suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
65
        suite.addTest(new SimpleFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
68
        suite.addTest(new SimpleFetchGroupTests("verifyUnfetchedAttributes"));
69
        suite.addTest(new SimpleFetchGroupTests("verifyFetchedRelationshipAttributes"));
66
        suite.addTest(new SimpleFetchGroupTests("verifyFetchedRelationshipAttributes"));
70
        suite.addTest(new SimpleFetchGroupTests("detachedByClosingEntityManagerObjectWithFetchGroup"));
67
        suite.addTest(new SimpleFetchGroupTests("detachedByClosingEntityManagerObjectWithFetchGroup"));
71
        suite.addTest(new SimpleFetchGroupTests("explicitlyDetachedObjectWithFetchGroup"));
68
        if (!isJPA10()) {
72
        
69
            suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup"));
70
            suite.addTest(new SimpleFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary"));
71
            suite.addTest(new SimpleFetchGroupTests("verifyUnfetchedAttributes"));
72
            suite.addTest(new SimpleFetchGroupTests("explicitlyDetachedObjectWithFetchGroup"));
73
        }
73
        return suite;
74
        return suite;
74
    }
75
    }
75
    
76
    
Lines 176-352 Link Here
176
    @Test
177
    @Test
177
    public void findEmptyFetchGroup() throws Exception {
178
    public void findEmptyFetchGroup() throws Exception {
178
        EntityManager em = createEntityManager("fieldaccess");
179
        EntityManager em = createEntityManager("fieldaccess");
179
        int minId = minimumEmployeeId(em);
180
        try {
181
            beginTransaction(em);
180
182
181
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
183
            int minId = minimumEmployeeId(em);
182
184
183
        Map<String, Object> properties = new HashMap<String, Object>();
185
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
184
        FetchGroup emptyFG = new FetchGroup();
185
        properties.put(QueryHints.FETCH_GROUP, emptyFG);
186
186
187
        Employee emp = em.find(Employee.class, minId, properties);
187
            Map<String, Object> properties = new HashMap<String, Object>();
188
            FetchGroup emptyFG = new FetchGroup();
189
            properties.put(QueryHints.FETCH_GROUP, emptyFG);
188
190
189
        assertNotNull(emp);
191
            Employee emp = em.find(Employee.class, minId, properties);
190
        assertFetched(emp, emptyFG);
191
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
192
192
193
        // Check Basics
193
            assertNotNull(emp);
194
        assertFetchedAttribute(emp, "id");
194
            assertFetched(emp, emptyFG);
195
        assertFetchedAttribute(emp, "version");
195
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
196
        assertNotFetchedAttribute(emp, "firstName");
197
        assertNotFetchedAttribute(emp, "lastName");
198
        assertNotFetchedAttribute(emp, "gender");
199
        assertNotFetchedAttribute(emp, "salary");
200
        assertNotFetchedAttribute(emp, "startTime");
201
        assertNotFetchedAttribute(emp, "endTime");
202
        if (emp.getPeriod() != null) {
203
            assertFetchedAttribute(emp.getPeriod(), "startDate");
204
            assertFetchedAttribute(emp.getPeriod(), "endDate");
205
        }
206
196
207
        // Check Relationships
197
            // Check Basics
208
        assertNotFetchedAttribute(emp, "address");
198
            assertFetchedAttribute(emp, "id");
209
        assertNotFetchedAttribute(emp, "manager");
199
            assertFetchedAttribute(emp, "version");
210
        assertNotFetchedAttribute(emp, "phoneNumbers");
200
            assertNotFetchedAttribute(emp, "firstName");
211
        assertNotFetchedAttribute(emp, "projects");
201
            assertNotFetchedAttribute(emp, "lastName");
202
            assertNotFetchedAttribute(emp, "gender");
203
            assertNotFetchedAttribute(emp, "salary");
204
            assertNotFetchedAttribute(emp, "startTime");
205
            assertNotFetchedAttribute(emp, "endTime");
206
            if (emp.getPeriod() != null) {
207
                assertFetchedAttribute(emp.getPeriod(), "startDate");
208
                assertFetchedAttribute(emp.getPeriod(), "endDate");
209
            }
212
210
213
        emp.getSalary();
211
            // Check Relationships
212
            assertNotFetchedAttribute(emp, "address");
213
            assertNotFetchedAttribute(emp, "manager");
214
            assertNotFetchedAttribute(emp, "phoneNumbers");
215
            assertNotFetchedAttribute(emp, "projects");
214
216
215
        assertFetchedAttribute(emp, "salary");
217
            emp.getSalary();
216
218
217
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
219
            assertFetchedAttribute(emp, "salary");
218
        assertNoFetchGroup(emp);
219
220
220
        emp.getAddress();
221
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
222
            assertNoFetchGroup(emp);
221
223
222
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
224
            emp.getAddress();
223
        assertNoFetchGroup(emp.getAddress());
224
225
225
        emp.getPhoneNumbers().size();
226
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
227
            assertNoFetchGroup(emp.getAddress());
226
228
227
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
229
            emp.getPhoneNumbers().size();
228
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
229
            assertNoFetchGroup(phone);
230
        }
231
230
232
        if (emp.getManager() != null) {
233
            assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
234
        } else {
235
            // If manager_id field is null then getManager() does not trigger an sql.
236
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
231
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
232
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
233
                assertNoFetchGroup(phone);
234
            }
235
236
            if (emp.getManager() != null) {
237
                assertEquals(6, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
238
            } else {
239
                // If manager_id field is null then getManager() does not trigger an sql.
240
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
241
            } 
242
        }finally {
243
            if (isTransactionActive(em)){
244
                rollbackTransaction(em);
245
            }
246
            closeEntityManager(em);
237
        }
247
        }
238
    }
248
    }
239
249
240
    @Test
250
    @Test
241
    public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception {
251
    public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception {
242
        EntityManager em = createEntityManager("fieldaccess");
252
        EntityManager em = createEntityManager("fieldaccess");
243
        int minId = minimumEmployeeId(em);
253
        try {
254
            beginTransaction(em);
244
255
245
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
256
            int minId = minimumEmployeeId(em);
246
257
247
        Map<String, Object> properties = new HashMap<String, Object>();
258
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
248
        FetchGroup emptyFG = new FetchGroup();
249
        properties.put(QueryHints.FETCH_GROUP, emptyFG);
250
259
251
        Employee emp = em.find(Employee.class, minId, properties);
260
            Map<String, Object> properties = new HashMap<String, Object>();
261
            FetchGroup emptyFG = new FetchGroup();
262
            properties.put(QueryHints.FETCH_GROUP, emptyFG);
252
263
253
        assertNotNull(emp);
264
            Employee emp = em.find(Employee.class, minId, properties);
254
        assertFetched(emp, emptyFG);
255
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
256
265
257
        // Check Basics
266
            assertNotNull(emp);
258
        assertFetchedAttribute(emp, "id");
267
            assertFetched(emp, emptyFG);
259
        assertFetchedAttribute(emp, "version");
268
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
260
        assertNotFetchedAttribute(emp, "firstName");
261
        assertNotFetchedAttribute(emp, "lastName");
262
        assertNotFetchedAttribute(emp, "gender");
263
        assertNotFetchedAttribute(emp, "salary");
264
        assertNotFetchedAttribute(emp, "startTime");
265
        assertNotFetchedAttribute(emp, "endTime");
266
        if (emp.getPeriod() != null) {
267
            assertFetchedAttribute(emp.getPeriod(), "startDate");
268
            assertFetchedAttribute(emp.getPeriod(), "endDate");
269
        }
270
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
271
269
272
        // Check Relationships
270
            // Check Basics
273
        assertNotFetchedAttribute(emp, "address");
271
            assertFetchedAttribute(emp, "id");
274
        assertNotFetchedAttribute(emp, "manager");
272
            assertFetchedAttribute(emp, "version");
275
        assertNotFetchedAttribute(emp, "phoneNumbers");
273
            assertNotFetchedAttribute(emp, "firstName");
276
        assertNotFetchedAttribute(emp, "projects");
274
            assertNotFetchedAttribute(emp, "lastName");
275
            assertNotFetchedAttribute(emp, "gender");
276
            assertNotFetchedAttribute(emp, "salary");
277
            assertNotFetchedAttribute(emp, "startTime");
278
            assertNotFetchedAttribute(emp, "endTime");
279
            if (emp.getPeriod() != null) {
280
                assertFetchedAttribute(emp.getPeriod(), "startDate");
281
                assertFetchedAttribute(emp.getPeriod(), "endDate");
282
            }
283
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
277
284
278
        emp.setSalary(1);
285
            // Check Relationships
286
            assertNotFetchedAttribute(emp, "address");
287
            assertNotFetchedAttribute(emp, "manager");
288
            assertNotFetchedAttribute(emp, "phoneNumbers");
289
            assertNotFetchedAttribute(emp, "projects");
279
290
280
        assertFetchedAttribute(emp, "salary");
291
            emp.setSalary(1);
281
292
282
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
293
            assertFetchedAttribute(emp, "salary");
283
        assertNoFetchGroup(emp);
284
294
285
        emp.getAddress();
295
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
296
            assertNoFetchGroup(emp);
286
297
287
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
298
            emp.getAddress();
288
        assertNoFetchGroup(emp.getAddress());
289
299
290
        emp.getPhoneNumbers().size();
300
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
301
            assertNoFetchGroup(emp.getAddress());
291
302
292
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
303
            emp.getPhoneNumbers().size();
293
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
304
294
            assertNoFetchGroup(phone);
305
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
306
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
307
                assertNoFetchGroup(phone);
308
            }
309
        } finally {
310
            if (isTransactionActive(em)){
311
                rollbackTransaction(em);
312
            }
313
            closeEntityManager(em);
295
        }
314
        }
296
    }
315
    }
297
316
298
    @Test
317
    @Test
299
    public void singleResultEmptyFetchGroup() throws Exception {
318
    public void singleResultEmptyFetchGroup() throws Exception {
300
        EntityManager em = createEntityManager("fieldaccess");
319
        EntityManager em = createEntityManager("fieldaccess");
320
        try {
321
            beginTransaction(em);
301
322
302
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
323
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
303
        query.setParameter("ID", minimumEmployeeId(em));
324
            query.setParameter("ID", minimumEmployeeId(em));
304
        FetchGroup emptyFG = new FetchGroup();
325
            FetchGroup emptyFG = new FetchGroup();
305
        query.setHint(QueryHints.FETCH_GROUP, emptyFG);
326
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);
306
327
307
        Employee emp = (Employee) query.getSingleResult();
328
            Employee emp = (Employee) query.getSingleResult();
308
329
309
        assertNotNull(emp);
330
            assertNotNull(emp);
310
        assertFetched(emp, emptyFG);
331
            assertFetched(emp, emptyFG);
311
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
332
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
312
333
313
        // Check Basics
334
            // Check Basics
314
        assertFetchedAttribute(emp, "id");
335
            assertFetchedAttribute(emp, "id");
315
        assertFetchedAttribute(emp, "version");
336
            assertFetchedAttribute(emp, "version");
316
        assertNotFetchedAttribute(emp, "firstName");
337
            assertNotFetchedAttribute(emp, "firstName");
317
        assertNotFetchedAttribute(emp, "lastName");
338
            assertNotFetchedAttribute(emp, "lastName");
318
        assertNotFetchedAttribute(emp, "gender");
339
            assertNotFetchedAttribute(emp, "gender");
319
        assertNotFetchedAttribute(emp, "salary");
340
            assertNotFetchedAttribute(emp, "salary");
320
        assertNotFetchedAttribute(emp, "startTime");
341
            assertNotFetchedAttribute(emp, "startTime");
321
        assertNotFetchedAttribute(emp, "endTime");
342
            assertNotFetchedAttribute(emp, "endTime");
322
        if (emp.getPeriod() != null) {
343
            if (emp.getPeriod() != null) {
323
            assertFetchedAttribute(emp.getPeriod(), "startDate");
344
                assertFetchedAttribute(emp.getPeriod(), "startDate");
324
            assertFetchedAttribute(emp.getPeriod(), "endDate");
345
                assertFetchedAttribute(emp.getPeriod(), "endDate");
325
        }
346
            }
326
347
327
        // Check Relationships
348
            // Check Relationships
328
        assertNotFetchedAttribute(emp, "address");
349
            assertNotFetchedAttribute(emp, "address");
329
        assertNotFetchedAttribute(emp, "manager");
350
            assertNotFetchedAttribute(emp, "manager");
330
        assertNotFetchedAttribute(emp, "phoneNumbers");
351
            assertNotFetchedAttribute(emp, "phoneNumbers");
331
        assertNotFetchedAttribute(emp, "projects");
352
            assertNotFetchedAttribute(emp, "projects");
332
353
333
        emp.getSalary();
354
            emp.getSalary();
334
355
335
        assertFetchedAttribute(emp, "salary");
356
            assertFetchedAttribute(emp, "salary");
336
357
337
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
358
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
338
        assertNoFetchGroup(emp);
359
            assertNoFetchGroup(emp);
339
360
340
        emp.getAddress();
361
            emp.getAddress();
341
362
342
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
363
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
343
        assertNoFetchGroup(emp.getAddress());
364
            assertNoFetchGroup(emp.getAddress());
344
365
345
        emp.getPhoneNumbers().size();
366
            emp.getPhoneNumbers().size();
346
367
347
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
368
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
348
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
369
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
349
            assertNoFetchGroup(phone);
370
                assertNoFetchGroup(phone);
371
            }
372
        } finally {
373
            if (isTransactionActive(em)){
374
                rollbackTransaction(em);
375
            }
376
            closeEntityManager(em);
350
        }
377
        }
351
    }
378
    }
352
379
Lines 356-414 Link Here
356
    @Test
383
    @Test
357
    public void resultListEmptyFetchGroup() throws Exception {
384
    public void resultListEmptyFetchGroup() throws Exception {
358
        EntityManager em = createEntityManager("fieldaccess");
385
        EntityManager em = createEntityManager("fieldaccess");
386
        try {
387
            beginTransaction(em);
359
388
360
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
389
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
361
        query.setParameter("ID", minimumEmployeeId(em));
390
            query.setParameter("ID", minimumEmployeeId(em));
362
        FetchGroup emptyFG = new FetchGroup();
391
            FetchGroup emptyFG = new FetchGroup();
363
        query.setHint(QueryHints.FETCH_GROUP, emptyFG);
392
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);
364
393
365
        List<Employee> emps = query.getResultList();
394
            List<Employee> emps = query.getResultList();
366
395
367
        assertNotNull(emps);
396
            assertNotNull(emps);
368
        assertEquals(1, emps.size());
397
            assertEquals(1, emps.size());
369
398
370
        Employee emp = emps.get(0);
399
            Employee emp = emps.get(0);
371
400
372
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
401
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
373
        assertFetched(emp, emptyFG);
402
            assertFetched(emp, emptyFG);
374
403
375
        // Check Basics
404
            // Check Basics
376
        assertFetchedAttribute(emp, "id");
405
            assertFetchedAttribute(emp, "id");
377
        assertFetchedAttribute(emp, "version");
406
            assertFetchedAttribute(emp, "version");
378
        assertNotFetchedAttribute(emp, "firstName");
407
            assertNotFetchedAttribute(emp, "firstName");
379
        assertNotFetchedAttribute(emp, "lastName");
408
            assertNotFetchedAttribute(emp, "lastName");
380
        assertNotFetchedAttribute(emp, "gender");
409
            assertNotFetchedAttribute(emp, "gender");
381
        assertNotFetchedAttribute(emp, "salary");
410
            assertNotFetchedAttribute(emp, "salary");
382
        assertNotFetchedAttribute(emp, "startTime");
411
            assertNotFetchedAttribute(emp, "startTime");
383
        assertNotFetchedAttribute(emp, "endTime");
412
            assertNotFetchedAttribute(emp, "endTime");
384
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
413
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
385
        if (emp.getPeriod() != null) {
414
            if (emp.getPeriod() != null) {
386
            assertFetchedAttribute(emp.getPeriod(), "startDate");
415
                assertFetchedAttribute(emp.getPeriod(), "startDate");
387
            assertFetchedAttribute(emp.getPeriod(), "endDate");
416
                assertFetchedAttribute(emp.getPeriod(), "endDate");
388
        }
417
            }
389
418
390
        // Check Relationships
419
            // Check Relationships
391
        assertNotFetchedAttribute(emp, "address");
420
            assertNotFetchedAttribute(emp, "address");
392
        assertNotFetchedAttribute(emp, "manager");
421
            assertNotFetchedAttribute(emp, "manager");
393
        assertNotFetchedAttribute(emp, "phoneNumbers");
422
            assertNotFetchedAttribute(emp, "phoneNumbers");
394
        assertNotFetchedAttribute(emp, "projects");
423
            assertNotFetchedAttribute(emp, "projects");
395
424
396
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
425
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
397
426
398
        emp.getSalary();
427
            emp.getSalary();
399
428
400
        assertFetchedAttribute(emp, "salary");
429
            assertFetchedAttribute(emp, "salary");
401
        assertNoFetchGroup(emp);
430
            assertNoFetchGroup(emp);
402
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
431
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
403
432
404
        assertNoFetchGroup(emp.getAddress());
433
            assertNoFetchGroup(emp.getAddress());
405
434
406
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
435
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
407
436
408
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
437
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
409
            assertNoFetchGroup(phone);
438
                assertNoFetchGroup(phone);
439
            }
440
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
441
        } finally {
442
            if (isTransactionActive(em)){
443
                rollbackTransaction(em);
444
            }
445
            closeEntityManager(em);
410
        }
446
        }
411
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
412
    }
447
    }
413
448
414
    /**
449
    /**
Lines 417-625 Link Here
417
    @Test
452
    @Test
418
    public void resultListPeriodFetchGroup() throws Exception {
453
    public void resultListPeriodFetchGroup() throws Exception {
419
        EntityManager em = createEntityManager("fieldaccess");
454
        EntityManager em = createEntityManager("fieldaccess");
455
        try {
456
            beginTransaction(em);
420
457
421
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
458
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
422
        query.setParameter("ID", minimumEmployeeId(em));
459
            query.setParameter("ID", minimumEmployeeId(em));
423
        FetchGroup fg = new FetchGroup();
460
            FetchGroup fg = new FetchGroup();
424
        fg.addAttribute("period");
461
            fg.addAttribute("period");
425
        query.setHint(QueryHints.FETCH_GROUP, fg);
462
            query.setHint(QueryHints.FETCH_GROUP, fg);
426
463
427
        List<Employee> emps = query.getResultList();
464
            List<Employee> emps = query.getResultList();
428
465
429
        assertNotNull(emps);
466
            assertNotNull(emps);
430
        assertEquals(1, emps.size());
467
            assertEquals(1, emps.size());
431
468
432
        Employee emp = emps.get(0);
469
            Employee emp = emps.get(0);
433
470
434
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
471
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
435
        assertFetched(emp, fg);
472
            assertFetched(emp, fg);
436
473
437
        // Check Basics
474
            // Check Basics
438
        assertFetchedAttribute(emp, "id");
475
            assertFetchedAttribute(emp, "id");
439
        assertFetchedAttribute(emp, "version");
476
            assertFetchedAttribute(emp, "version");
440
        assertNotFetchedAttribute(emp, "firstName");
477
            assertNotFetchedAttribute(emp, "firstName");
441
        assertNotFetchedAttribute(emp, "lastName");
478
            assertNotFetchedAttribute(emp, "lastName");
442
        assertNotFetchedAttribute(emp, "gender");
479
            assertNotFetchedAttribute(emp, "gender");
443
        assertNotFetchedAttribute(emp, "salary");
480
            assertNotFetchedAttribute(emp, "salary");
444
        assertNotFetchedAttribute(emp, "startTime");
481
            assertNotFetchedAttribute(emp, "startTime");
445
        assertNotFetchedAttribute(emp, "endTime");
482
            assertNotFetchedAttribute(emp, "endTime");
446
        if (emp.getPeriod() != null) {
483
            if (emp.getPeriod() != null) {
447
            assertFetchedAttribute(emp.getPeriod(), "startDate");
484
                assertFetchedAttribute(emp.getPeriod(), "startDate");
448
            assertFetchedAttribute(emp.getPeriod(), "endDate");
485
                assertFetchedAttribute(emp.getPeriod(), "endDate");
449
        }
486
            }
450
487
451
        // Check Relationships
488
            // Check Relationships
452
        assertNotFetchedAttribute(emp, "address");
489
            assertNotFetchedAttribute(emp, "address");
453
        assertNotFetchedAttribute(emp, "manager");
490
            assertNotFetchedAttribute(emp, "manager");
454
        assertNotFetchedAttribute(emp, "phoneNumbers");
491
            assertNotFetchedAttribute(emp, "phoneNumbers");
455
        assertNotFetchedAttribute(emp, "projects");
492
            assertNotFetchedAttribute(emp, "projects");
456
493
457
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
494
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
458
495
459
        emp.getSalary();
496
            emp.getSalary();
460
497
461
        assertFetchedAttribute(emp, "salary");
498
            assertFetchedAttribute(emp, "salary");
462
        assertNoFetchGroup(emp);
499
            assertNoFetchGroup(emp);
463
500
464
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
501
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
465
502
466
        assertNoFetchGroup(emp.getAddress());
503
            assertNoFetchGroup(emp.getAddress());
467
504
468
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
505
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
469
506
470
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
507
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
471
            assertNoFetchGroup(phone);
508
                assertNoFetchGroup(phone);
509
            }
510
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
511
        } finally {
512
            if (isTransactionActive(em)){
513
                rollbackTransaction(em);
514
            }
515
            closeEntityManager(em);
472
        }
516
        }
473
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
474
    }
517
    }
475
518
476
    @Test
519
    @Test
477
    public void managerFetchGroup() throws Exception {
520
    public void managerFetchGroup() throws Exception {
478
        EntityManager em = createEntityManager("fieldaccess");
521
        EntityManager em = createEntityManager("fieldaccess");
522
        try {
523
            beginTransaction(em);
479
524
480
        // Use q query since find will only use default fetch group
525
            // Use q query since find will only use default fetch group
481
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
526
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
482
//        query.setParameter("ID", minimumEmployeeId(em));
527
            //query.setParameter("ID", minimumEmployeeId(em));
483
        
528
            
484
        // Complex where clause used to avoid triggering employees and their departments:
529
            // Complex where clause used to avoid triggering employees and their departments:
485
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
530
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
486
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
531
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
487
        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");
532
            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");
488
533
489
        FetchGroup managerFG = new FetchGroup();
534
            FetchGroup managerFG = new FetchGroup();
490
        managerFG.addAttribute("manager");
535
            managerFG.addAttribute("manager");
491
536
492
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
537
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
493
538
494
        assertNotNull(getFetchGroup(query));
539
            assertNotNull(getFetchGroup(query));
495
        assertSame(managerFG, getFetchGroup(query));
540
            assertSame(managerFG, getFetchGroup(query));
496
541
497
        Employee emp = (Employee) query.getSingleResult();
542
            Employee emp = (Employee) query.getSingleResult();
498
543
499
        assertFetched(emp, managerFG);
544
            assertFetched(emp, managerFG);
500
//        int nSqlBeforeGetManager = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
545
            //int nSqlBeforeGetManager = getQuerySQLTracker(em).getTotalSQLSELECTCalls();
501
        // manager hasn't been instantiated yet
546
            // manager hasn't been instantiated yet
502
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
547
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
503
        
548
            
504
        int nSqlToAdd = 0;
549
            int nSqlToAdd = 0;
505
        if (emp.getManager() != null) {
550
            if (emp.getManager() != null) {
506
            assertFetchedAttribute(emp, "manager");
551
                assertFetchedAttribute(emp, "manager");
507
            // additional sql to select the manager
552
                // additional sql to select the manager
508
            nSqlToAdd++;
553
                nSqlToAdd++;
509
        }        
554
            }
510
        assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
555
            assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
511
        
556
            
512
        // acuses instantioation of the whole object
557
            // acuses instantioation of the whole object
513
        emp.getLastName();
558
            emp.getLastName();
514
559
515
        assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
560
            assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
516
        assertNoFetchGroup(emp);
561
            assertNoFetchGroup(emp);
517
562
518
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
563
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
519
            assertNoFetchGroup(phone);
564
                assertNoFetchGroup(phone);
520
            phone.getAreaCode();
565
                phone.getAreaCode();
566
            }
567
568
            assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
569
        } finally {
570
            if (isTransactionActive(em)){
571
                rollbackTransaction(em);
572
            }
573
            closeEntityManager(em);
521
        }
574
        }
522
523
        assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
524
    }
575
    }
525
576
526
    @Test
577
    @Test
527
    public void managerFetchGroupWithJoinFetch() throws Exception {
578
    public void managerFetchGroupWithJoinFetch() throws Exception {
528
        EntityManager em = createEntityManager("fieldaccess");
579
        EntityManager em = createEntityManager("fieldaccess");
580
        try {
581
            beginTransaction(em);
529
582
530
//        int minId = minimumEmployeeId(em);
583
            //int minId = minimumEmployeeId(em);
531
//        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
584
            //assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
532
585
533
        // Use q query since find will only use default fetch group
586
            // Use q query since find will only use default fetch group
534
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
587
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
535
//        query.setParameter("ID", minId);
588
            //query.setParameter("ID", minId);
536
589
537
        // Complex where clause used to avoid triggering employees and their departments:
590
            // Complex where clause used to avoid triggering employees and their departments:
538
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
591
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
539
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
592
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
540
        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");
593
            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");
541
        FetchGroup managerFG = new FetchGroup();
594
            FetchGroup managerFG = new FetchGroup();
542
        managerFG.addAttribute("manager");
595
            managerFG.addAttribute("manager");
543
596
544
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
597
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
545
        query.setHint(QueryHints.LEFT_FETCH, "e.manager");
598
            query.setHint(QueryHints.LEFT_FETCH, "e.manager");
546
599
547
        assertNotNull(getFetchGroup(query));
600
            assertNotNull(getFetchGroup(query));
548
        assertSame(managerFG, getFetchGroup(query));
601
            assertSame(managerFG, getFetchGroup(query));
549
602
550
        Employee emp = (Employee) query.getSingleResult();
603
            Employee emp = (Employee) query.getSingleResult();
551
604
552
        assertFetched(emp, managerFG);
605
            assertFetched(emp, managerFG);
553
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
606
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
554
        
607
            
555
        // manager (if not null) is instantiated by the fetch group, before emp.getManager call.
608
            // manager (if not null) is instantiated by the fetch group, before emp.getManager call.
556
        emp.getManager();
609
            emp.getManager();
557
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
610
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
558
        
611
            
559
        // instantiates the whole object
612
            // instantiates the whole object
560
        emp.getLastName();
613
            emp.getLastName();
561
614
562
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
615
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
563
        assertNoFetchGroup(emp);
616
            assertNoFetchGroup(emp);
564
617
565
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
618
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
566
            assertNoFetchGroup(phone);
619
                assertNoFetchGroup(phone);
567
            phone.getAreaCode();
620
                phone.getAreaCode();
621
            }
622
623
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
624
        } finally {
625
            if (isTransactionActive(em)){
626
                rollbackTransaction(em);
627
            }
628
            closeEntityManager(em);
568
        }
629
        }
569
570
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
571
    }
630
    }
572
631
573
    @Test
632
    @Test
574
    public void employeeNamesFetchGroup() throws Exception {
633
    public void employeeNamesFetchGroup() throws Exception {
575
        EntityManager em = createEntityManager("fieldaccess");
634
        EntityManager em = createEntityManager("fieldaccess");
635
        try {
636
            beginTransaction(em);
576
637
577
        int minId = minimumEmployeeId(em);
638
            int minId = minimumEmployeeId(em);
578
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
639
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
579
640
580
        // Use q query since find will only use default fetch group
641
            // Use q query since find will only use default fetch group
581
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
642
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
582
        query.setParameter("ID", minId);
643
            query.setParameter("ID", minId);
583
        FetchGroup namesFG = new FetchGroup();
644
            FetchGroup namesFG = new FetchGroup();
584
        namesFG.addAttribute("firstName");
645
            namesFG.addAttribute("firstName");
585
        namesFG.addAttribute("lastName");
646
            namesFG.addAttribute("lastName");
586
647
587
        query.setHint(QueryHints.FETCH_GROUP, namesFG);
648
            query.setHint(QueryHints.FETCH_GROUP, namesFG);
588
649
589
        assertNotNull(getFetchGroup(query));
650
            assertNotNull(getFetchGroup(query));
590
        assertSame(namesFG, getFetchGroup(query));
651
            assertSame(namesFG, getFetchGroup(query));
591
652
592
        Employee emp = (Employee) query.getSingleResult();
653
            Employee emp = (Employee) query.getSingleResult();
593
654
594
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
655
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
595
        assertFetched(emp, namesFG);
656
            assertFetched(emp, namesFG);
596
657
597
        emp.getId();
658
            emp.getId();
598
        emp.getFirstName();
659
            emp.getFirstName();
599
        emp.getLastName();
660
            emp.getLastName();
600
        emp.getVersion();
661
            emp.getVersion();
601
662
602
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
663
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
603
        assertFetched(emp, namesFG);
664
            assertFetched(emp, namesFG);
604
665
605
        emp.getGender();
666
            emp.getGender();
606
        emp.getSalary();
667
            emp.getSalary();
607
668
608
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
669
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
609
        assertNoFetchGroup(emp);
670
            assertNoFetchGroup(emp);
610
671
611
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
672
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
612
            assertNoFetchGroup(phone);
673
                assertNoFetchGroup(phone);
613
            phone.getAreaCode();
674
                phone.getAreaCode();
614
        }
675
            }
615
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
676
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
616
677
617
        if (emp.getManager() != null) {
678
            if (emp.getManager() != null) {
618
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
679
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
619
            assertNoFetchGroup(emp.getManager());
680
                assertNoFetchGroup(emp.getManager());
620
        } else {
681
            } else {
621
            // If manager_id field is null then getManager() does not trigger an sql.
682
                // If manager_id field is null then getManager() does not trigger an sql.
622
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
683
                assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
684
            }
685
        } finally {
686
            if (isTransactionActive(em)){
687
                rollbackTransaction(em);
688
            }
689
            closeEntityManager(em);
623
        }
690
        }
624
    }
691
    }
625
692
Lines 658-686 Link Here
658
    @Test
725
    @Test
659
    public void verifyUnfetchedAttributes() throws Exception {
726
    public void verifyUnfetchedAttributes() throws Exception {
660
        EntityManager em = createEntityManager("fieldaccess");
727
        EntityManager em = createEntityManager("fieldaccess");
728
        try {
729
            beginTransaction(em);
730
            TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.owner.id) FROM PhoneNumber p)", Employee.class);
731
            FetchGroup fg = new FetchGroup("Employee.empty");
732
            q.setHint(QueryHints.FETCH_GROUP, fg);
733
            Employee emp = q.getSingleResult();
661
734
662
        TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.owner.id) FROM PhoneNumber p)", Employee.class);
735
            assertNotNull(emp);
663
        FetchGroup fg = new FetchGroup("Employee.empty");
736
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
664
        q.setHint(QueryHints.FETCH_GROUP, fg);
665
        Employee emp = q.getSingleResult();
666
737
667
        assertNotNull(emp);
738
            // This check using the mapping returns a default (empty) IndirectList
668
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
739
            /*OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers");
740
            IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp);
741
            assertNotNull(phones);
742
            assertTrue(phones.isInstantiated());
743
            assertEquals(0, phones.size());
744
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/
669
745
670
        // This check using the mapping returns a default (empty) IndirectList
746
            IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers();
671
/*        OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers");
747
            assertFalse(phonesIL.isInstantiated());
672
        IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp);
748
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
673
        assertNotNull(phones);
674
        assertTrue(phones.isInstantiated());
675
        assertEquals(0, phones.size());
676
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/
677
749
678
        IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers();
750
            assertTrue(emp.getPhoneNumbers().size() > 0);
679
        assertFalse(phonesIL.isInstantiated());
751
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
680
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
752
        } finally {
681
753
            if (isTransactionActive(em)){
682
        assertTrue(emp.getPhoneNumbers().size() > 0);
754
                rollbackTransaction(em);
683
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
755
            }
756
            closeEntityManager(em);
757
        }
684
    }
758
    }
685
759
686
    @Test
760
    @Test
Lines 725-744 Link Here
725
    @Test
799
    @Test
726
    public void explicitlyDetachedObjectWithFetchGroup() {
800
    public void explicitlyDetachedObjectWithFetchGroup() {
727
        EntityManager em = createEntityManager("fieldaccess");
801
        EntityManager em = createEntityManager("fieldaccess");
802
        try {
803
            beginTransaction(em);
804
            FetchGroup fg = new FetchGroup();
805
            fg.addAttribute("firstName");
806
            fg.addAttribute("lastName");
728
807
729
        FetchGroup fg = new FetchGroup();
808
            Map<String, Object> hints = new HashMap<String, Object>();
730
        fg.addAttribute("firstName");
809
            hints.put(QueryHints.FETCH_GROUP, fg);
731
        fg.addAttribute("lastName");
732
810
733
        Map<String, Object> hints = new HashMap<String, Object>();
811
            Employee emp = minimumEmployee(em, hints);
734
        hints.put(QueryHints.FETCH_GROUP, fg);
812
            em.detach(emp);
735
813
            assertFetched(emp, fg);
736
        Employee emp = minimumEmployee(em, hints);
814
            
737
        em.detach(emp);
815
            // trigger the fetch group
738
        assertFetched(emp, fg);
816
            emp.getSalary();
739
        
817
            assertNoFetchGroup(emp);
740
        // trigger the fetch group
818
        } finally {
741
        emp.getSalary();
819
            if (isTransactionActive(em)){
742
        assertNoFetchGroup(emp);
820
                rollbackTransaction(em);
821
            }
822
            closeEntityManager(em);
823
        }
743
    }
824
    }
744
}
825
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleNamedFetchGroupTests.java (-32 / +39 lines)
Lines 269-316 Link Here
269
    @Test
269
    @Test
270
    public void managerFetchGroup() throws Exception {
270
    public void managerFetchGroup() throws Exception {
271
        EntityManager em = createEntityManager("fieldaccess");
271
        EntityManager em = createEntityManager("fieldaccess");
272
        try {
273
            beginTransaction(em);
274
            // Use q query since find will only use default fetch group
275
            // Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
276
            // query.setParameter("ID", minimumEmployeeId(em));
272
277
273
        // Use q query since find will only use default fetch group
278
            // Complex where clause used to avoid triggering employees and their departments:
274
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
279
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
275
//        query.setParameter("ID", minimumEmployeeId(em));
280
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
281
            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");
282
            FetchGroup managerFG = new FetchGroup();
283
            managerFG.addAttribute("manager");
276
284
277
        // Complex where clause used to avoid triggering employees and their departments:
285
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
278
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
279
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
280
        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");
281
        FetchGroup managerFG = new FetchGroup();
282
        managerFG.addAttribute("manager");
283
286
284
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
287
            assertNotNull(getFetchGroup(query));
288
            assertSame(managerFG, getFetchGroup(query));
285
289
286
        assertNotNull(getFetchGroup(query));
290
            Employee emp = (Employee) query.getSingleResult();
287
        assertSame(managerFG, getFetchGroup(query));
288
291
289
        Employee emp = (Employee) query.getSingleResult();
292
            assertFetched(emp, managerFG);
293
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
294
            
295
            int nSqlToAdd = 0;
296
            if (emp.getManager() != null) {
297
                assertFetchedAttribute(emp, "manager");
298
                // additional sql to select the manager
299
                nSqlToAdd++;
300
            }
301
            
302
            assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
290
303
291
        assertFetched(emp, managerFG);
304
            // instantiates the whole object
292
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
305
            emp.getLastName();
293
        
294
        int nSqlToAdd = 0;
295
        if (emp.getManager() != null) {
296
            assertFetchedAttribute(emp, "manager");
297
            // additional sql to select the manager
298
            nSqlToAdd++;
299
        }
300
        
301
        assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
302
306
303
        // instantiates the whole object
307
            assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
304
        emp.getLastName();
308
            assertNoFetchGroup(emp);
305
309
306
        assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
310
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
307
        assertNoFetchGroup(emp);
311
                assertNoFetchGroup(phone);
312
            }
308
313
309
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
314
            assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
310
            assertNoFetchGroup(phone);
315
        } finally {
316
            if (isTransactionActive(em)){
317
                rollbackTransaction(em);
318
            }
319
            closeEntityManager(em);
311
        }
320
        }
312
313
        assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
314
    }
321
    }
315
322
316
    @Test
323
    @Test
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/fieldaccess/fetchgroups/SimpleSerializeFetchGroupTests.java (-543 / +638 lines)
Lines 12-17 Link Here
12
 ******************************************************************************/
12
 ******************************************************************************/
13
package org.eclipse.persistence.testing.tests.jpa.fieldaccess.fetchgroups;
13
package org.eclipse.persistence.testing.tests.jpa.fieldaccess.fetchgroups;
14
14
15
import java.io.ByteArrayInputStream;
16
import java.io.ObjectInputStream;
17
import java.io.ObjectOutputStream;
15
import java.io.IOException;
18
import java.io.IOException;
16
import java.io.Serializable;
19
import java.io.Serializable;
17
import java.util.ArrayList;
20
import java.util.ArrayList;
Lines 65-72 Link Here
65
        
68
        
66
        suite.addTest(new SimpleSerializeFetchGroupTests("testSetup"));
69
        suite.addTest(new SimpleSerializeFetchGroupTests("testSetup"));
67
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyWriteReplaceOnFetchGroup"));
70
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyWriteReplaceOnFetchGroup"));
68
        suite.addTest(new SimpleSerializeFetchGroupTests("findMinimalFetchGroup"));
69
        suite.addTest(new SimpleSerializeFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary"));
70
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyAddAttributeInDetachedEntityFetchGroup"));
71
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyAddAttributeInDetachedEntityFetchGroup"));
71
        suite.addTest(new SimpleSerializeFetchGroupTests("singleResultEmptyFetchGroup"));
72
        suite.addTest(new SimpleSerializeFetchGroupTests("singleResultEmptyFetchGroup"));
72
        suite.addTest(new SimpleSerializeFetchGroupTests("resultListEmptyFetchGroup"));
73
        suite.addTest(new SimpleSerializeFetchGroupTests("resultListEmptyFetchGroup"));
Lines 76-94 Link Here
76
        suite.addTest(new SimpleSerializeFetchGroupTests("employeeNamesFetchGroup"));
77
        suite.addTest(new SimpleSerializeFetchGroupTests("employeeNamesFetchGroup"));
77
        suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
78
        suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
78
        suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
79
        suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
79
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyUnfetchedAttributes"));
80
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyFetchedRelationshipAttributes"));
80
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyFetchedRelationshipAttributes"));
81
        suite.addTest(new SimpleSerializeFetchGroupTests("simpleSerializeAndMerge"));
81
        if (!isJPA10()) {
82
        suite.addTest(new SimpleSerializeFetchGroupTests("partialMerge"));
82
            suite.addTest(new SimpleSerializeFetchGroupTests("findMinimalFetchGroup"));
83
        suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge"));
83
            suite.addTest(new SimpleSerializeFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary"));
84
        suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge2"));
84
            suite.addTest(new SimpleSerializeFetchGroupTests("verifyUnfetchedAttributes"));
85
        suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPk"));
85
            suite.addTest(new SimpleSerializeFetchGroupTests("simpleSerializeAndMerge"));
86
        suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPkUseFullGroup"));
86
            suite.addTest(new SimpleSerializeFetchGroupTests("partialMerge"));
87
        suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPk"));
87
            suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge"));
88
        suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPkUseFullGroup"));
88
            suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge2"));
89
        suite.addTest(new SimpleSerializeFetchGroupTests("copyNoCascade"));
89
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPk"));
90
        suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadePrivateParts"));
90
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPkUseFullGroup"));
91
        suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadeAllParts"));
91
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPk"));
92
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPkUseFullGroup"));
93
            suite.addTest(new SimpleSerializeFetchGroupTests("copyNoCascade"));
94
            suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadePrivateParts"));
95
            suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadeAllParts"));
96
        }
92
        
97
        
93
        return suite;
98
        return suite;
94
    }
99
    }
Lines 96-105 Link Here
96
    @Test
101
    @Test
97
    public void verifyWriteReplaceOnFetchGroup() throws Exception {
102
    public void verifyWriteReplaceOnFetchGroup() throws Exception {
98
        EntityFetchGroup fg = new EntityFetchGroup(new String[]{"basic", "a"});
103
        EntityFetchGroup fg = new EntityFetchGroup(new String[]{"basic", "a"});
99
//        fg.addAttribute("basic");
104
        //fg.addAttribute("basic");
100
//        fg.addAttribute("a.b");
105
        //fg.addAttribute("a.b");
101
106
102
//        assertTrue(fg.getClass() == FetchGroup.class);
107
        //assertTrue(fg.getClass() == FetchGroup.class);
103
108
104
        FetchGroup serFG = serialize(fg);
109
        FetchGroup serFG = serialize(fg);
105
110
Lines 110-124 Link Here
110
        AttributeItem basicFI = serFG.getItem("basic");
115
        AttributeItem basicFI = serFG.getItem("basic");
111
116
112
        assertNotNull(basicFI);
117
        assertNotNull(basicFI);
113
//        assertTrue(basicFI instanceof DetachedFetchItem);
118
        //assertTrue(basicFI instanceof DetachedFetchItem);
114
119
115
        AttributeItem aFI = serFG.getItem("a");
120
        AttributeItem aFI = serFG.getItem("a");
116
121
117
        assertNotNull(aFI);
122
        assertNotNull(aFI);
118
//        assertTrue(aFI instanceof DetachedFetchItem);
123
        //assertTrue(aFI instanceof DetachedFetchItem);
119
        // serialized EntityFetchGroup is always flat - doesn't have nested groups.
124
        // serialized EntityFetchGroup is always flat - doesn't have nested groups.
120
        assertNull(aFI.getGroup());
125
        assertNull(aFI.getGroup());
121
/*        assertNotNull(aFI.getGroup());
126
        /*assertNotNull(aFI.getGroup());
122
        assertTrue(aFI.getGroup() instanceof EntityFetchGroup);
127
        assertTrue(aFI.getGroup() instanceof EntityFetchGroup);
123
        EntityFetchGroup aEFG = (EntityFetchGroup) aFI.getGroup();
128
        EntityFetchGroup aEFG = (EntityFetchGroup) aFI.getGroup();
124
        assertNull(aEFG.getParent());
129
        assertNull(aEFG.getParent());
Lines 127-133 Link Here
127
        AttributeItem bFI = aEFG.getItem("b");
132
        AttributeItem bFI = aEFG.getItem("b");
128
133
129
        assertNotNull(bFI);
134
        assertNotNull(bFI);
130
//        assertTrue(bFI instanceof DetachedFetchItem);
135
        //assertTrue(bFI instanceof DetachedFetchItem);
131
        assertNull(bFI.getGroup());*/
136
        assertNull(bFI.getGroup());*/
132
    }
137
    }
133
138
Lines 194-250 Link Here
194
    public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception {
199
    public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception {
195
        EntityManager em = createEntityManager("fieldaccess");
200
        EntityManager em = createEntityManager("fieldaccess");
196
        int minId = minimumEmployeeId(em);
201
        int minId = minimumEmployeeId(em);
202
        try {
203
            beginTransaction(em);
197
204
198
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
205
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
199
206
200
        Map<String, Object> properties = new HashMap<String, Object>();
207
            Map<String, Object> properties = new HashMap<String, Object>();
201
        FetchGroup emptyFG = new FetchGroup();
208
            FetchGroup emptyFG = new FetchGroup();
202
        properties.put(QueryHints.FETCH_GROUP, emptyFG);
209
            properties.put(QueryHints.FETCH_GROUP, emptyFG);
203
210
204
        Employee emp = em.find(Employee.class, minId, properties);
211
            Employee emp = em.find(Employee.class, minId, properties);
205
212
206
        assertNotNull(emp);
213
            assertNotNull(emp);
207
        assertFetched(emp, emptyFG);
214
            assertFetched(emp, emptyFG);
208
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
215
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
209
216
210
        // Check Basics
217
            // Check Basics
211
        assertFetchedAttribute(emp, "id");
218
            assertFetchedAttribute(emp, "id");
212
        assertFetchedAttribute(emp, "version");
219
            assertFetchedAttribute(emp, "version");
213
        assertNotFetchedAttribute(emp, "firstName");
220
            assertNotFetchedAttribute(emp, "firstName");
214
        assertNotFetchedAttribute(emp, "lastName");
221
            assertNotFetchedAttribute(emp, "lastName");
215
        assertNotFetchedAttribute(emp, "gender");
222
            assertNotFetchedAttribute(emp, "gender");
216
        assertNotFetchedAttribute(emp, "salary");
223
            assertNotFetchedAttribute(emp, "salary");
217
        assertNotFetchedAttribute(emp, "startTime");
224
            assertNotFetchedAttribute(emp, "startTime");
218
        assertNotFetchedAttribute(emp, "endTime");
225
            assertNotFetchedAttribute(emp, "endTime");
219
        if (emp.getPeriod() != null) {
226
            if (emp.getPeriod() != null) {
220
            assertFetchedAttribute(emp.getPeriod(), "startDate");
227
                assertFetchedAttribute(emp.getPeriod(), "startDate");
221
            assertFetchedAttribute(emp.getPeriod(), "endDate");
228
                assertFetchedAttribute(emp.getPeriod(), "endDate");
222
        }
229
            }
223
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
230
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
224
231
225
        // Check Relationships
232
            // Check Relationships
226
        assertNotFetchedAttribute(emp, "address");
233
            assertNotFetchedAttribute(emp, "address");
227
        assertNotFetchedAttribute(emp, "manager");
234
            assertNotFetchedAttribute(emp, "manager");
228
        assertNotFetchedAttribute(emp, "phoneNumbers");
235
            assertNotFetchedAttribute(emp, "phoneNumbers");
229
        assertNotFetchedAttribute(emp, "projects");
236
            assertNotFetchedAttribute(emp, "projects");
230
237
231
        emp.setSalary(1);
238
            emp.setSalary(1);
232
239
233
        assertFetchedAttribute(emp, "salary");
240
            assertFetchedAttribute(emp, "salary");
234
241
235
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
242
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
236
        assertNoFetchGroup(emp);
243
            assertNoFetchGroup(emp);
237
244
238
        emp.getAddress();
245
            emp.getAddress();
239
246
240
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
247
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
241
        assertNoFetchGroup(emp.getAddress());
248
            assertNoFetchGroup(emp.getAddress());
242
249
243
        emp.getPhoneNumbers().size();
250
            emp.getPhoneNumbers().size();
244
251
245
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
252
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
246
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
253
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
247
            assertNoFetchGroup(phone);
254
                assertNoFetchGroup(phone);
255
            }
256
        } finally {
257
            if (isTransactionActive(em)){
258
                rollbackTransaction(em);
259
            }
260
            closeEntityManager(em);
248
        }
261
        }
249
    }
262
    }
250
263
Lines 256-351 Link Here
256
    public void verifyAddAttributeInDetachedEntityFetchGroup() {
269
    public void verifyAddAttributeInDetachedEntityFetchGroup() {
257
        EntityFetchGroup detFG = new EntityFetchGroup(new String[]{"basic", "a"});
270
        EntityFetchGroup detFG = new EntityFetchGroup(new String[]{"basic", "a"});
258
271
259
//        detFG.addAttribute("basic");
272
        //detFG.addAttribute("basic");
260
//        detFG.addAttribute("a.b");
273
        //detFG.addAttribute("a.b");
261
274
262
//        assertNull(detFG.getParent());
275
        //assertNull(detFG.getParent());
263
        assertEquals(2, detFG.getItems().size());
276
        assertEquals(2, detFG.getItems().size());
264
277
265
        AttributeItem basicItem = detFG.getItem("basic");
278
        AttributeItem basicItem = detFG.getItem("basic");
266
        assertNotNull(basicItem);
279
        assertNotNull(basicItem);
267
        assertEquals("basic", basicItem.getAttributeName());
280
        assertEquals("basic", basicItem.getAttributeName());
268
//        assertTrue(basicItem instanceof DetachedFetchItem);
281
        //assertTrue(basicItem instanceof DetachedFetchItem);
269
        assertNull(basicItem.getGroup());
282
        assertNull(basicItem.getGroup());
270
        assertSame(detFG, basicItem.getParent());
283
        assertSame(detFG, basicItem.getParent());
271
//        assertFalse(basicItem.useDefaultFetchGroup());
284
        //assertFalse(basicItem.useDefaultFetchGroup());
272
285
273
        AttributeItem aItem = detFG.getItem("a");
286
        AttributeItem aItem = detFG.getItem("a");
274
        assertNotNull(aItem);
287
        assertNotNull(aItem);
275
        assertEquals("a", aItem.getAttributeName());
288
        assertEquals("a", aItem.getAttributeName());
276
//        assertTrue(aItem instanceof DetachedFetchItem);
289
        //assertTrue(aItem instanceof DetachedFetchItem);
277
        // serialized EntityFetchGroup is always flat - doesn't have nested groups.
290
        // serialized EntityFetchGroup is always flat - doesn't have nested groups.
278
////        assertNull(aItem.getGroup());
291
        //assertNull(aItem.getGroup());
279
        assertNull(aItem.getGroup());
292
        assertNull(aItem.getGroup());
280
        assertSame(detFG, aItem.getParent());
293
        assertSame(detFG, aItem.getParent());
281
//        assertFalse(aItem.useDefaultFetchGroup());
294
        //assertFalse(aItem.useDefaultFetchGroup());
282
//        assertTrue(aItem.getGroup() instanceof EntityFetchGroup);
295
        //assertTrue(aItem.getGroup() instanceof EntityFetchGroup);
283
296
284
//        EntityFetchGroup aFG = (EntityFetchGroup) aItem.getGroup();
297
        //EntityFetchGroup aFG = (EntityFetchGroup) aItem.getGroup();
285
298
286
//        assertEquals(1, aFG.getItems().size());
299
        //assertEquals(1, aFG.getItems().size());
287
300
288
//        AttributeItem bItem = aFG.getItem("b");
301
        //AttributeItem bItem = aFG.getItem("b");
289
//        assertNotNull(bItem);
302
        //assertNotNull(bItem);
290
//        assertEquals("b", bItem.getAttributeName());
303
        //assertEquals("b", bItem.getAttributeName());
291
//        assertTrue(bItem instanceof DetachedFetchItem);
304
        //assertTrue(bItem instanceof DetachedFetchItem);
292
  //      assertNull(bItem.getGroup());
305
        //assertNull(bItem.getGroup());
293
//        assertSame(aFG, bItem.getParent());
306
        //assertSame(aFG, bItem.getParent());
294
//        assertFalse(bItem.useDefaultFetchGroup());
307
        //assertFalse(bItem.useDefaultFetchGroup());
295
    }
308
    }
296
309
297
    @Test
310
    @Test
298
    public void singleResultEmptyFetchGroup() throws Exception {
311
    public void singleResultEmptyFetchGroup() throws Exception {
299
        EntityManager em = createEntityManager("fieldaccess");
312
        EntityManager em = createEntityManager("fieldaccess");
313
        try {
314
            beginTransaction(em);
300
315
301
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
316
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
302
        query.setParameter("ID", minimumEmployeeId(em));
317
            query.setParameter("ID", minimumEmployeeId(em));
303
        FetchGroup emptyFG = new FetchGroup();
318
            FetchGroup emptyFG = new FetchGroup();
304
        query.setHint(QueryHints.FETCH_GROUP, emptyFG);
319
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);
305
320
306
        Employee emp = (Employee) query.getSingleResult();
321
            Employee emp = (Employee) query.getSingleResult();
307
322
308
        assertNotNull(emp);
323
            assertNotNull(emp);
309
        assertFetched(emp, emptyFG);
324
            assertFetched(emp, emptyFG);
310
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
325
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
311
326
312
        // Check Basics
327
            // Check Basics
313
        assertFetchedAttribute(emp, "id");
328
            assertFetchedAttribute(emp, "id");
314
        assertFetchedAttribute(emp, "version");
329
            assertFetchedAttribute(emp, "version");
315
        assertNotFetchedAttribute(emp, "firstName");
330
            assertNotFetchedAttribute(emp, "firstName");
316
        assertNotFetchedAttribute(emp, "lastName");
331
            assertNotFetchedAttribute(emp, "lastName");
317
        assertNotFetchedAttribute(emp, "gender");
332
            assertNotFetchedAttribute(emp, "gender");
318
        assertNotFetchedAttribute(emp, "salary");
333
            assertNotFetchedAttribute(emp, "salary");
319
        assertNotFetchedAttribute(emp, "startTime");
334
            assertNotFetchedAttribute(emp, "startTime");
320
        assertNotFetchedAttribute(emp, "endTime");
335
            assertNotFetchedAttribute(emp, "endTime");
321
        if (emp.getPeriod() != null) {
336
            if (emp.getPeriod() != null) {
322
            assertFetchedAttribute(emp.getPeriod(), "startDate");
337
                assertFetchedAttribute(emp.getPeriod(), "startDate");
323
            assertFetchedAttribute(emp.getPeriod(), "endDate");
338
                assertFetchedAttribute(emp.getPeriod(), "endDate");
324
        }
339
            }
325
340
326
        // Check Relationships
341
            // Check Relationships
327
        assertNotFetchedAttribute(emp, "address");
342
            assertNotFetchedAttribute(emp, "address");
328
        assertNotFetchedAttribute(emp, "manager");
343
            assertNotFetchedAttribute(emp, "manager");
329
        assertNotFetchedAttribute(emp, "phoneNumbers");
344
            assertNotFetchedAttribute(emp, "phoneNumbers");
330
        assertNotFetchedAttribute(emp, "projects");
345
            assertNotFetchedAttribute(emp, "projects");
331
346
332
        emp.getSalary();
347
            emp.getSalary();
333
348
334
        assertFetchedAttribute(emp, "salary");
349
            assertFetchedAttribute(emp, "salary");
335
350
336
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
351
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
337
        assertNoFetchGroup(emp);
352
            assertNoFetchGroup(emp);
338
353
339
        emp.getAddress();
354
            emp.getAddress();
340
355
341
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
356
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
342
        assertNoFetchGroup(emp.getAddress());
357
            assertNoFetchGroup(emp.getAddress());
343
358
344
        emp.getPhoneNumbers().size();
359
            emp.getPhoneNumbers().size();
345
360
346
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
361
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
347
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
362
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
348
            assertNoFetchGroup(phone);
363
                assertNoFetchGroup(phone);
364
            }
365
        } finally {
366
            if (isTransactionActive(em)){
367
                rollbackTransaction(em);
368
            }
369
            closeEntityManager(em);
349
        }
370
        }
350
    }
371
    }
351
372
Lines 355-413 Link Here
355
    @Test
376
    @Test
356
    public void resultListEmptyFetchGroup() throws Exception {
377
    public void resultListEmptyFetchGroup() throws Exception {
357
        EntityManager em = createEntityManager("fieldaccess");
378
        EntityManager em = createEntityManager("fieldaccess");
379
        try {
380
            beginTransaction(em);
358
381
359
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
382
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
360
        query.setParameter("ID", minimumEmployeeId(em));
383
            query.setParameter("ID", minimumEmployeeId(em));
361
        FetchGroup emptyFG = new FetchGroup();
384
            FetchGroup emptyFG = new FetchGroup();
362
        query.setHint(QueryHints.FETCH_GROUP, emptyFG);
385
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);
363
386
364
        List<Employee> emps = query.getResultList();
387
            List<Employee> emps = query.getResultList();
365
388
366
        assertNotNull(emps);
389
            assertNotNull(emps);
367
        assertEquals(1, emps.size());
390
            assertEquals(1, emps.size());
368
391
369
        Employee emp = emps.get(0);
392
            Employee emp = emps.get(0);
370
393
371
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
394
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
372
        assertFetched(emp, emptyFG);
395
            assertFetched(emp, emptyFG);
373
396
374
        // Check Basics
397
            // Check Basics
375
        assertFetchedAttribute(emp, "id");
398
            assertFetchedAttribute(emp, "id");
376
        assertFetchedAttribute(emp, "version");
399
            assertFetchedAttribute(emp, "version");
377
        assertNotFetchedAttribute(emp, "firstName");
400
            assertNotFetchedAttribute(emp, "firstName");
378
        assertNotFetchedAttribute(emp, "lastName");
401
            assertNotFetchedAttribute(emp, "lastName");
379
        assertNotFetchedAttribute(emp, "gender");
402
            assertNotFetchedAttribute(emp, "gender");
380
        assertNotFetchedAttribute(emp, "salary");
403
            assertNotFetchedAttribute(emp, "salary");
381
        assertNotFetchedAttribute(emp, "startTime");
404
            assertNotFetchedAttribute(emp, "startTime");
382
        assertNotFetchedAttribute(emp, "endTime");
405
            assertNotFetchedAttribute(emp, "endTime");
383
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
406
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
384
        if (emp.getPeriod() != null) {
407
            if (emp.getPeriod() != null) {
385
            assertFetchedAttribute(emp.getPeriod(), "startDate");
408
                assertFetchedAttribute(emp.getPeriod(), "startDate");
386
            assertFetchedAttribute(emp.getPeriod(), "endDate");
409
                assertFetchedAttribute(emp.getPeriod(), "endDate");
387
        }
410
            }
388
411
389
        // Check Relationships
412
            // Check Relationships
390
        assertNotFetchedAttribute(emp, "address");
413
            assertNotFetchedAttribute(emp, "address");
391
        assertNotFetchedAttribute(emp, "manager");
414
            assertNotFetchedAttribute(emp, "manager");
392
        assertNotFetchedAttribute(emp, "phoneNumbers");
415
            assertNotFetchedAttribute(emp, "phoneNumbers");
393
        assertNotFetchedAttribute(emp, "projects");
416
            assertNotFetchedAttribute(emp, "projects");
394
417
395
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
418
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
396
419
397
        emp.getSalary();
420
            emp.getSalary();
398
421
399
        assertFetchedAttribute(emp, "salary");
422
            assertFetchedAttribute(emp, "salary");
400
        assertNoFetchGroup(emp);
423
            assertNoFetchGroup(emp);
401
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
424
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
402
425
403
        assertNoFetchGroup(emp.getAddress());
426
            assertNoFetchGroup(emp.getAddress());
404
427
405
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
428
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
406
429
407
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
430
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
408
            assertNoFetchGroup(phone);
431
                assertNoFetchGroup(phone);
432
            }
433
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
434
        } finally {
435
            if (isTransactionActive(em)){
436
                rollbackTransaction(em);
437
            }
438
            closeEntityManager(em);
409
        }
439
        }
410
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
411
    }
440
    }
412
441
413
    /**
442
    /**
Lines 416-624 Link Here
416
    @Test
445
    @Test
417
    public void resultListPeriodFetchGroup() throws Exception {
446
    public void resultListPeriodFetchGroup() throws Exception {
418
        EntityManager em = createEntityManager("fieldaccess");
447
        EntityManager em = createEntityManager("fieldaccess");
448
        try {
449
            beginTransaction(em);
419
450
420
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
451
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
421
        query.setParameter("ID", minimumEmployeeId(em));
452
            query.setParameter("ID", minimumEmployeeId(em));
422
        FetchGroup fg = new FetchGroup();
453
            FetchGroup fg = new FetchGroup();
423
        fg.addAttribute("period");
454
            fg.addAttribute("period");
424
        query.setHint(QueryHints.FETCH_GROUP, fg);
455
            query.setHint(QueryHints.FETCH_GROUP, fg);
425
456
426
        List<Employee> emps = query.getResultList();
457
            List<Employee> emps = query.getResultList();
427
458
428
        assertNotNull(emps);
459
            assertNotNull(emps);
429
        assertEquals(1, emps.size());
460
            assertEquals(1, emps.size());
430
461
431
        Employee emp = emps.get(0);
462
            Employee emp = emps.get(0);
432
463
433
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
464
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
434
        assertFetched(emp, fg);
465
            assertFetched(emp, fg);
435
466
436
        // Check Basics
467
            // Check Basics
437
        assertFetchedAttribute(emp, "id");
468
            assertFetchedAttribute(emp, "id");
438
        assertFetchedAttribute(emp, "version");
469
            assertFetchedAttribute(emp, "version");
439
        assertNotFetchedAttribute(emp, "firstName");
470
            assertNotFetchedAttribute(emp, "firstName");
440
        assertNotFetchedAttribute(emp, "lastName");
471
            assertNotFetchedAttribute(emp, "lastName");
441
        assertNotFetchedAttribute(emp, "gender");
472
            assertNotFetchedAttribute(emp, "gender");
442
        assertNotFetchedAttribute(emp, "salary");
473
            assertNotFetchedAttribute(emp, "salary");
443
        assertNotFetchedAttribute(emp, "startTime");
474
            assertNotFetchedAttribute(emp, "startTime");
444
        assertNotFetchedAttribute(emp, "endTime");
475
            assertNotFetchedAttribute(emp, "endTime");
445
        if (emp.getPeriod() != null) {
476
            if (emp.getPeriod() != null) {
446
            assertFetchedAttribute(emp.getPeriod(), "startDate");
477
                assertFetchedAttribute(emp.getPeriod(), "startDate");
447
            assertFetchedAttribute(emp.getPeriod(), "endDate");
478
                assertFetchedAttribute(emp.getPeriod(), "endDate");
448
        }
479
            }
449
480
450
        // Check Relationships
481
            // Check Relationships
451
        assertNotFetchedAttribute(emp, "address");
482
            assertNotFetchedAttribute(emp, "address");
452
        assertNotFetchedAttribute(emp, "manager");
483
            assertNotFetchedAttribute(emp, "manager");
453
        assertNotFetchedAttribute(emp, "phoneNumbers");
484
            assertNotFetchedAttribute(emp, "phoneNumbers");
454
        assertNotFetchedAttribute(emp, "projects");
485
            assertNotFetchedAttribute(emp, "projects");
455
486
456
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
487
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
457
488
458
        emp.getSalary();
489
            emp.getSalary();
459
490
460
        assertFetchedAttribute(emp, "salary");
491
            assertFetchedAttribute(emp, "salary");
461
        assertNoFetchGroup(emp);
492
            assertNoFetchGroup(emp);
462
493
463
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
494
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
464
495
465
        assertNoFetchGroup(emp.getAddress());
496
            assertNoFetchGroup(emp.getAddress());
466
497
467
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
498
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
468
499
469
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
500
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
470
            assertNoFetchGroup(phone);
501
                assertNoFetchGroup(phone);
502
            }
503
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
504
        } finally {
505
            if (isTransactionActive(em)){
506
                rollbackTransaction(em);
507
            }
508
            closeEntityManager(em);
471
        }
509
        }
472
        assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
473
    }
510
    }
474
511
475
    @Test
512
    @Test
476
    public void managerFetchGroup() throws Exception {
513
    public void managerFetchGroup() throws Exception {
477
        EntityManager em = createEntityManager("fieldaccess");
514
        EntityManager em = createEntityManager("fieldaccess");
515
        try {
516
            beginTransaction(em);
478
517
479
        // Use q query since find will only use default fetch group
518
            // Use q query since find will only use default fetch group
480
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
519
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
481
//        query.setParameter("ID", minimumEmployeeId(em));
520
            //query.setParameter("ID", minimumEmployeeId(em));
482
521
483
        // Complex where clause used to avoid triggering employees and their departments:
522
            // Complex where clause used to avoid triggering employees and their departments:
484
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
523
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
485
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
524
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
486
        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");
525
            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");
487
        
526
            
488
        FetchGroup managerFG = new FetchGroup();
527
            FetchGroup managerFG = new FetchGroup();
489
        managerFG.addAttribute("manager");
528
            managerFG.addAttribute("manager");
490
529
491
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
530
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
492
531
493
        assertNotNull(getFetchGroup(query));
532
            assertNotNull(getFetchGroup(query));
494
        assertSame(managerFG, getFetchGroup(query));
533
            assertSame(managerFG, getFetchGroup(query));
495
534
496
        Employee emp = (Employee) query.getSingleResult();
535
            Employee emp = (Employee) query.getSingleResult();
497
536
498
        assertFetched(emp, managerFG);
537
            assertFetched(emp, managerFG);
499
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
538
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
500
        
539
            
501
        // manager (if not null) hasn't been instantiated yet.
540
            // manager (if not null) hasn't been instantiated yet.
502
        int nSqlToAdd = 0;
541
            int nSqlToAdd = 0;
503
        if (emp.getManager() != null) {
542
            if (emp.getManager() != null) {
504
            assertFetchedAttribute(emp, "manager");
543
                assertFetchedAttribute(emp, "manager");
505
            // additional sql to select the manager
544
                // additional sql to select the manager
506
            nSqlToAdd++;
545
                nSqlToAdd++;
507
        }
546
            }
508
        
547
            
509
        assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
548
            assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
510
549
511
        emp.getLastName();
550
            emp.getLastName();
512
551
513
        assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
552
            assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
514
        assertNoFetchGroup(emp);
553
            assertNoFetchGroup(emp);
515
554
516
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
555
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
517
            assertNoFetchGroup(phone);
556
                assertNoFetchGroup(phone);
518
            phone.getAreaCode();
557
                phone.getAreaCode();
558
            }
559
560
            assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
561
        } finally {
562
            if (isTransactionActive(em)){
563
                rollbackTransaction(em);
564
            }
565
            closeEntityManager(em);
519
        }
566
        }
520
521
        assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
522
    }
567
    }
523
568
524
    @Test
569
    @Test
525
    public void managerFetchGroupWithJoinFetch() throws Exception {
570
    public void managerFetchGroupWithJoinFetch() throws Exception {
526
        EntityManager em = createEntityManager("fieldaccess");
571
        EntityManager em = createEntityManager("fieldaccess");
572
        try {
573
            beginTransaction(em);
527
574
528
//        int minId = minimumEmployeeId(em);
575
            //int minId = minimumEmployeeId(em);
529
//        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
576
            //assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
530
577
531
        // Use q query since find will only use default fetch group
578
            // Use q query since find will only use default fetch group
532
//        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
579
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
533
//        query.setParameter("ID", minId);
580
            //query.setParameter("ID", minId);
534
581
535
        // Complex where clause used to avoid triggering employees and their departments:
582
            // Complex where clause used to avoid triggering employees and their departments:
536
        //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
583
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
537
        //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
584
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
538
        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");
585
            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");
539
586
540
        FetchGroup managerFG = new FetchGroup();
587
            FetchGroup managerFG = new FetchGroup();
541
        managerFG.addAttribute("manager");
588
            managerFG.addAttribute("manager");
542
589
543
        query.setHint(QueryHints.FETCH_GROUP, managerFG);
590
            query.setHint(QueryHints.FETCH_GROUP, managerFG);
544
        query.setHint(QueryHints.LEFT_FETCH, "e.manager");
591
            query.setHint(QueryHints.LEFT_FETCH, "e.manager");
545
592
546
        assertNotNull(getFetchGroup(query));
593
            assertNotNull(getFetchGroup(query));
547
        assertSame(managerFG, getFetchGroup(query));
594
            assertSame(managerFG, getFetchGroup(query));
548
595
549
        Employee emp = (Employee) query.getSingleResult();
596
            Employee emp = (Employee) query.getSingleResult();
550
597
551
        assertFetched(emp, managerFG);
598
            assertFetched(emp, managerFG);
552
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
599
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
553
        
600
            
554
        // manager has been already instantiated by the query.
601
            // manager has been already instantiated by the query.
555
        emp.getManager();
602
            emp.getManager();
556
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
603
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
557
        
604
            
558
        // instantiates the whiole object
605
            // instantiates the whiole object
559
        emp.getLastName();
606
            emp.getLastName();
560
607
561
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
608
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
562
        assertNoFetchGroup(emp);
609
            assertNoFetchGroup(emp);
563
610
564
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
611
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
565
            assertNoFetchGroup(phone);
612
                assertNoFetchGroup(phone);
566
            phone.getAreaCode();
613
                phone.getAreaCode();
614
            }
615
616
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
617
        } finally {
618
            if (isTransactionActive(em)){
619
                rollbackTransaction(em);
620
            }
621
            closeEntityManager(em);
567
        }
622
        }
568
569
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
570
    }
623
    }
571
624
572
    @Test
625
    @Test
573
    public void employeeNamesFetchGroup() throws Exception {
626
    public void employeeNamesFetchGroup() throws Exception {
574
        EntityManager em = createEntityManager("fieldaccess");
627
        EntityManager em = createEntityManager("fieldaccess");
628
        try {
629
            beginTransaction(em);
575
630
576
        int minId = minimumEmployeeId(em);
631
            int minId = minimumEmployeeId(em);
577
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
632
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
578
633
579
        // Use q query since find will only use default fetch group
634
            // Use q query since find will only use default fetch group
580
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
635
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
581
        query.setParameter("ID", minId);
636
            query.setParameter("ID", minId);
582
        FetchGroup namesFG = new FetchGroup();
637
            FetchGroup namesFG = new FetchGroup();
583
        namesFG.addAttribute("firstName");
638
            namesFG.addAttribute("firstName");
584
        namesFG.addAttribute("lastName");
639
            namesFG.addAttribute("lastName");
585
640
586
        query.setHint(QueryHints.FETCH_GROUP, namesFG);
641
            query.setHint(QueryHints.FETCH_GROUP, namesFG);
587
642
588
        assertNotNull(getFetchGroup(query));
643
            assertNotNull(getFetchGroup(query));
589
        assertSame(namesFG, getFetchGroup(query));
644
            assertSame(namesFG, getFetchGroup(query));
590
645
591
        Employee emp = (Employee) query.getSingleResult();
646
            Employee emp = (Employee) query.getSingleResult();
592
647
593
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
648
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
594
        assertFetched(emp, namesFG);
649
            assertFetched(emp, namesFG);
595
650
596
        emp.getId();
651
            emp.getId();
597
        emp.getFirstName();
652
            emp.getFirstName();
598
        emp.getLastName();
653
            emp.getLastName();
599
        emp.getVersion();
654
            emp.getVersion();
600
655
601
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
656
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
602
        assertFetched(emp, namesFG);
657
            assertFetched(emp, namesFG);
603
658
604
        emp.getGender();
659
            emp.getGender();
605
        emp.getSalary();
660
            emp.getSalary();
606
661
607
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
662
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
608
        assertNoFetchGroup(emp);
663
            assertNoFetchGroup(emp);
609
664
610
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
665
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
611
            assertNoFetchGroup(phone);
666
                assertNoFetchGroup(phone);
612
            phone.getAreaCode();
667
                phone.getAreaCode();
613
        }
668
            }
614
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
669
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
615
670
616
        if (emp.getManager() != null) {
671
            if (emp.getManager() != null) {
617
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
672
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
618
            assertNoFetchGroup(emp.getManager());
673
                assertNoFetchGroup(emp.getManager());
619
        } else {
674
            } else {
620
            // If manager_id field is null then getManager() does not trigger an sql.
675
                // If manager_id field is null then getManager() does not trigger an sql.
621
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
676
                assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
677
            }
678
        } finally {
679
            if (isTransactionActive(em)){
680
                rollbackTransaction(em);
681
            }
682
            closeEntityManager(em);
622
        }
683
        }
623
    }
684
    }
624
685
Lines 657-685 Link Here
657
    @Test
718
    @Test
658
    public void verifyUnfetchedAttributes() throws Exception {
719
    public void verifyUnfetchedAttributes() throws Exception {
659
        EntityManager em = createEntityManager("fieldaccess");
720
        EntityManager em = createEntityManager("fieldaccess");
721
        try {
722
            beginTransaction(em);
660
723
661
        TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.owner.id) FROM PhoneNumber p)", Employee.class);
724
            TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.owner.id) FROM PhoneNumber p)", Employee.class);
662
        FetchGroup fg = new FetchGroup("Employee.empty");
725
            FetchGroup fg = new FetchGroup("Employee.empty");
663
        q.setHint(QueryHints.FETCH_GROUP, fg);
726
            q.setHint(QueryHints.FETCH_GROUP, fg);
664
        Employee emp = q.getSingleResult();
727
            Employee emp = q.getSingleResult();
665
728
666
        assertNotNull(emp);
729
            assertNotNull(emp);
667
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
730
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
668
731
669
        // This check using the mapping returns a default (empty) IndirectList
732
            // This check using the mapping returns a default (empty) IndirectList
670
/*        OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers");
733
            /*OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers");
671
        IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp);
734
            IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp);
672
        assertNotNull(phones);
735
            assertNotNull(phones);
673
        assertTrue(phones.isInstantiated());
736
            assertTrue(phones.isInstantiated());
674
        assertEquals(0, phones.size());
737
            assertEquals(0, phones.size());
675
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/
738
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/
676
739
677
        IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers();
740
            IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers();
678
        assertFalse(phonesIL.isInstantiated());
741
            assertFalse(phonesIL.isInstantiated());
679
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
742
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
680
743
681
        assertTrue(emp.getPhoneNumbers().size() > 0);
744
            assertTrue(emp.getPhoneNumbers().size() > 0);
682
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
745
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
746
        } finally {
747
            if (isTransactionActive(em)){
748
                rollbackTransaction(em);
749
            }
750
            closeEntityManager(em);
751
        }
683
    }
752
    }
684
753
685
    @Test
754
    @Test
Lines 805-811 Link Here
805
        em.clear();
874
        em.clear();
806
        HashMap hints = new HashMap(2);
875
        HashMap hints = new HashMap(2);
807
        hints.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
876
        hints.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
808
//        hints.put(QueryHints.FETCH_GROUP, fetchGroup);
877
        //hints.put(QueryHints.FETCH_GROUP, fetchGroup);
809
        Employee empShared = em.find(Employee.class, id, hints);
878
        Employee empShared = em.find(Employee.class, id, hints);
810
        assertEquals("newFirstName", empShared.getFirstName());
879
        assertEquals("newFirstName", empShared.getFirstName());
811
        assertEquals("newLastName", empShared.getLastName());
880
        assertEquals("newLastName", empShared.getLastName());
Lines 853-859 Link Here
853
            closeEntityManager(em);
922
            closeEntityManager(em);
854
        }
923
        }
855
    }
924
    }
856
/*    public void simpleSerializeAndMerge() throws Exception {
925
    /*public void simpleSerializeAndMerge() throws Exception {
857
        EntityManager em = createEntityManager("fieldaccess");
926
        EntityManager em = createEntityManager("fieldaccess");
858
        int id = minimumEmployeeId(em);
927
        int id = minimumEmployeeId(em);
859
        // save the original Employee for clean up
928
        // save the original Employee for clean up
Lines 932-1050 Link Here
932
    public void partialMerge() throws Exception {
1001
    public void partialMerge() throws Exception {
933
        EntityManager em = createEntityManager("fieldaccess");
1002
        EntityManager em = createEntityManager("fieldaccess");
934
        // Search for an Employee with an Address and Phone Numbers 
1003
        // Search for an Employee with an Address and Phone Numbers 
935
        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);
1004
        try {
936
        
1005
            beginTransaction(em);
937
        // Load only its names and phone Numbers
1006
            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);
938
        FetchGroup fetchGroup = new FetchGroup();
1007
            
939
        fetchGroup.addAttribute("firstName");
1008
            // Load only its names and phone Numbers
940
        fetchGroup.addAttribute("lastName");
1009
            FetchGroup fetchGroup = new FetchGroup();
941
        FetchGroup phonesFG = phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
1010
            fetchGroup.addAttribute("firstName");
942
        // that ensures the owner is not instantiated
1011
            fetchGroup.addAttribute("lastName");
943
        phonesFG.addAttribute("owner.id");
1012
            FetchGroup phonesFG = phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
944
        phonesFG.removeAttribute("status");
1013
            // that ensures the owner is not instantiated
945
        phonesFG.setShouldLoad(true);
1014
            phonesFG.addAttribute("owner.id");
946
        fetchGroup.addAttribute("phoneNumbers", phonesFG);
1015
            phonesFG.removeAttribute("status");
947
        
1016
            phonesFG.setShouldLoad(true);
948
        // Make sure the FetchGroup also forces the relationships to be loaded
1017
            fetchGroup.addAttribute("phoneNumbers", phonesFG);
949
        fetchGroup.setShouldLoad(true);
1018
            
950
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
1019
            // Make sure the FetchGroup also forces the relationships to be loaded
951
        
1020
            fetchGroup.setShouldLoad(true);
952
        Employee emp = query.getSingleResult();
1021
            query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
953
        
1022
            
954
        // Detach Employee through Serialization
1023
            Employee emp = query.getSingleResult();
955
        Employee detachedEmp = (Employee) SerializationHelper.clone(emp);
1024
956
        // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
1025
            // Detach Employee through Serialization 
957
        detachedEmp.setFirstName(emp.getLastName());
1026
            Employee detachedEmp = (Employee)clone(emp);
958
        detachedEmp.setLastName(emp.getFirstName());
1027
959
        detachedEmp.addPhoneNumber(new PhoneNumber("TEST", "999", "999999"));
1028
            // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
960
        // NOte that salary was not part of the original FetchGroupdetachedEmp.setSalary(1);
1029
            detachedEmp.setFirstName(emp.getLastName());
961
        detachedEmp.setSalary(1);
1030
            detachedEmp.setLastName(emp.getFirstName());
962
        
1031
            detachedEmp.addPhoneNumber(new PhoneNumber("TEST", "999", "999999"));
963
        beginTransaction(em);
1032
            // NOte that salary was not part of the original FetchGroupdetachedEmp.setSalary(1);
964
        // Merge the detached employee
1033
            detachedEmp.setSalary(1);
965
        em.merge(detachedEmp);
1034
            
966
        // Flush the changes to the database
1035
            // Merge the detached employee
967
        em.flush();
1036
            em.merge(detachedEmp);
968
        rollbackTransaction(em);
1037
            // Flush the changes to the database
1038
            em.flush();
1039
        } finally {
1040
            rollbackTransaction(em);
1041
            closeEntityManager(em);
1042
        }
969
    }
1043
    }
970
1044
971
    public void copyGroupMerge() {
1045
    public void copyGroupMerge() {
972
        // Search for an Employee with an Address and Phone Numbers
1046
        // Search for an Employee with an Address and Phone Numbers
973
        EntityManager em = createEntityManager("fieldaccess");
1047
        EntityManager em = createEntityManager("fieldaccess");
974
        TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(ee.id) FROM Employee ee)", Employee.class);
1048
        try {
975
        Employee emp = query.getSingleResult();
1049
            beginTransaction(em);
976
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1050
            TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(ee.id) FROM Employee ee)", Employee.class);
977
        System.out.println(">>> Employee retrieved");
1051
            Employee emp = query.getSingleResult();
978
        
1052
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
979
        // Copy only its names and phone Numbers
1053
            System.out.println(">>> Employee retrieved");
980
        AttributeGroup group = new CopyGroup();
1054
            
981
        group.addAttribute("firstName");
1055
            // Copy only its names and phone Numbers
982
        group.addAttribute("lastName");
1056
            AttributeGroup group = new CopyGroup();
983
        group.addAttribute("address");
1057
            group.addAttribute("firstName");
984
        
1058
            group.addAttribute("lastName");
985
        Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);
1059
            group.addAttribute("address");
986
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1060
            
987
        System.out.println(">>> Employee copied");
1061
            Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);
988
        
1062
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
989
        // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
1063
            System.out.println(">>> Employee copied");
990
        empCopy.setFirstName(emp.getLastName());
1064
            
991
        empCopy.setLastName(emp.getFirstName());
1065
            // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
992
        
1066
            empCopy.setFirstName(emp.getLastName());
993
        // Note that salary was not part of the original FetchGroup
1067
            empCopy.setLastName(emp.getFirstName());
994
        //empCopy.setSalary(1);
1068
            
995
        
1069
            // Note that salary was not part of the original FetchGroup
996
        beginTransaction(em);
1070
            //empCopy.setSalary(1);
997
        // Merge the detached employee
1071
            
998
        em.merge(empCopy);
1072
            // Merge the detached employee
999
        System.out.println(">>> Sparse merge complete");
1073
            em.merge(empCopy);
1000
        
1074
            System.out.println(">>> Sparse merge complete");
1001
        // Flush the changes to the database
1075
            
1002
        em.flush();
1076
            // Flush the changes to the database
1003
        System.out.println(">>> Flush complete");
1077
            em.flush();
1004
        
1078
            System.out.println(">>> Flush complete");
1005
        rollbackTransaction(em);
1079
        } finally {
1080
            rollbackTransaction(em);
1081
            closeEntityManager(em);
1082
        }
1006
    }
1083
    }
1007
    
1084
    
1008
    public void copyGroupMerge2() {
1085
    public void copyGroupMerge2() {
1009
        // Search for an Employee with an Address and Phone Numbers
1086
        // Search for an Employee with an Address and Phone Numbers
1010
        EntityManager em = createEntityManager("fieldaccess");
1087
        EntityManager em = createEntityManager("fieldaccess");
1011
        TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e", Employee.class);
1088
        try {
1012
        query.setHint(QueryHints.BATCH, "e.address");
1089
            beginTransaction(em);
1013
        List<Employee> employees = query.getResultList();
1090
            TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e", Employee.class);
1014
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1091
            query.setHint(QueryHints.BATCH, "e.address");
1015
        System.out.println(">>> Employees retrieved");
1092
            List<Employee> employees = query.getResultList();
1016
        
1093
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1017
        // Copy only its names and phone Numbers
1094
            System.out.println(">>> Employees retrieved");
1018
        AttributeGroup group = new CopyGroup();
1019
        group.addAttribute("firstName");
1020
        group.addAttribute("lastName");
1021
        group.addAttribute("address");
1022
        
1023
        List<Employee> employeesCopy = (List<Employee>) em.unwrap(JpaEntityManager.class).copy(employees, group);
1024
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1025
        System.out.println(">>> Employees copied");
1026
        
1027
        beginTransaction(em);
1028
        for(Employee empCopy : employeesCopy) {
1029
            // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
1030
            String firstName = empCopy.getFirstName();
1031
            String lastName = empCopy.getLastName();
1032
            empCopy.setFirstName(lastName);
1033
            empCopy.setLastName(firstName);
1034
    
1035
            // Note that salary was not part of the original FetchGroup
1036
            //empCopy.setSalary(1);        
1037
            
1095
            
1038
            // Merge the detached employee
1096
            // Copy only its names and phone Numbers
1039
            em.merge(empCopy);
1097
            AttributeGroup group = new CopyGroup();
1098
            group.addAttribute("firstName");
1099
            group.addAttribute("lastName");
1100
            group.addAttribute("address");
1101
            
1102
            List<Employee> employeesCopy = (List<Employee>) em.unwrap(JpaEntityManager.class).copy(employees, group);
1103
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
1104
            System.out.println(">>> Employees copied");
1105
            
1106
            for(Employee empCopy : employeesCopy) {
1107
                // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
1108
                String firstName = empCopy.getFirstName();
1109
                String lastName = empCopy.getLastName();
1110
                empCopy.setFirstName(lastName);
1111
                empCopy.setLastName(firstName);
1112
            
1113
                // Note that salary was not part of the original FetchGroup
1114
                //empCopy.setSalary(1);        
1115
                
1116
                // Merge the detached employee
1117
                em.merge(empCopy);
1118
            }
1119
            System.out.println(">>> Sparse merge complete");
1120
            
1121
            // Flush the changes to the database
1122
            em.flush();
1123
            System.out.println(">>> Flush complete");
1124
            
1125
        } finally {
1126
            rollbackTransaction(em);
1127
            closeEntityManager(em);
1040
        }
1128
        }
1041
        System.out.println(">>> Sparse merge complete");
1042
        
1043
        // Flush the changes to the database
1044
        em.flush();
1045
        System.out.println(">>> Flush complete");
1046
        
1047
        rollbackTransaction(em);
1048
    }
1129
    }
1049
    
1130
    
1050
    @Test
1131
    @Test
Lines 1137-1147 Link Here
1137
        }
1218
        }
1138
        
1219
        
1139
        EntityManager em = createEntityManager("fieldaccess");
1220
        EntityManager em = createEntityManager("fieldaccess");
1140
        Employee emp = minimumEmployee(em);        
1141
        Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);
1142
        
1143
        beginTransaction(em);
1144
        try {
1221
        try {
1222
            beginTransaction(em);
1223
            Employee emp = minimumEmployee(em);
1224
            Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);
1225
            
1145
            if(noPk) {
1226
            if(noPk) {
1146
                assertNoFetchGroup(empCopy);
1227
                assertNoFetchGroup(empCopy);
1147
                assertNoFetchGroup(empCopy.getAddress());
1228
                assertNoFetchGroup(empCopy.getAddress());
Lines 1232-1385 Link Here
1232
    
1313
    
1233
    void copyCascade(int cascadeDepth) {
1314
    void copyCascade(int cascadeDepth) {
1234
        EntityManager em = createEntityManager("fieldaccess");
1315
        EntityManager em = createEntityManager("fieldaccess");
1235
        Query query = em.createQuery("SELECT e FROM Employee e");
1316
        try {
1236
        List<Employee> employees = query.getResultList();
1317
            beginTransaction(em);
1318
            Query query = em.createQuery("SELECT e FROM Employee e");
1319
            List<Employee> employees = query.getResultList();
1237
1320
1238
        CopyGroup group = new CopyGroup();
1321
            CopyGroup group = new CopyGroup();
1239
        if(cascadeDepth == CopyGroup.NO_CASCADE) {
1322
            if(cascadeDepth == CopyGroup.NO_CASCADE) {
1240
            group.dontCascade();
1323
                group.dontCascade();
1241
        } else if(cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1324
            } else if(cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1242
            // default cascade depth setting
1325
                // default cascade depth setting
1243
            group.cascadePrivateParts();
1326
                group.cascadePrivateParts();
1244
        } else if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) {
1327
            } else if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) {
1245
            group.cascadeAllParts();
1328
                group.cascadeAllParts();
1246
        } else {
1329
            } else {
1247
            fail("Invalid cascadeDepth = " + cascadeDepth);
1330
                fail("Invalid cascadeDepth = " + cascadeDepth);
1248
        }
1249
        group.setShouldResetPrimaryKey(true);
1250
        
1251
        List<Employee> employeesCopy;
1252
        if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1253
            // In this case the objects should be copied one by one - each one using a new CopyGroup.
1254
            // That ensures most referenced object are original ones (not copies) -
1255
            // the only exception is privately owned objects in CASCADE_PRIVATE_PARTS case.
1256
            employeesCopy = new ArrayList(employees.size());
1257
            for(Employee emp : employees) {
1258
                CopyGroup groupClone = group.clone();
1259
                employeesCopy.add((Employee)em.unwrap(JpaEntityManager.class).copy(emp, groupClone));
1260
            }
1331
            }
1261
        } else {
1332
            group.setShouldResetPrimaryKey(true);
1262
            // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1333
            
1263
            // In this case all objects should be copied using a single CopyGroup.
1334
            List<Employee> employeesCopy;
1264
            // That ensures identities of the copies:
1335
            if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1265
            // for instance if several employees referenced the same project,
1336
                // In this case the objects should be copied one by one - each one using a new CopyGroup.
1266
            // then all copies of these employees will reference the single copy of the project. 
1337
                // That ensures most referenced object are original ones (not copies) -
1267
            employeesCopy = (List)em.unwrap(JpaEntityManager.class).copy(employees, group);
1338
                // the only exception is privately owned objects in CASCADE_PRIVATE_PARTS case.
1268
        }
1339
                employeesCopy = new ArrayList(employees.size());
1269
        
1340
                for(Employee emp : employees) {
1270
        // IdentityHashSets will be used to verify copy identities
1341
                    CopyGroup groupClone = group.clone();
1271
        IdentityHashSet originalEmployees = new IdentityHashSet();
1342
                    employeesCopy.add((Employee)em.unwrap(JpaEntityManager.class).copy(emp, groupClone));
1272
        IdentityHashSet copyEmployees = new IdentityHashSet();
1343
                }
1273
        IdentityHashSet originalAddresses = new IdentityHashSet();
1274
        IdentityHashSet copyAddresses = new IdentityHashSet();
1275
        IdentityHashSet originalProjects = new IdentityHashSet();
1276
        IdentityHashSet copyProjects = new IdentityHashSet();
1277
        IdentityHashSet originalPhones = new IdentityHashSet();
1278
        IdentityHashSet copyPhones = new IdentityHashSet();
1279
        
1280
        int size = employees.size();
1281
        for(int i=0; i < size; i++) {
1282
            Employee emp = employees.get(i);
1283
            Employee empCopy = employeesCopy.get(i);
1284
            if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) {
1285
                originalEmployees.add(emp);
1286
                copyEmployees.add(empCopy);
1287
            } else {
1344
            } else {
1288
                // cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS
1345
                // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1289
                // In this case all Employees referenced by empCopyes are originals (manager and managed employees).
1346
                // In this case all objects should be copied using a single CopyGroup.
1290
                // Therefore if we add here each emp and empCopy to originalEmployees and copyEmployees respectively
1347
                // That ensures identities of the copies:
1291
                // then copyEmployees will always contain all original managers and managed + plus all copies.
1348
                // for instance if several employees referenced the same project,
1292
                // Therefore in this case originalEmployees and copyEmployees will contain only references (managers and managed employees).
1349
                // then all copies of these employees will reference the single copy of the project. 
1350
                employeesCopy = (List)em.unwrap(JpaEntityManager.class).copy(employees, group);
1293
            }
1351
            }
1352
            
1353
            // IdentityHashSets will be used to verify copy identities
1354
            IdentityHashSet originalEmployees = new IdentityHashSet();
1355
            IdentityHashSet copyEmployees = new IdentityHashSet();
1356
            IdentityHashSet originalAddresses = new IdentityHashSet();
1357
            IdentityHashSet copyAddresses = new IdentityHashSet();
1358
            IdentityHashSet originalProjects = new IdentityHashSet();
1359
            IdentityHashSet copyProjects = new IdentityHashSet();
1360
            IdentityHashSet originalPhones = new IdentityHashSet();
1361
            IdentityHashSet copyPhones = new IdentityHashSet();
1362
            
1363
            int size = employees.size();
1364
            for(int i=0; i < size; i++) {
1365
                Employee emp = employees.get(i);
1366
                Employee empCopy = employeesCopy.get(i);
1367
                if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) {
1368
                    originalEmployees.add(emp);
1369
                    copyEmployees.add(empCopy);
1370
                } else {
1371
                    // cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS
1372
                    // In this case all Employees referenced by empCopyes are originals (manager and managed employees).
1373
                    // Therefore if we add here each emp and empCopy to originalEmployees and copyEmployees respectively
1374
                    // then copyEmployees will always contain all original managers and managed + plus all copies.
1375
                    // Therefore in this case originalEmployees and copyEmployees will contain only references (managers and managed employees).
1376
                }
1294
1377
1295
            if(emp.getAddress() == null) {
1378
                if(emp.getAddress() == null) {
1296
                assertTrue("emp.getAddress() == null, but empCopy.getAddress() != null", empCopy.getAddress() == null);
1379
                    assertTrue("emp.getAddress() == null, but empCopy.getAddress() != null", empCopy.getAddress() == null);
1297
            } else {
1298
                originalAddresses.add(emp.getAddress());
1299
                copyAddresses.add(empCopy.getAddress());
1300
                if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1301
                    assertTrue("address has been copied", emp.getAddress() == empCopy.getAddress());
1302
                } else {
1380
                } else {
1303
                    // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1381
                    originalAddresses.add(emp.getAddress());
1304
                    assertFalse("address has not been copied", emp.getAddress() == empCopy.getAddress());
1382
                    copyAddresses.add(empCopy.getAddress());
1383
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1384
                        assertTrue("address has been copied", emp.getAddress() == empCopy.getAddress());
1385
                    } else {
1386
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1387
                        assertFalse("address has not been copied", emp.getAddress() == empCopy.getAddress());
1388
                    }
1305
                }
1389
                }
1306
            }
1307
1390
1308
            boolean same;
1391
                boolean same;
1309
            for(Project project : emp.getProjects()) {
1392
                for(Project project : emp.getProjects()) {
1310
                originalProjects.add(project);
1393
                    originalProjects.add(project);
1311
                same = false;
1394
                    same = false;
1312
                for(Project projectCopy : empCopy.getProjects()) {
1395
                    for(Project projectCopy : empCopy.getProjects()) {
1313
                    copyProjects.add(projectCopy);
1396
                        copyProjects.add(projectCopy);
1314
                    if(!same && project == projectCopy) {
1397
                        if(!same && project == projectCopy) {
1315
                        same = true;
1398
                            same = true;
1399
                        }
1316
                    }
1400
                    }
1401
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1402
                        assertTrue("project has been copied", same);
1403
                    } else {
1404
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1405
                        assertFalse("project has not been copied", same);
1406
                    }
1317
                }
1407
                }
1318
                if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1319
                    assertTrue("project has been copied", same);
1320
                } else {
1321
                    // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1322
                    assertFalse("project has not been copied", same);
1323
                }
1324
            }
1325
            
1408
            
1326
            for(Employee managedEmp : emp.getManagedEmployees()) {
1409
                for(Employee managedEmp : emp.getManagedEmployees()) {
1327
                originalEmployees.add(managedEmp);
1410
                    originalEmployees.add(managedEmp);
1328
                same = false;
1411
                    same = false;
1329
                for(Employee managedEmpCopy : empCopy.getManagedEmployees()) {
1412
                    for(Employee managedEmpCopy : empCopy.getManagedEmployees()) {
1330
                    copyEmployees.add(managedEmpCopy);
1413
                        copyEmployees.add(managedEmpCopy);
1331
                    if(!same && managedEmp == managedEmpCopy) {
1414
                        if(!same && managedEmp == managedEmpCopy) {
1332
                        same = true;
1415
                            same = true;
1416
                        }
1333
                    }
1417
                    }
1418
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1419
                        assertTrue("managedEmployee has been copied", same);
1420
                    } else {
1421
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1422
                        assertFalse("managedEmployee has not been copied", same);
1423
                    }
1334
                }
1424
                }
1335
                if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1425
                
1336
                    assertTrue("managedEmployee has been copied", same);
1426
                if(emp.getManager() == null) {
1427
                    assertTrue("emp.getManager() == null, but empCopy.getManager() != null", empCopy.getManager() == null);
1337
                } else {
1428
                } else {
1338
                    // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1429
                    originalEmployees.add(emp.getManager());
1339
                    assertFalse("managedEmployee has not been copied", same);
1430
                    copyEmployees.add(empCopy.getManager());
1431
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1432
                        assertTrue("manager has been copied", emp.getManager() == empCopy.getManager());
1433
                    } else {
1434
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1435
                        assertFalse("manager has not been copied", emp.getManager() == empCopy.getManager());
1436
                    }
1340
                }
1437
                }
1341
            }
1342
            
1343
            if(emp.getManager() == null) {
1344
                assertTrue("emp.getManager() == null, but empCopy.getManager() != null", empCopy.getManager() == null);
1345
            } else {
1346
                originalEmployees.add(emp.getManager());
1347
                copyEmployees.add(empCopy.getManager());
1348
                if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
1349
                    assertTrue("manager has been copied", emp.getManager() == empCopy.getManager());
1350
                } else {
1351
                    // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
1352
                    assertFalse("manager has not been copied", emp.getManager() == empCopy.getManager());
1353
                }
1354
            }
1355
1438
1356
            // phoneNumbers is privately owned
1439
                // phoneNumbers is privately owned
1357
            for(PhoneNumber phone : emp.getPhoneNumbers()) {
1440
                for(PhoneNumber phone : emp.getPhoneNumbers()) {
1358
                originalPhones.add(phone);
1441
                    originalPhones.add(phone);
1359
                same = false;
1442
                    same = false;
1360
                for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) {
1443
                    for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) {
1361
                    copyPhones.add(phoneCopy);
1444
                        copyPhones.add(phoneCopy);
1362
                    if(!same && phone == phoneCopy) {
1445
                        if(!same && phone == phoneCopy) {
1363
                        same = true;
1446
                            same = true;
1447
                        }
1364
                    }
1448
                    }
1449
                    if(cascadeDepth == CopyGroup.NO_CASCADE) {
1450
                        assertTrue("phone has been copied", same);
1451
                    } else {
1452
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS
1453
                        assertFalse("phone has not been copied", same);
1454
                    }
1365
                }
1455
                }
1366
                if(cascadeDepth == CopyGroup.NO_CASCADE) {
1367
                    assertTrue("phone has been copied", same);
1368
                } else {
1369
                    // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS
1370
                    assertFalse("phone has not been copied", same);
1371
                }
1372
            }
1456
            }
1457
            
1458
            assertTrue("copyEmployees.size() == " + copyEmployees.size() + "; was expected " + originalEmployees.size(), originalEmployees.size() == copyEmployees.size());
1459
            assertTrue("copyAddresses.size() == " + copyAddresses.size() + "; was expected " + originalAddresses.size(), originalAddresses.size() == copyAddresses.size());
1460
            assertTrue("copyProjects.size() == " + copyProjects.size() + "; was expected " + originalProjects.size(), originalProjects.size() == copyProjects.size());
1461
            assertTrue("copyPhones.size() == " + copyPhones.size() + "; was expected " + originalPhones.size(), originalPhones.size() == copyPhones.size());
1462
        } finally {
1463
            if(isTransactionActive(em)) {
1464
                rollbackTransaction(em);
1465
            }
1373
        }
1466
        }
1374
        
1375
        assertTrue("copyEmployees.size() == " + copyEmployees.size() + "; was expected " + originalEmployees.size(), originalEmployees.size() == copyEmployees.size());
1376
        assertTrue("copyAddresses.size() == " + copyAddresses.size() + "; was expected " + originalAddresses.size(), originalAddresses.size() == copyAddresses.size());
1377
        assertTrue("copyProjects.size() == " + copyProjects.size() + "; was expected " + originalProjects.size(), originalProjects.size() == copyProjects.size());
1378
        assertTrue("copyPhones.size() == " + copyPhones.size() + "; was expected " + originalPhones.size(), originalPhones.size() == copyPhones.size());
1379
    }
1467
    }
1380
    
1468
    
1381
    private <T> T serialize(Serializable entity) throws IOException, ClassNotFoundException {
1469
    private <T> T serialize(Serializable entity) throws IOException, ClassNotFoundException {
1382
        byte[] bytes = SerializationHelper.serialize(entity);
1470
        byte[] bytes = SerializationHelper.serialize(entity);
1383
        return (T) SerializationHelper.deserialize(bytes);
1471
        ObjectInputStream inStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
1472
        return (T) inStream.readObject();
1384
    }
1473
    }
1474
1475
    private Object clone(Serializable object) throws IOException, ClassNotFoundException {
1476
        byte[] bytes = SerializationHelper.serialize(object);
1477
        ObjectInputStream inStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
1478
        return inStream.readObject();
1479
    }
1385
}
1480
}

Return to bug 319134