/*
 * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     05/19/2010-2.1 ailitchev - Bug 244124 - Add Nested FetchGroup
package org.eclipse.persistence.testing.tests.jpa.fetchgroups;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;

import junit.framework.TestSuite;

import org.eclipse.persistence.config.CacheUsage;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.indirection.IndirectList;
import org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.helper.IdentityHashSet;
import org.eclipse.persistence.internal.helper.SerializationHelper;
import org.eclipse.persistence.internal.jpa.EntityManagerImpl;
import org.eclipse.persistence.internal.queries.AttributeItem;
import org.eclipse.persistence.internal.queries.EntityFetchGroup;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jpa.JpaEntityManager;
import org.eclipse.persistence.mappings.OneToOneMapping;
import org.eclipse.persistence.queries.AttributeGroup;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.sessions.CopyGroup;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.testing.models.jpa.advanced.Address;
import org.eclipse.persistence.testing.models.jpa.advanced.Department;
import org.eclipse.persistence.testing.models.jpa.advanced.Employee;
import org.eclipse.persistence.testing.models.jpa.advanced.EmploymentPeriod;
import org.eclipse.persistence.testing.models.jpa.advanced.PhoneNumber;
import org.eclipse.persistence.testing.models.jpa.advanced.Project;

import org.junit.Test;

/**
 * Simple tests to verify the functionality of {@link FetchGroup} when the
 * entities are detached through serialization.
 *
 * @author dclarke
 * @since EclipseLink 2.1
 */
public class SimpleSerializeFetchGroupTests extends BaseFetchGroupTests {

    public SimpleSerializeFetchGroupTests() {
        super();
    }

    public SimpleSerializeFetchGroupTests(String name) {
        super(name);
    }

    public static junit.framework.Test suite() {
        TestSuite suite = new TestSuite();
        suite.setName("SimpleSerializeFetchGroupTests");

        suite.addTest(new SimpleSerializeFetchGroupTests("testSetup"));
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyWriteReplaceOnFetchGroup"));
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyAddAttributeInDetachedEntityFetchGroup"));
        suite.addTest(new SimpleSerializeFetchGroupTests("singleResultEmptyFetchGroup"));
        suite.addTest(new SimpleSerializeFetchGroupTests("resultListEmptyFetchGroup"));
        suite.addTest(new SimpleSerializeFetchGroupTests("resultListPeriodFetchGroup"));
        suite.addTest(new SimpleSerializeFetchGroupTests("managerFetchGroup"));
        suite.addTest(new SimpleSerializeFetchGroupTests("managerFetchGroupWithJoinFetch"));
        suite.addTest(new SimpleSerializeFetchGroupTests("employeeNamesFetchGroup"));
        suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
        suite.addTest(new SimpleSerializeFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));
        suite.addTest(new SimpleSerializeFetchGroupTests("verifyFetchedRelationshipAttributes"));
        suite.addTest(new SimpleSerializeFetchGroupTests("attrAndVHContainSameObjectAfterGetRealAttributeValue"));
        if (!isJPA10()) {
            suite.addTest(new SimpleSerializeFetchGroupTests("findMinimalFetchGroup"));
            suite.addTest(new SimpleSerializeFetchGroupTests("findEmptyFetchGroup_setUnfetchedSalary"));
            suite.addTest(new SimpleSerializeFetchGroupTests("verifyUnfetchedAttributes"));
            suite.addTest(new SimpleSerializeFetchGroupTests("simpleSerializeAndMerge"));
            suite.addTest(new SimpleSerializeFetchGroupTests("partialMerge"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupObjectGraph"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyGroupMerge2"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPk"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithPkUseFullGroup"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPk"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyWithoutPkUseFullGroup"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyNoCascade"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadePrivateParts"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyCascadeAllParts"));
            suite.addTest(new SimpleSerializeFetchGroupTests("copyEmbedded"));
        }

        return suite;
    }

    @Test
    public void verifyWriteReplaceOnFetchGroup() throws Exception {
        EntityFetchGroup fg = new EntityFetchGroup(new String[]{"basic", "a"});
        //fg.addAttribute("basic");
        //fg.addAttribute("a.b");

        //assertTrue(fg.getClass() == FetchGroup.class);

        FetchGroup serFG = serialize(fg);

        assertNotNull(serFG);
        assertTrue(serFG.getClass() == EntityFetchGroup.class);
        assertTrue(serFG.hasItems());

        AttributeItem basicFI = serFG.getItem("basic");

        assertNotNull(basicFI);
        //assertTrue(basicFI instanceof DetachedFetchItem);

        AttributeItem aFI = serFG.getItem("a");

        assertNotNull(aFI);
        //assertTrue(aFI instanceof DetachedFetchItem);
        // serialized EntityFetchGroup is always flat - doesn't have nested groups.
        assertNull(aFI.getGroup());
        /*assertNotNull(aFI.getGroup());
        assertTrue(aFI.getGroup() instanceof EntityFetchGroup);
        EntityFetchGroup aEFG = (EntityFetchGroup) aFI.getGroup();
        assertNull(aEFG.getParent());
        assertTrue(aEFG.hasItems());

        AttributeItem bFI = aEFG.getItem("b");

        assertNotNull(bFI);
        //assertTrue(bFI instanceof DetachedFetchItem);
        assertNull(bFI.getGroup());*/
    }

    @Test
    public void findMinimalFetchGroup() throws Exception {
        EntityManager em = createEntityManager();
        int minId = minimumEmployeeId(em);

        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        Map<String, Object> properties = new HashMap<String, Object>();

        FetchGroup fg = new FetchGroup();
        fg.addAttribute("id");
        fg.addAttribute("version");

        properties.put(QueryHints.FETCH_GROUP, fg);

        Employee emp = em.find(Employee.class, minId, properties);

        assertNotNull(emp);
        assertFetched(emp, fg);
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        assertFetchedAttribute(emp, "id");
        assertFetchedAttribute(emp, "version");
        assertNotFetchedAttribute(emp, "firstName");
        assertNotFetchedAttribute(emp, "lastName");
        assertNotFetchedAttribute(emp, "gender");
        assertNotFetchedAttribute(emp, "salary");
        assertNotFetchedAttribute(emp, "startTime");
        assertNotFetchedAttribute(emp, "endTime");
        assertNotFetchedAttribute(emp, "period");
        assertNotFetchedAttribute(emp, "address");
        assertNotFetchedAttribute(emp, "manager");
        assertNotFetchedAttribute(emp, "phoneNumbers");
        assertNotFetchedAttribute(emp, "projects");

        assertTrue(getFetchGroup(emp).getClass() == EntityFetchGroup.class);
        Employee serEmp = serialize(emp);

        assertNotNull(serEmp);
        assertFetchedAttribute(serEmp, "id");
        assertFetchedAttribute(serEmp, "version");
        assertNotFetchedAttribute(serEmp, "firstName");
        assertNotFetchedAttribute(serEmp, "lastName");
        assertNotFetchedAttribute(serEmp, "gender");
        assertNotFetchedAttribute(serEmp, "salary");
        assertNotFetchedAttribute(serEmp, "startTime");
        assertNotFetchedAttribute(serEmp, "endTime");
        assertNotFetchedAttribute(serEmp, "period");
        assertNotFetchedAttribute(serEmp, "address");
        assertNotFetchedAttribute(serEmp, "manager");
        assertNotFetchedAttribute(serEmp, "phoneNumbers");
        assertNotFetchedAttribute(serEmp, "projects");

        assertTrue(getFetchGroup(serEmp) instanceof EntityFetchGroup);

        serEmp.setFirstName("Doug");
        assertFetchedAttribute(serEmp, "firstName");
    }

    @Test
    public void findEmptyFetchGroup_setUnfetchedSalary() throws Exception {
        EntityManager em = createEntityManager();
        int minId = minimumEmployeeId(em);
        try {
            beginTransaction(em);

            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            Map<String, Object> properties = new HashMap<String, Object>();
            FetchGroup emptyFG = new FetchGroup();
            properties.put(QueryHints.FETCH_GROUP, emptyFG);

            Employee emp = em.find(Employee.class, minId, properties);

            assertNotNull(emp);
            assertFetched(emp, emptyFG);
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            // Check Basics
            assertFetchedAttribute(emp, "id");
            assertFetchedAttribute(emp, "version");
            assertNotFetchedAttribute(emp, "firstName");
            assertNotFetchedAttribute(emp, "lastName");
            assertNotFetchedAttribute(emp, "gender");
            assertNotFetchedAttribute(emp, "salary");
            assertNotFetchedAttribute(emp, "startTime");
            assertNotFetchedAttribute(emp, "endTime");
            if (emp.getPeriod() != null) {
                assertFetchedAttribute(emp.getPeriod(), "startDate");
                assertFetchedAttribute(emp.getPeriod(), "endDate");
            }
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            // Check Relationships
            assertNotFetchedAttribute(emp, "address");
            assertNotFetchedAttribute(emp, "manager");
            assertNotFetchedAttribute(emp, "phoneNumbers");
            assertNotFetchedAttribute(emp, "projects");

            emp.setSalary(1);

            assertFetchedAttribute(emp, "salary");

            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertNoFetchGroup(emp);

            emp.getAddress();

            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertNoFetchGroup(emp.getAddress());

            emp.getPhoneNumbers().size();

            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
                assertNoFetchGroup(phone);
            }
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    /**
     * Verify that attributes added to detached EntityFetchGroup are added using
     * DetachedFetchItem
     */
    @Test
    public void verifyAddAttributeInDetachedEntityFetchGroup() {
        EntityFetchGroup detFG = new EntityFetchGroup(new String[]{"basic", "a"});

        //detFG.addAttribute("basic");
        //detFG.addAttribute("a.b");

        //assertNull(detFG.getParent());
        assertEquals(2, detFG.getItems().size());

        AttributeItem basicItem = detFG.getItem("basic");
        assertNotNull(basicItem);
        assertEquals("basic", basicItem.getAttributeName());
        //assertTrue(basicItem instanceof DetachedFetchItem);
        assertNull(basicItem.getGroup());
        assertSame(detFG, basicItem.getParent());
        //assertFalse(basicItem.useDefaultFetchGroup());

        AttributeItem aItem = detFG.getItem("a");
        assertNotNull(aItem);
        assertEquals("a", aItem.getAttributeName());
        //assertTrue(aItem instanceof DetachedFetchItem);
        // serialized EntityFetchGroup is always flat - doesn't have nested groups.
        //assertNull(aItem.getGroup());
        assertNull(aItem.getGroup());
        assertSame(detFG, aItem.getParent());
        //assertFalse(aItem.useDefaultFetchGroup());
        //assertTrue(aItem.getGroup() instanceof EntityFetchGroup);

        //EntityFetchGroup aFG = (EntityFetchGroup) aItem.getGroup();

        //assertEquals(1, aFG.getItems().size());

        //AttributeItem bItem = aFG.getItem("b");
        //assertNotNull(bItem);
        //assertEquals("b", bItem.getAttributeName());
        //assertTrue(bItem instanceof DetachedFetchItem);
        //assertNull(bItem.getGroup());
        //assertSame(aFG, bItem.getParent());
        //assertFalse(bItem.useDefaultFetchGroup());
    }

    @Test
    public void singleResultEmptyFetchGroup() throws Exception {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
            query.setParameter("ID", minimumEmployeeId(em));
            FetchGroup emptyFG = new FetchGroup();
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);

            Employee emp = (Employee) query.getSingleResult();

            assertNotNull(emp);
            assertFetched(emp, emptyFG);
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            // Check Basics
            assertFetchedAttribute(emp, "id");
            assertFetchedAttribute(emp, "version");
            assertNotFetchedAttribute(emp, "firstName");
            assertNotFetchedAttribute(emp, "lastName");
            assertNotFetchedAttribute(emp, "gender");
            assertNotFetchedAttribute(emp, "salary");
            assertNotFetchedAttribute(emp, "startTime");
            assertNotFetchedAttribute(emp, "endTime");
            if (emp.getPeriod() != null) {
                assertFetchedAttribute(emp.getPeriod(), "startDate");
                assertFetchedAttribute(emp.getPeriod(), "endDate");
            }

            // Check Relationships
            assertNotFetchedAttribute(emp, "address");
            assertNotFetchedAttribute(emp, "manager");
            assertNotFetchedAttribute(emp, "phoneNumbers");
            assertNotFetchedAttribute(emp, "projects");

            emp.getSalary();

            assertFetchedAttribute(emp, "salary");

            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertNoFetchGroup(emp);

            emp.getAddress();

            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertNoFetchGroup(emp.getAddress());

            emp.getPhoneNumbers().size();

            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            for (PhoneNumber phone : emp.getPhoneNumbers()) {
                assertNoFetchGroup(phone);
            }
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    /**
     *
     */
    @Test
    public void resultListEmptyFetchGroup() throws Exception {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
            query.setParameter("ID", minimumEmployeeId(em));
            FetchGroup emptyFG = new FetchGroup();
            query.setHint(QueryHints.FETCH_GROUP, emptyFG);

            List<Employee> emps = query.getResultList();

            assertNotNull(emps);
            assertEquals(1, emps.size());

            Employee emp = emps.get(0);

            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertFetched(emp, emptyFG);

            // Check Basics
            assertFetchedAttribute(emp, "id");
            assertFetchedAttribute(emp, "version");
            assertNotFetchedAttribute(emp, "firstName");
            assertNotFetchedAttribute(emp, "lastName");
            assertNotFetchedAttribute(emp, "gender");
            assertNotFetchedAttribute(emp, "salary");
            assertNotFetchedAttribute(emp, "startTime");
            assertNotFetchedAttribute(emp, "endTime");
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            if (emp.getPeriod() != null) {
                assertFetchedAttribute(emp.getPeriod(), "startDate");
                assertFetchedAttribute(emp.getPeriod(), "endDate");
            }

            // Check Relationships
            assertNotFetchedAttribute(emp, "address");
            assertNotFetchedAttribute(emp, "manager");
            assertNotFetchedAttribute(emp, "phoneNumbers");
            assertNotFetchedAttribute(emp, "projects");

            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            emp.getSalary();

            assertFetchedAttribute(emp, "salary");
            assertNoFetchGroup(emp);
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            assertNoFetchGroup(emp.getAddress());

            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            for (PhoneNumber phone : emp.getPhoneNumbers()) {
                assertNoFetchGroup(phone);
            }
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    /**
     *
     */
    @Test
    public void resultListPeriodFetchGroup() throws Exception {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
            query.setParameter("ID", minimumEmployeeId(em));
            FetchGroup fg = new FetchGroup();
            fg.addAttribute("period");
            query.setHint(QueryHints.FETCH_GROUP, fg);

            List<Employee> emps = query.getResultList();

            assertNotNull(emps);
            assertEquals(1, emps.size());

            Employee emp = emps.get(0);

            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertFetched(emp, fg);

            // Check Basics
            assertFetchedAttribute(emp, "id");
            assertFetchedAttribute(emp, "version");
            assertNotFetchedAttribute(emp, "firstName");
            assertNotFetchedAttribute(emp, "lastName");
            assertNotFetchedAttribute(emp, "gender");
            assertNotFetchedAttribute(emp, "salary");
            assertNotFetchedAttribute(emp, "startTime");
            assertNotFetchedAttribute(emp, "endTime");
            if (emp.getPeriod() != null) {
                assertFetchedAttribute(emp.getPeriod(), "startDate");
                assertFetchedAttribute(emp.getPeriod(), "endDate");
            }

            // Check Relationships
            assertNotFetchedAttribute(emp, "address");
            assertNotFetchedAttribute(emp, "manager");
            assertNotFetchedAttribute(emp, "phoneNumbers");
            assertNotFetchedAttribute(emp, "projects");

            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            emp.getSalary();

            assertFetchedAttribute(emp, "salary");
            assertNoFetchGroup(emp);

            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            assertNoFetchGroup(emp.getAddress());

            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            for (PhoneNumber phone : emp.getPhoneNumbers()) {
                assertNoFetchGroup(phone);
            }
            assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    @Override
    @Test
    public void managerFetchGroup() throws Exception {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            // Use q query since find will only use default fetch group
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
            //query.setParameter("ID", minimumEmployeeId(em));

            // Complex where clause used to avoid triggering employees and their departments:
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL");

            FetchGroup managerFG = new FetchGroup();
            managerFG.addAttribute("manager");

            query.setHint(QueryHints.FETCH_GROUP, managerFG);

            assertNotNull(getFetchGroup(query));
            assertSame(managerFG, getFetchGroup(query));

            Employee emp = (Employee) query.getSingleResult();

            assertFetched(emp, managerFG);
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            // manager (if not null) hasn't been instantiated yet.
            int nSqlToAdd = 0;
            if (emp.getManager() != null) {
                assertFetchedAttribute(emp, "manager");
                // additional sql to select the manager
                nSqlToAdd++;
            }

            assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            emp.getLastName();

            assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertNoFetchGroup(emp);

            for (PhoneNumber phone : emp.getPhoneNumbers()) {
                assertNoFetchGroup(phone);
                phone.getAreaCode();
            }

            assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    @Test
    public void managerFetchGroupWithJoinFetch() throws Exception {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            //int minId = minimumEmployeeId(em);
            //assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            // Use q query since find will only use default fetch group
            //Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
            //query.setParameter("ID", minId);

            // Complex where clause used to avoid triggering employees and their departments:
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL");

            FetchGroup managerFG = new FetchGroup();
            managerFG.addAttribute("manager");

            query.setHint(QueryHints.FETCH_GROUP, managerFG);
            query.setHint(QueryHints.LEFT_FETCH, "e.manager");

            assertNotNull(getFetchGroup(query));
            assertSame(managerFG, getFetchGroup(query));

            Employee emp = (Employee) query.getSingleResult();

            assertFetched(emp, managerFG);
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            // manager has been already instantiated by the query.
            emp.getManager();
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            // instantiates the whiole object
            emp.getLastName();

            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertNoFetchGroup(emp);

            for (PhoneNumber phone : emp.getPhoneNumbers()) {
                assertNoFetchGroup(phone);
                phone.getAreaCode();
            }

            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    @Override
    @Test
    public void employeeNamesFetchGroup() throws Exception {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            int minId = minimumEmployeeId(em);
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            // Use q query since find will only use default fetch group
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
            query.setParameter("ID", minId);
            FetchGroup namesFG = new FetchGroup();
            namesFG.addAttribute("firstName");
            namesFG.addAttribute("lastName");

            query.setHint(QueryHints.FETCH_GROUP, namesFG);

            assertNotNull(getFetchGroup(query));
            assertSame(namesFG, getFetchGroup(query));

            Employee emp = (Employee) query.getSingleResult();

            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertFetched(emp, namesFG);

            emp.getId();
            emp.getFirstName();
            emp.getLastName();
            emp.getVersion();

            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertFetched(emp, namesFG);

            emp.getGender();
            emp.getSalary();

            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertNoFetchGroup(emp);

            for (PhoneNumber phone : emp.getPhoneNumbers()) {
                assertNoFetchGroup(phone);
                phone.getAreaCode();
            }
            assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            if (emp.getManager() != null) {
                assertEquals(5, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
                assertNoFetchGroup(emp.getManager());
            } else {
                // If manager_id field is null then getManager() does not trigger an sql.
                assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            }
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    @Override
    @Test
    public void joinFetchEmployeeAddressWithDynamicFetchGroup() {
        EntityManager em = createEntityManager();

        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address");

        FetchGroup fetchGroup = new FetchGroup("names");
        fetchGroup.addAttribute("firstName");
        fetchGroup.addAttribute("lastName");
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);

        List<Employee> emps = query.getResultList();

        assertNotNull(emps);
    }

    @Override
    @Test
    public void joinFetchEmployeeAddressPhoneWithDynamicFetchGroup() {
        EntityManager em = createEntityManager();

        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.id FROM PhoneNumber p)");

        FetchGroup fetchGroup = new FetchGroup("names");
        fetchGroup.addAttribute("firstName");
        fetchGroup.addAttribute("lastName");
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);

        List<Employee> emps = query.getResultList();

        assertNotNull(emps);
    }

    @Test
    public void verifyUnfetchedAttributes() throws Exception {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            TypedQuery<Employee> q = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class);
            FetchGroup fg = new FetchGroup("Employee.empty");
            q.setHint(QueryHints.FETCH_GROUP, fg);
            Employee emp = q.getSingleResult();

            assertNotNull(emp);
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            // This check using the mapping returns a default (empty) IndirectList
            /*OneToManyMapping phoneMapping = (OneToManyMapping) employeeDescriptor.getMappingForAttributeName("phoneNumbers");
            IndirectList phones = (IndirectList) phoneMapping.getAttributeValueFromObject(emp);
            assertNotNull(phones);
            assertTrue(phones.isInstantiated());
            assertEquals(0, phones.size());
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());*/

            IndirectList phonesIL = (IndirectList) emp.getPhoneNumbers();
            assertFalse(phonesIL.isInstantiated());
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            assertTrue(emp.getPhoneNumbers().size() > 0);
            assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    @Test
    public void verifyFetchedRelationshipAttributes() throws Exception {
        EntityManager em = createEntityManager();

        FetchGroup fg = new FetchGroup("Employee.relationships");
        fg.addAttribute("address");
        fg.addAttribute("phoneNumbers");
        fg.addAttribute("manager");
        fg.addAttribute("projects");

        Map<String, Object> hints = new HashMap<String, Object>();
        hints.put(QueryHints.FETCH_GROUP, fg);

        Employee emp = minimumEmployee(em, hints);

        assertNotNull(emp);

    }

    @Test
    public void simpleSerializeAndMerge() throws Exception {
        EntityManager em = createEntityManager();
        int id = minEmployeeIdWithAddressAndPhones(em);
        HashMap<String, PhoneNumber> phonesOriginal = new HashMap();
        // save the original Employee for clean up
        Employee empOriginal = em.find(Employee.class, id);
        for(PhoneNumber phone : empOriginal.getPhoneNumbers()) {
            phonesOriginal.put(phone.getType(), phone);
        }
        closeEntityManager(em);
        clearCache();
        int newSalary = empOriginal.getSalary() * 2;
        if(newSalary == 0) {
            newSalary = 100;
        }

        em = createEntityManager();
        beginTransaction(em);
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = "+id);
        FetchGroup fetchGroup = new FetchGroup("names");
        fetchGroup.addAttribute("firstName");
        fetchGroup.addAttribute("lastName");
        fetchGroup.addAttribute("address.country");
        fetchGroup.addAttribute("phoneNumbers.areaCode");
        fetchGroup.addAttribute("phoneNumbers.owner.id");
        fetchGroup.setShouldLoad(true);
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
        Employee emp = (Employee)query.getSingleResult();

        Employee empSerialized;
        Employee empDeserialized;
        Employee empMerged;
        try {
            empSerialized = serialize(emp);

            assertFetched(empSerialized, fetchGroup);
            empSerialized.setFirstName("newFirstName");
            empSerialized.setLastName("newLastName");

            // salary is not in the original fetchGroup
            empSerialized.setSalary(newSalary);
            FetchGroup extendedFetchGroup = fetchGroup.clone();
            extendedFetchGroup.addAttribute("salary");
            assertFetched(empSerialized, extendedFetchGroup);

            empSerialized.getAddress().setCountry("newCountry");
            assertFetched(empSerialized.getAddress(), fetchGroup.getGroup("address"));
            // address.city is not in the original fetchGroup
            empSerialized.getAddress().setCity("newCity");
            extendedFetchGroup.addAttribute("address.city");
            assertFetched(empSerialized.getAddress(), extendedFetchGroup.getGroup("address"));

            // phoneNumbers.number is not in the original fetchGroup
            extendedFetchGroup.addAttribute("phoneNumbers.number");
            for(PhoneNumber phone : empSerialized.getPhoneNumbers()) {
                phone.setAreaCode("000");
                assertFetched(phone, fetchGroup.getGroup("phoneNumbers"));
                // phoneNumbers.number is not in the original fetchGroup
                phone.setNumber("0000000");
                assertFetched(phone, extendedFetchGroup.getGroup("phoneNumbers"));
            }

            empDeserialized = serialize(empSerialized);
            assertFetched(empDeserialized, extendedFetchGroup);
            assertFetched(empDeserialized.getAddress(), extendedFetchGroup.getGroup("address"));
            for(PhoneNumber phone : empDeserialized.getPhoneNumbers()) {
                assertFetched(phone, extendedFetchGroup.getGroup("phoneNumbers"));
            }

            empMerged = em.merge(empDeserialized);

            // verify merged in em
            assertEquals("newFirstName", empMerged.getFirstName());
            assertEquals("newLastName", empMerged.getLastName());
            assertEquals(newSalary, empMerged.getSalary());
            assertEquals("newCountry", empMerged.getAddress().getCountry());
            assertEquals("newCity", empMerged.getAddress().getCity());
            for(PhoneNumber phone : empSerialized.getPhoneNumbers()) {
                assertEquals("000", phone.getAreaCode());
                assertEquals("0000000", phone.getNumber());
            }

            // verify that the attributes outside of the fetch group not nullified.
            assertEquals(empOriginal.getGender(), empMerged.getGender());
            if(empOriginal.getDepartment() != null) {
                assertEquals(empOriginal.getDepartment().getId(), empMerged.getDepartment().getId());
            }
            if(empOriginal.getPeriod() != null) {
                assertEquals(empOriginal.getPeriod().getStartDate(), empMerged.getPeriod().getStartDate());
                assertEquals(empOriginal.getPeriod().getEndDate(), empMerged.getPeriod().getEndDate());
            }
            assertEquals(empOriginal.getPayScale(), empMerged.getPayScale());
            assertEquals(empOriginal.getStartTime(), empMerged.getStartTime());
            assertEquals(empOriginal.getEndTime(), empMerged.getEndTime());
            commitTransaction(em);
        } finally {
            if(isTransactionActive(em)) {
               rollbackTransaction(em);
            }
        }

        // verify merged in the shared cache - clear em cache, query using cache only.
        em.clear();
        Map<String, Object> hints = new HashMap<String, Object>(2);
        hints.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
        //hints.put(QueryHints.FETCH_GROUP, fetchGroup);
        Employee empShared = em.find(Employee.class, id, hints);
        assertEquals("newFirstName", empShared.getFirstName());
        assertEquals("newLastName", empShared.getLastName());
        assertEquals(newSalary, empShared.getSalary());
        assertEquals("newCountry", empShared.getAddress().getCountry());
        assertEquals("newCity", empShared.getAddress().getCity());
        for(PhoneNumber phone : empShared.getPhoneNumbers()) {
            assertEquals("000", phone.getAreaCode());
            assertEquals("0000000", phone.getNumber());
        }

        // verify merged in shared the db - clear both em and shared caches.
        // Must read through the old EntityManager - the changes haven't been committed in the db.
        clearCache();
        em.clear();
        Employee empDb = em.find(Employee.class, id);
        assertEquals("newFirstName", empDb.getFirstName());
        assertEquals("newLastName", empDb.getLastName());
        assertEquals(newSalary, empDb.getSalary());
        assertEquals("newCountry", empDb.getAddress().getCountry());
        assertEquals("newCity", empDb.getAddress().getCity());
        for(PhoneNumber phone : empDb.getPhoneNumbers()) {
            assertEquals("000", phone.getAreaCode());
            assertEquals("0000000", phone.getNumber());
        }

        // clean up
        beginTransaction(em);
        try {
            empDb.setFirstName(empOriginal.getFirstName());
            empDb.setLastName(empOriginal.getLastName());
            empDb.setSalary(empOriginal.getSalary());
            empDb.getAddress().setCountry(empOriginal.getAddress().getCountry());
            empDb.getAddress().setCity(empOriginal.getAddress().getCity());
            for(PhoneNumber phone : empDb.getPhoneNumbers()) {
                PhoneNumber phoneOriginal = phonesOriginal.get(phone.getType());
                phone.setAreaCode(phoneOriginal.getAreaCode());
                phone.setNumber(phoneOriginal.getNumber());
            }
            commitTransaction(em);
        } finally {
            if(isTransactionActive(em)) {
                rollbackTransaction(em);
             }
            closeEntityManager(em);
        }
    }
    /*public void simpleSerializeAndMerge() throws Exception {
        EntityManager em = createEntityManager();
        int id = minimumEmployeeId(em);
        // save the original Employee for clean up
        Employee empOriginal = em.find(Employee.class, id);
        closeEntityManager(em);
        clearCache();
        int newSalary = empOriginal.getSalary() * 2;
        if(newSalary == 0) {
            newSalary = 100;
        }

        em = createEntityManager();
        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = "+id);
        FetchGroup fetchGroup = new FetchGroup("names");
        fetchGroup.addAttribute("firstName");
        fetchGroup.addAttribute("lastName");
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
        Employee emp = (Employee)query.getSingleResult();

        Employee empSerialized;
        Employee empDeserialized;
        Employee empMerged;
        beginTransaction(em);
        try {
            empSerialized = serialize(emp);
            empSerialized.setFirstName("newFirstName");
            empSerialized.setLastName("newLastName");
            empSerialized.setSalary(newSalary);
            empDeserialized = serialize(empSerialized);
            empMerged = em.merge(empDeserialized);

            // verify merged in em
            assertEquals("newFirstName", empMerged.getFirstName());
            assertEquals("newLastName", empMerged.getLastName());
            assertEquals(newSalary, empMerged.getSalary());
            commitTransaction(em);
        } finally {
            if(isTransactionActive(em)) {
               rollbackTransaction(em);
            }
        }

        // verify merged in the shared cache - clear em cache, query using cache only.
        em.clear();
        HashMap hints = new HashMap(2);
        hints.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
        hints.put(QueryHints.FETCH_GROUP, fetchGroup);
        Employee empShared = em.find(Employee.class, id, hints);
        assertEquals("newFirstName", empShared.getFirstName());
        assertEquals("newLastName", empShared.getLastName());
        assertEquals(newSalary, empShared.getSalary());

        // verify merged in shared the db - clear both em and shared caches.
        // Must read through the old EntityManager - the changes haven't been committed in the db.
        clearCache();
        em.clear();
        Employee empDb = em.find(Employee.class, id);
        assertEquals("newFirstName", empDb.getFirstName());
        assertEquals("newLastName", empDb.getLastName());
        assertEquals(newSalary, empDb.getSalary());

        beginTransaction(em);
        try {
            empDb.setFirstName(empOriginal.getFirstName());
            empDb.setLastName(empOriginal.getLastName());
            empDb.setSalary(empOriginal.getSalary());
            commitTransaction(em);
        } finally {
            if(isTransactionActive(em)) {
                rollbackTransaction(em);
             }
            closeEntityManager(em);
        }
    }*/

    public void partialMerge() throws Exception {
        EntityManager em = createEntityManager();
        // Search for an Employee with an Address and Phone Numbers
        try {
            beginTransaction(em);
            TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e WHERE e.address IS NOT NULL AND e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)", Employee.class);

            // Load only its names and phone Numbers
            FetchGroup fetchGroup = new FetchGroup();
            fetchGroup.addAttribute("firstName");
            fetchGroup.addAttribute("lastName");
            FetchGroup phonesFG = phoneDescriptor.getFetchGroupManager().createFullFetchGroup();
            // that ensures the owner is not instantiated
            phonesFG.addAttribute("owner.id");
            phonesFG.removeAttribute("status");
            phonesFG.setShouldLoad(true);
            fetchGroup.addAttribute("phoneNumbers", phonesFG);

            // Make sure the FetchGroup also forces the relationships to be loaded
            fetchGroup.setShouldLoad(true);
            query.setHint(QueryHints.FETCH_GROUP, fetchGroup);

            Employee emp = query.getSingleResult();

            // Detach Employee through Serialization
            Employee detachedEmp = serialize(emp);

            // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
            detachedEmp.setFirstName(emp.getLastName());
            detachedEmp.setLastName(emp.getFirstName());
            detachedEmp.addPhoneNumber(new PhoneNumber("TEST", "999", "999999"));
            // NOte that salary was not part of the original FetchGroupdetachedEmp.setSalary(1);
            detachedEmp.setSalary(1);

            // Merge the detached employee
            em.merge(detachedEmp);
            // Flush the changes to the database
            em.flush();
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
    }

    public void copyGroupObjectGraph() {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            TypedQuery<Department> query = em.createQuery("SELECT d FROM ADV_DEPT d WHERE d.id IN (SELECT MIN(dd.id) FROM ADV_DEPT dd)", Department.class);
            Department dept = query.getSingleResult();

            CopyGroup group = new CopyGroup();
            group.addAttribute("name");
            group.addAttribute("employees", new CopyGroup());
            group.getGroup("employees").addAttribute("name");
            group.getGroup("employees").addAttribute("department", new CopyGroup());
            group.getGroup("employees").getGroup("department").addAttribute("name");
            Department deptCopy = (Department) em.unwrap(JpaEntityManager.class).copy(dept, group);

            String reportCG = group.toString();
            assertNotNull(reportCG);
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
    }


    public void copyGroupMerge() {
        // Search for an Employee with an Address and Phone Numbers
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(ee.id) FROM Employee ee)", Employee.class);
            Employee emp = query.getSingleResult();
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            System.out.println(">>> Employee retrieved");

            // Copy only its names and phone Numbers
            AttributeGroup group = new CopyGroup();
            group.addAttribute("firstName");
            group.addAttribute("lastName");
            group.addAttribute("address");

            Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            System.out.println(">>> Employee copied");

            // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
            empCopy.setFirstName(emp.getLastName());
            empCopy.setLastName(emp.getFirstName());

            // Note that salary was not part of the original FetchGroup
            //empCopy.setSalary(1);

            // Merge the detached employee
            em.merge(empCopy);
            System.out.println(">>> Sparse merge complete");

            // Flush the changes to the database
            em.flush();
            System.out.println(">>> Flush complete");
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
    }

    public void copyGroupMerge2() {
        // Search for an Employee with an Address and Phone Numbers
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e", Employee.class);
            query.setHint(QueryHints.BATCH, "e.address");
            List<Employee> employees = query.getResultList();
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            System.out.println(">>> Employees retrieved");

            // Copy only its names and phone Numbers
            AttributeGroup group = new CopyGroup();
            group.addAttribute("firstName");
            group.addAttribute("lastName");
            group.addAttribute("address");

            List<Employee> employeesCopy = (List<Employee>) em.unwrap(JpaEntityManager.class).copy(employees, group);
            assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            System.out.println(">>> Employees copied");

            for(Employee empCopy : employeesCopy) {
                // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
                String firstName = empCopy.getFirstName();
                String lastName = empCopy.getLastName();
                empCopy.setFirstName(lastName);
                empCopy.setLastName(firstName);

                // Note that salary was not part of the original FetchGroup
                //empCopy.setSalary(1);

                // Merge the detached employee
                em.merge(empCopy);
            }
            System.out.println(">>> Sparse merge complete");

            // Flush the changes to the database
            em.flush();
            System.out.println(">>> Flush complete");

        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
    }


    @Test
    public void copyWithPk() {
        copyWithOrWithoutPk(false, false);
    }

    @Test
    public void copyWithPkUseFullGroup() {
        copyWithOrWithoutPk(false, true);
    }

    @Test
    public void copyWithoutPk() {
        copyWithOrWithoutPk(true, false);
    }

    @Test
    public void copyWithoutPkUseFullGroup() {
        copyWithOrWithoutPk(true, true);
    }

    void copyWithOrWithoutPk(boolean noPk, boolean useFullGroup) {
        CopyGroup group = new CopyGroup();
        if(noPk) {
            // setShouldResetPrimaryKey set to true means that:
            //  pk would not be copied - unless explicitly specified in the group;
            //  copy would not have a fetch group
            group.setShouldResetPrimaryKey(true);
            // setShouldResetVersion set to true means that
            // version would not be copied - unless explicitly specified in the group;
            group.setShouldResetVersion(true);
        }
        group.cascadeTree(); // Copy only the attributes specified
        // note that
        // default value shouldResetPrimaryKey==false causes pk to copied, too;
        // default value shouldResetVersion==false causes version to be copied, too.
        group.addAttribute("firstName");
        group.addAttribute("lastName");
        group.addAttribute("gender");
        group.addAttribute("period");
        group.addAttribute("salary");

        if(useFullGroup) {
            // copy group contains all the attributes defined in Address class
            CopyGroup address = addressDescriptor.getFetchGroupManager().createFullFetchGroup().toCopyGroup();
            // attribute "employees" removed from the group
            address.removeAttribute("employees");
            if(noPk) {
                // pk attribute "ID" removed from the group - not that it's necessary to explicitly remove it:
                // setShouldResetPrimaryKey(true) would not remove explicitly specified in the group pk.
                address.removeAttribute("ID");
                // note that default value shouldResetPrimaryKey==false would have resulted in copying the pk (that would be equivalent of adding the removed "ID" attribute back to the group).
                address.setShouldResetPrimaryKey(true);
                address.setShouldResetVersion(true);
            }
            group.addAttribute("address", address);

            // copy group contains all the attributes defined in PhoneNumber class
            CopyGroup phones = phoneDescriptor.getFetchGroupManager().createFullFetchGroup().toCopyGroup();
            if(noPk) {
                // the only goal of setting shouldResetPrimaryKey to true here is to avoid a FetchGroup being assigned to phone's copy.
                // Note that because both pk components ("owner" and "type") are part of the copy group they  still will be copied:
                // the phone's copy will have the same type as original and it's owner will be original's owner's copy.
                phones.setShouldResetPrimaryKey(true);
            }
            if(!noPk) {
                // to avoid instantiating the whole owner
                phones.addAttribute("owner.id");
            }
            group.addAttribute("phoneNumbers", phones);
        } else {
            // implicitly created sub CopyGroups address and phoneNumbers will have the same shouldReset flags values as their master CopyGroup.

            group.addAttribute("address.country");
            group.addAttribute("address.province");
            group.addAttribute("address.street");
            group.addAttribute("address.postalCode");
            group.addAttribute("address.city");

            if(noPk) {
                group.addAttribute("phoneNumbers.owner");
            } else {
                // to avoid instantiating the whole owner
                group.addAttribute("phoneNumbers.owner.id");
            }
            group.addAttribute("phoneNumbers.type");
            group.addAttribute("phoneNumbers.id");
            group.addAttribute("phoneNumbers.areaCode");
            group.addAttribute("phoneNumbers.number");
        }

        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            Employee emp = minimumEmployee(em);
            Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);

            if(noPk) {
                assertNoFetchGroup(empCopy);
                assertNoFetchGroup(empCopy.getAddress());
                for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) {
                    assertNoFetchGroup(phoneCopy);
                }
                // Persist the employee copy
                em.persist(empCopy);
            } else {
                FetchGroup fetchGroup = group.toFetchGroup();
                // the following call adds pk and version, verifies that all attribute names correct.
                employeeDescriptor.getFetchGroupManager().prepareAndVerify(fetchGroup);
                // copyEmp, its address and phones each should have an EntityFetchGroup corresponding to the respective copyGroup.
                assertFetched(empCopy, fetchGroup);

                EntityFetchGroup addressEntityFetchGroup = addressDescriptor.getFetchGroupManager().getEntityFetchGroup(fetchGroup.getGroup("address"));
                if(addressEntityFetchGroup == null) {
                    assertNoFetchGroup(empCopy.getAddress());
                } else {
                    assertFetched(empCopy.getAddress(), addressEntityFetchGroup);
                }

                EntityFetchGroup phonesEntityFetchGroup = phoneDescriptor.getFetchGroupManager().getEntityFetchGroup(fetchGroup.getGroup("phoneNumbers"));
                for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) {
                    if(phonesEntityFetchGroup == null) {
                        assertNoFetchGroup(phoneCopy);
                    } else {
                        assertFetched(phoneCopy, phonesEntityFetchGroup);
                    }
                }

                // to cause updates let's change something:
                //   in Employee table
                empCopy.setFirstName((empCopy.getFirstName() != null ? empCopy.getFirstName() : "") + "_NEW");
                //   in Salary table
                empCopy.setSalary(empCopy.getSalary() * 2 + 1);
                //   in Address
                empCopy.getAddress().setCountry((empCopy.getAddress().getCountry() != null ? empCopy.getAddress().getCountry() : "") + "_NEW");
                //   in each Phone
                for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) {
                    if(phoneCopy.getAreaCode() != null && phoneCopy.getAreaCode().equals("000")) {
                        phoneCopy.setAreaCode("111");
                    } else {
                        phoneCopy.setAreaCode("000");
                    }
                }
                em.merge(empCopy);
            }

            // Insert a new row into Employee, Salary, Address, and a row for each Phone
            int nExpectedInsertsOrUpdates = 3 + empCopy.getPhoneNumbers().size();
            int nExpectedInserts, nExpectedUpdates;
            if(noPk) {
                nExpectedInserts = nExpectedInsertsOrUpdates;
                // table sequence might have been updated
                nExpectedUpdates = getQuerySQLTracker(em).getTotalSQLUPDATECalls();
            } else {
                nExpectedInserts = 0;
                nExpectedUpdates = nExpectedInsertsOrUpdates;
            }

            // Flush the changes to the database
            em.flush();

            assertEquals(nExpectedInserts, getQuerySQLTracker(em).getTotalSQLINSERTCalls());
            assertEquals(nExpectedUpdates, getQuerySQLTracker(em).getTotalSQLUPDATECalls());
        } finally {
            if(isTransactionActive(em)) {
                rollbackTransaction(em);
            }
        }
    }

    @Test
    public void copyNoCascade() {
        copyCascade(CopyGroup.NO_CASCADE);
    }

    @Test
    public void copyCascadePrivateParts() {
        copyCascade(CopyGroup.CASCADE_PRIVATE_PARTS);
    }

    @Test
    public void copyCascadeAllParts() {
        copyCascade(CopyGroup.CASCADE_ALL_PARTS);
    }

    void copyCascade(int cascadeDepth) {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            Query query = em.createQuery("SELECT e FROM Employee e");
            List<Employee> employees = query.getResultList();

            CopyGroup group = new CopyGroup();
            if(cascadeDepth == CopyGroup.NO_CASCADE) {
                group.dontCascade();
            } else if(cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
                // default cascade depth setting
                group.cascadePrivateParts();
            } else if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) {
                group.cascadeAllParts();
            } else {
                fail("Invalid cascadeDepth = " + cascadeDepth);
            }
            group.setShouldResetPrimaryKey(true);

            List<Employee> employeesCopy;
            if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
                // In this case the objects should be copied one by one - each one using a new CopyGroup.
                // That ensures most referenced object are original ones (not copies) -
                // the only exception is privately owned objects in CASCADE_PRIVATE_PARTS case.
                employeesCopy = new ArrayList(employees.size());
                for(Employee emp : employees) {
                    CopyGroup groupClone = group.clone();
                    employeesCopy.add((Employee)em.unwrap(JpaEntityManager.class).copy(emp, groupClone));
                }
            } else {
                // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
                // In this case all objects should be copied using a single CopyGroup.
                // That ensures identities of the copies:
                // for instance if several employees referenced the same project,
                // then all copies of these employees will reference the single copy of the project.
                employeesCopy = (List)em.unwrap(JpaEntityManager.class).copy(employees, group);
            }

            // IdentityHashSets will be used to verify copy identities
            IdentityHashSet originalEmployees = new IdentityHashSet();
            IdentityHashSet copyEmployees = new IdentityHashSet();
            IdentityHashSet originalAddresses = new IdentityHashSet();
            IdentityHashSet copyAddresses = new IdentityHashSet();
            IdentityHashSet originalProjects = new IdentityHashSet();
            IdentityHashSet copyProjects = new IdentityHashSet();
            IdentityHashSet originalPhones = new IdentityHashSet();
            IdentityHashSet copyPhones = new IdentityHashSet();

            int size = employees.size();
            for(int i=0; i < size; i++) {
                Employee emp = employees.get(i);
                Employee empCopy = employeesCopy.get(i);
                if(cascadeDepth == CopyGroup.CASCADE_ALL_PARTS) {
                    originalEmployees.add(emp);
                    copyEmployees.add(empCopy);
                } else {
                    // cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS
                    // In this case all Employees referenced by empCopyes are originals (manager and managed employees).
                    // Therefore if we add here each emp and empCopy to originalEmployees and copyEmployees respectively
                    // then copyEmployees will always contain all original managers and managed + plus all copies.
                    // Therefore in this case originalEmployees and copyEmployees will contain only references (managers and managed employees).
                }

                if(emp.getAddress() == null) {
                    assertTrue("emp.getAddress() == null, but empCopy.getAddress() != null", empCopy.getAddress() == null);
                } else {
                    originalAddresses.add(emp.getAddress());
                    copyAddresses.add(empCopy.getAddress());
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
                        assertTrue("address has been copied", emp.getAddress() == empCopy.getAddress());
                    } else {
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
                        assertFalse("address has not been copied", emp.getAddress() == empCopy.getAddress());
                    }
                }

                boolean same;
                for(Project project : emp.getProjects()) {
                    originalProjects.add(project);
                    same = false;
                    for(Project projectCopy : empCopy.getProjects()) {
                        copyProjects.add(projectCopy);
                        if(!same && project == projectCopy) {
                            same = true;
                        }
                    }
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
                        assertTrue("project has been copied", same);
                    } else {
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
                        assertFalse("project has not been copied", same);
                    }
                }

                for(Employee managedEmp : emp.getManagedEmployees()) {
                    originalEmployees.add(managedEmp);
                    same = false;
                    for(Employee managedEmpCopy : empCopy.getManagedEmployees()) {
                        copyEmployees.add(managedEmpCopy);
                        if(!same && managedEmp == managedEmpCopy) {
                            same = true;
                        }
                    }
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
                        assertTrue("managedEmployee has been copied", same);
                    } else {
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
                        assertFalse("managedEmployee has not been copied", same);
                    }
                }

                if(emp.getManager() == null) {
                    assertTrue("emp.getManager() == null, but empCopy.getManager() != null", empCopy.getManager() == null);
                } else {
                    originalEmployees.add(emp.getManager());
                    copyEmployees.add(empCopy.getManager());
                    if(cascadeDepth == CopyGroup.NO_CASCADE || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS) {
                        assertTrue("manager has been copied", emp.getManager() == empCopy.getManager());
                    } else {
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS
                        assertFalse("manager has not been copied", emp.getManager() == empCopy.getManager());
                    }
                }

                // phoneNumbers is privately owned
                for(PhoneNumber phone : emp.getPhoneNumbers()) {
                    originalPhones.add(phone);
                    same = false;
                    for(PhoneNumber phoneCopy : empCopy.getPhoneNumbers()) {
                        copyPhones.add(phoneCopy);
                        if(!same && phone == phoneCopy) {
                            same = true;
                        }
                    }
                    if(cascadeDepth == CopyGroup.NO_CASCADE) {
                        assertTrue("phone has been copied", same);
                    } else {
                        // cascadeDepth == CopyGroup.CASCADE_ALL_PARTS || cascadeDepth == CopyGroup.CASCADE_PRIVATE_PARTS
                        assertFalse("phone has not been copied", same);
                    }
                }
            }

            assertTrue("copyEmployees.size() == " + copyEmployees.size() + "; was expected " + originalEmployees.size(), originalEmployees.size() == copyEmployees.size());
            assertTrue("copyAddresses.size() == " + copyAddresses.size() + "; was expected " + originalAddresses.size(), originalAddresses.size() == copyAddresses.size());
            assertTrue("copyProjects.size() == " + copyProjects.size() + "; was expected " + originalProjects.size(), originalProjects.size() == copyProjects.size());
            assertTrue("copyPhones.size() == " + copyPhones.size() + "; was expected " + originalPhones.size(), originalPhones.size() == copyPhones.size());
        } finally {
            if(isTransactionActive(em)) {
                rollbackTransaction(em);
            }
        }
    }

    @Test
    public void attrAndVHContainSameObjectAfterGetRealAttributeValue() throws Exception {
        String errorMsg = "";
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

             Query query = em.createQuery("SELECT e FROM Employee e WHERE e.address IS NOT NULL and e.manager IS NOT NULL");
             List<Employee> employees = query.getResultList();

             OneToOneMapping addressMapping = (OneToOneMapping)employeeDescriptor.getMappingForAttributeName("address");
             OneToOneMapping managerMapping = (OneToOneMapping)employeeDescriptor.getMappingForAttributeName("manager");

             InstanceVariableAttributeAccessor addressAccessor = new InstanceVariableAttributeAccessor();
             addressAccessor.setAttributeName("m_address");
             addressAccessor.initializeAttributes(Employee.class);

             InstanceVariableAttributeAccessor managerAccessor = new InstanceVariableAttributeAccessor();
             managerAccessor.setAttributeName("manager");
             managerAccessor.initializeAttributes(Employee.class);

             AbstractSession session = (AbstractSession)((EntityManagerImpl)em.getDelegate()).getActiveSession();

             for(Employee emp : employees) {
                 String localErrorMsg = "";
                 Address addressVH = (Address)addressMapping.getRealAttributeValueFromObject(emp, session);
                 Address addressAttr = (Address)addressAccessor.getAttributeValueFromObject(emp);
                 if(addressVH != addressAttr) {
                     localErrorMsg += "\n\taddressVH = " + addressVH + " != addressAttr = " + addressAttr;
                 }
                 Employee managerVH = (Employee)managerMapping.getRealAttributeValueFromObject(emp, session);
                 Employee managerAttr = (Employee)managerAccessor.getAttributeValueFromObject(emp);
                 if(managerVH != managerAttr) {
                     localErrorMsg += "\n\tmanagerVH = " + managerVH + " != managerAttr = " + managerAttr;
                 }
                 if(localErrorMsg.length() > 0) {
                     localErrorMsg = emp.toString() + localErrorMsg + "\n";
                     errorMsg += localErrorMsg;
                 }
             }
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
        if(errorMsg.length() > 0) {
            errorMsg = '\n' + errorMsg;
            fail(errorMsg);
        }
    }

    @Test
    public void copyEmbedded() {
        Employee emp = new Employee();
        emp.setPeriod(new EmploymentPeriod(Helper.dateFromYearMonthDate(1993, 0, 1), Helper.dateFromYearMonthDate(1996, 11, 31)));

        CopyGroup group = new CopyGroup();
        group.addAttribute("period");

        EntityManager em = createEntityManager();
        Employee empCopy = (Employee) em.unwrap(ServerSession.class).copy(emp, group);

        assertTrue("!emp.getPeriod().equals(empCopy.getPeriod())", emp.getPeriod().equals(empCopy.getPeriod()));
        assertHasFetchGroup(empCopy);
    }

    private <T> T serialize(Serializable entity) throws IOException, ClassNotFoundException {
        byte[] bytes = SerializationHelper.serialize(entity);
        ObjectInputStream inStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
        return (T) inStream.readObject();
    }
}
