/*
 * Copyright (c) 2012, 2020 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:
//     Oracle - initial API and implementation
//     03/29/2016-2.6_WAS Will Dazey
//       - 490114: Add testing for PersistenceUnitUtil.getIdentifier with nested embeddables in EmbeddedId class
package org.eclipse.persistence.testing.tests.jpa.complexaggregate;

import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.PersistenceUnitUtil;
import jakarta.persistence.Query;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.eclipse.persistence.annotations.BatchFetchType;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.changetracking.ChangeTracker;
import org.eclipse.persistence.internal.descriptors.changetracking.AttributeChangeListener;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.jpa.JpaHelper;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.testing.framework.JoinedAttributeTestHelper;
import org.eclipse.persistence.testing.framework.QuerySQLTracker;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.Body;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.CitySlicker;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.CoachVitals;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.ComplexAggregateTableCreator;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.CountryDweller;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.Heart;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.HockeyCoach;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.HockeyPlayer;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.HockeyPuck;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.HockeyRink;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.HockeySponsor;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.HockeyTeam;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.Name;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.PersonalVitals;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.Location;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.Place;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.Role;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.TeamVitals;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.Torso;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.Vitals;
import org.eclipse.persistence.testing.models.jpa.complexaggregate.World;

/**
 * <p><b>Purpose</b>: To JPA with the complex aggregate test model.
 */
public class ComplexAggregateTestSuite extends JUnitTestCase {

    public ComplexAggregateTestSuite() {
    }

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

    /**
     * The setup is done as a test, both to record its failure, and to allow execution in the server.
     */
    public void testSetup() {
        new ComplexAggregateTableCreator().replaceTables(getDatabaseSession());
        clearCache();
    }

    public static Test suite() {
        TestSuite suite = (TestSuite) suiteSpring();
        suite.addTest(new ComplexAggregateTestSuite("testInvalidateAndRefreshEmbeddableParent"));

        return suite;
    }

    public static Test suiteSpring() {
        TestSuite suite = new TestSuite();
        suite.setName("ComplexAggregateTestSuite");
        suite.addTest(new ComplexAggregateTestSuite("testSetup"));
        suite.addTest(new ComplexAggregateTestSuite("testMapKeyColumnMerge"));
        suite.addTest(new ComplexAggregateTestSuite("testAggregatePrimaryKey"));
        suite.addTest(new ComplexAggregateTestSuite("testAggregatePrimaryKeyOrderBy"));
        suite.addTest(new ComplexAggregateTestSuite("testNestedAggregate"));
        suite.addTest(new ComplexAggregateTestSuite("testNestedAggregatePrimaryKey"));
        suite.addTest(new ComplexAggregateTestSuite("testAggregateReadOnlyMapKey"));
        suite.addTest(new ComplexAggregateTestSuite("testComplexAggregateJoin"));
        suite.addTest(new ComplexAggregateTestSuite("testComplexAggregateBatch"));
        suite.addTest(new ComplexAggregateTestSuite("testAggregateFieldAttributeOverrides"));

        return suite;
    }

    public void testMapKeyColumnMerge() {
        clearCache();

        EntityManager em = createEntityManager();
        try {
            HockeyPlayer player = new HockeyPlayer();
            player.setFirstName("Guy");
            player.setLastName("Flower");
            // must have non null Vitals and TeamVitals because TeamVitals has a target foreign key mapping, therefore allowingNull automatically set to false
            Vitals vitals = new Vitals();
            vitals.setTeamVitals(new TeamVitals());
            player.setVitals(vitals);

            HockeyPlayer player2 = new HockeyPlayer();
            player2.setFirstName("Power");
            player2.setLastName("Flower");;
            // must have non null Vitals and TeamVitals because TeamVitals has a target foreign key mapping, therefore allowingNull automatically set to false
            Vitals vitals2 = new Vitals();
            vitals2.setTeamVitals(new TeamVitals());
            player2.setVitals(vitals2);

            HockeyCoach coach = new HockeyCoach();
            coach.setFirstName("Scott");
            coach.setLastName("Arrowman");
            CoachVitals cVitals = new CoachVitals();
            PersonalVitals pVitals = new PersonalVitals();
            pVitals.setAge(45);
            pVitals.setHeight(3.3);
            pVitals.setWeight(333);
            cVitals.setPersonalVitals(pVitals);
            coach.setVitals(cVitals);

            beginTransaction(em);

            em.persist(player);
            em.persist(player2);
            em.persist(coach);
            Object playerId = player.getPlayerId();
            Object player2Id = player2.getPlayerId();
            Object coachId = coach.getId();
            coach.addFavouritePlayer(player);

            commitTransaction(em);
            closeEntityManager(em);

            em = createEntityManager();
            beginTransaction(em);
    //        ((ChangeTracker)coach)._persistence_setPropertyChangeListener(null);
    //        ((IndirectMap)coach.getFavouritePlayers())._persistence_setPropertyChangeListener(null);
            coach.addFavouritePlayer(player2);
            em.merge(coach);
            commitTransaction(em);

            beginTransaction(em);
            player = em.find(HockeyPlayer.class, playerId);
            player2 = em.find(HockeyPlayer.class, player2Id);
            coach = em.find(HockeyCoach.class, coachId);
            if (player != null){
                em.remove(player);
            }
            if (player2 != null){
                em.remove(player2);
            }
            if (coach != null){
                em.remove(coach);
            }
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
    }

    public void testAggregatePrimaryKey() {
        clearCache();
        EntityManager em = createEntityManager();
        try {
            Name name1 = new Name();
            name1.setFirstName("Tom");
            name1.setLastName("Ware");

            CountryDweller countryDweller = new CountryDweller();
            countryDweller.setAge(30);
            countryDweller.setName(name1);

            CitySlicker citySlicker = new CitySlicker();
            citySlicker.setAge(53);
            // Bug 300696 - Invalid tests: sharing embedded objects is not allowed
            // Changed the test to use clone instead of sharing the same Name between the two Entities.
            Name name1Clone = (Name)name1.clone();
            citySlicker.setName(name1Clone);

            Name name2 = new Name();
            name2.setFirstName("Guy");
            name2.setLastName("Pelletier");

            CountryDweller countryDweller2 = new CountryDweller();
            countryDweller2.setAge(65);
            countryDweller2.setName(name2);

            beginTransaction(em);
            em.persist(countryDweller);
            em.persist(countryDweller2);
            em.persist(citySlicker);
            commitTransaction(em);

            // Clear the cache.
            clearCache();
            em.clear();

            // Now read them back in and delete them.
            beginTransaction(em);

            // Note that in Identity case name1Clone may no longer have the same id as name1
            CitySlicker cs = em.find(CitySlicker.class, name1Clone);
            CountryDweller cd = em.merge(countryDweller);
            CountryDweller cd2 = em.merge(countryDweller2);

            em.remove(cs);
            em.remove(cd);
            em.remove(cd2);

            commitTransaction(em);
        } catch (RuntimeException e) {
            closeEntityManagerAndTransaction(em);
            throw e;
        }
    }

    public void testAggregatePrimaryKeyOrderBy() {
        clearCache();
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            World world = new World();

            // First pair
            Name name1 = new Name();
            name1.setFirstName("Guy");
            name1.setLastName("Pelletier");

            CountryDweller countryDweller1 = new CountryDweller();
            countryDweller1.setAge(30);
            countryDweller1.setName(name1);
            countryDweller1.setGender("Male");
            em.persist(countryDweller1);
            world.addCountryDweller(countryDweller1);

            CitySlicker citySlicker1 = new CitySlicker();
            citySlicker1.setAge(53);
            // Bug 300696 - Invalid tests: sharing embedded objects is not allowed
            // Changed the test to use clone instead of sharing the same Name between the two Entities.
            Name name1Clone = (Name)name1.clone();
            citySlicker1.setName(name1Clone);
            citySlicker1.setGender("Male");
            em.persist(citySlicker1);
            world.addCitySlicker(citySlicker1);

            // Second pair
            Name name2 = new Name();
            name2.setFirstName("Steve");
            name2.setLastName("Harp");

            CountryDweller countryDweller2 = new CountryDweller();
            countryDweller2.setAge(28);
            countryDweller2.setName(name2);
            countryDweller2.setGender("Male");
            em.persist(countryDweller2);
            world.addCountryDweller(countryDweller2);

            CitySlicker citySlicker2 = new CitySlicker();
            citySlicker2.setAge(41);
            // Bug 300696 - Invalid tests: sharing embedded objects is not allowed
            // Changed the test to use clone instead of sharing the same Name between the two Entities.
            Name name2Clone = (Name)name2.clone();
            citySlicker2.setName(name2Clone);
            citySlicker2.setGender("Male");
            em.persist(citySlicker2);
            world.addCitySlicker(citySlicker2);

            // Third pair
            Name name3 = new Name();
            name3.setFirstName("Jesse");
            name3.setLastName("Petoncle");

            CountryDweller countryDweller3 = new CountryDweller();
            countryDweller3.setAge(48);
            countryDweller3.setName(name3);
            countryDweller3.setGender("Male");
            em.persist(countryDweller3);
            world.addCountryDweller(countryDweller3);

            CitySlicker citySlicker3 = new CitySlicker();
            citySlicker3.setAge(76);
            // Bug 300696 - Invalid tests: sharing embedded objects is not allowed
            // Changed the test to use clone instead of sharing the same Name between the two Entities.
            Name name3Clone = (Name)name3.clone();
            citySlicker3.setName(name3Clone);
            citySlicker3.setGender("Female");
            em.persist(citySlicker3);
            world.addCitySlicker(citySlicker3);

            em.persist(world);

            commitTransaction(em);

            // Clear the cache.
            clearCache();
            em.clear();

            // Now read them back in and delete them.
            beginTransaction(em);

            World w = em.find(World.class, world.getId());

            Collection css = w.getCitySlickers();
            css.toString();
            Collection cds = w.getCountryDwellers();
            cds.toString();

            // Check the ordering
            // JBS - Ordering check removed as order is random based on class method order which is not consistent in Java.
            //citySlickersAreOrdered = ((CitySlicker) css.elementAt(0)).getName().getFirstName().equals("Guy") && ((CitySlicker) css.elementAt(1)).getName().getFirstName().equals("Jesse") && ((CitySlicker) css.elementAt(2)).getName().getFirstName().equals("Steve");
            //countryDwellersAreOrdered = ((CountryDweller) cds.elementAt(0)).getAge() == 28 && ((CountryDweller) cds.elementAt(1)).getAge() == 30 && ((CountryDweller) cds.elementAt(2)).getAge() == 48;

            // Make sure we delete them
            // Note that in Identity case name1Clone may no longer have the same id as name1
            CitySlicker cs1 = em.find(CitySlicker.class, name1Clone);
            em.remove(cs1);
            CitySlicker cs2 = em.find(CitySlicker.class, name2Clone);
            em.remove(cs2);
            CitySlicker cs3 = em.find(CitySlicker.class, name3Clone);
            em.remove(cs3);

            CountryDweller cd1 = em.merge(countryDweller1);
            em.remove(cd1);
            CountryDweller cd2 = em.merge(countryDweller2);
            em.remove(cd2);
            CountryDweller cd3 = em.merge(countryDweller3);
            em.remove(cd3);

            commitTransaction(em);

        } catch (RuntimeException e) {
            closeEntityManagerAndTransaction(em);
            throw e;
        }
    }

    public void testNestedAggregate() {
        int[] teamIDs = new int[3];
        clearCache();
        //////// Team 1 ////////
        HockeyTeam team1 = new HockeyTeam();
        team1.setName("Axemen");
        team1.setAwayColor("Red");
        team1.setHomeColor("White");
        team1.setLevel("Division 5");

        //////// Team 2 ////////
        HockeyTeam team2 = new HockeyTeam();
        team2.setName("Cartier Partners");
        team2.setAwayColor("Black");
        team2.setHomeColor("White");
        team2.setLevel("Division 2");

        //////// Team 3 ////////
        HockeyTeam team3 = new HockeyTeam();
        team3.setName("Dead Last");
        team3.setAwayColor("Blue");
        team3.setHomeColor("White");
        team3.setLevel("Division 4");

        //////// Player 1 ////////
        HockeyPlayer player1 = new HockeyPlayer();
        player1.setFirstName("Guy");
        player1.setLastName("Pelletier");

        PersonalVitals personalVitals1 = new PersonalVitals();
        personalVitals1.setAge(29);
        personalVitals1.setHeight(1.80);
        personalVitals1.setWeight(180);

        TeamVitals teamVitals1 = new TeamVitals();
        teamVitals1.setHockeyTeam(team2);
        team2.getPlayers().add(player1);
        teamVitals1.setJerseyNumber(20);
        teamVitals1.setPosition("Goalie");
        teamVitals1.getRoles().add(new Role("Stop pucks!"));

        Vitals vitals1 = new Vitals();
        vitals1.setPersonalVitals(personalVitals1);
        vitals1.setTeamVitals(teamVitals1);
        player1.setVitals(vitals1);

        //////// Player 2 ////////
        HockeyPlayer player2 = new HockeyPlayer();
        player2.setFirstName("Dave");
        player2.setLastName("McCann");

        PersonalVitals personalVitals2 = new PersonalVitals();
        personalVitals2.setAge(35);
        personalVitals2.setHeight(1.77);
        personalVitals2.setWeight(165);

        TeamVitals teamVitals2 = new TeamVitals();
        teamVitals2.setHockeyTeam(team1);
        team1.getPlayers().add(player2);
        teamVitals2.setJerseyNumber(70);
        teamVitals2.setPosition("Left wing");
        teamVitals2.getRoles().add(new Role("Power play unit"));
        teamVitals2.getRoles().add(new Role("Face-off specialist"));

        Vitals vitals2 = new Vitals();
        vitals2.setPersonalVitals(personalVitals2);
        vitals2.setTeamVitals(teamVitals2);
        player2.setVitals(vitals2);

        //////// Player 3 ////////
        HockeyPlayer player3 = new HockeyPlayer();
        player3.setFirstName("Tom");
        player3.setLastName("Ware");

        PersonalVitals personalVitals3 = new PersonalVitals();
        personalVitals3.setAge(30);
        personalVitals3.setHeight(1.83);
        personalVitals3.setWeight(200);

        TeamVitals teamVitals3 = new TeamVitals();
        teamVitals3.setHockeyTeam(team1);
        team1.getPlayers().add(player3);
        teamVitals3.setJerseyNumber(12);
        teamVitals3.setPosition("Defence");
        teamVitals3.getRoles().add(new Role("Penalty kill unit"));

        Vitals vitals3 = new Vitals();
        vitals3.setPersonalVitals(personalVitals3);
        vitals3.setTeamVitals(teamVitals3);
        player3.setVitals(vitals3);

        //////// Player 4 ////////
        HockeyPlayer player4 = new HockeyPlayer();
        player4.setFirstName("George");
        player4.setLastName("Robinson");

        PersonalVitals personalVitals4 = new PersonalVitals();
        personalVitals4.setAge(32);
        personalVitals4.setHeight(1.86);
        personalVitals4.setWeight(210);

        TeamVitals teamVitals4 = new TeamVitals();
        teamVitals4.setHockeyTeam(team3);
        team3.getPlayers().add(player4);
        teamVitals4.setJerseyNumber(6);
        teamVitals4.setPosition("Center");
        teamVitals4.getRoles().add(new Role("Power play unit"));
        teamVitals4.getRoles().add(new Role("Goon"));

        Vitals vitals4 = new Vitals();
        vitals4.setPersonalVitals(personalVitals4);
        vitals4.setTeamVitals(teamVitals4);
        player4.setVitals(vitals4);

        //////// Player 5 ////////
        HockeyPlayer player5 = new HockeyPlayer();
        player5.setFirstName("Andrew");
        player5.setLastName("Glennie");

        PersonalVitals personalVitals5 = new PersonalVitals();
        personalVitals5.setAge(31);
        personalVitals5.setHeight(1.80);
        personalVitals5.setWeight(205);

        TeamVitals teamVitals5 = new TeamVitals();
        teamVitals5.setHockeyTeam(team3);
        team3.getPlayers().add(player5);
        teamVitals5.setJerseyNumber(7);
        teamVitals5.setPosition("Right wing");

        Vitals vitals5 = new Vitals();
        vitals5.setPersonalVitals(personalVitals5);
        vitals5.setTeamVitals(teamVitals5);
        player5.setVitals(vitals5);

        //////// Player 6 ////////
        HockeyPlayer player6 = new HockeyPlayer();
        player6.setFirstName("David");
        player6.setLastName("Whittaker");

        PersonalVitals personalVitals6 = new PersonalVitals();
        personalVitals6.setAge(32);
        personalVitals6.setHeight(1.83);
        personalVitals6.setWeight(190);

        TeamVitals teamVitals6 = new TeamVitals();
        teamVitals6.setHockeyTeam(team2);
        team2.getPlayers().add(player6);
        teamVitals6.setJerseyNumber(17);
        teamVitals6.setPosition("Defence");

        Vitals vitals6 = new Vitals();
        vitals6.setPersonalVitals(personalVitals6);
        vitals6.setTeamVitals(teamVitals6);
        player6.setVitals(vitals6);

        //////// Coach 1 ////////
        HockeyCoach coach1 = new HockeyCoach();
        coach1.setFirstName("Don");
        coach1.setLastName("Hyslop");

        PersonalVitals coachPersonalVitals1 = new PersonalVitals();
        coachPersonalVitals1.setAge(55);
        coachPersonalVitals1.setHeight(1.85);
        coachPersonalVitals1.setWeight(200);

        CoachVitals coachVitals1 = new CoachVitals();
        coachVitals1.setPersonalVitals(coachPersonalVitals1);
        coachVitals1.setHockeyTeam(team1);
        team1.getCoaches().add(coach1);
        coach1.setVitals(coachVitals1);

        //////// Coach 2 ////////
        HockeyCoach coach2 = new HockeyCoach();
        coach2.setFirstName("Al");
        coach2.setLastName("Montoya");

        PersonalVitals coachPersonalVitals2 = new PersonalVitals();
        coachPersonalVitals2.setAge(63);
        coachPersonalVitals2.setHeight(1.86);
        coachPersonalVitals2.setWeight(213);

        CoachVitals coachVitals2 = new CoachVitals();
        coachVitals2.setPersonalVitals(coachPersonalVitals2);
        coachVitals2.setHockeyTeam(team2);
        team2.getCoaches().add(coach2);
        coach2.setVitals(coachVitals2);

        //////// Coach 3 ////////
        HockeyCoach coach3 = new HockeyCoach();
        coach3.setFirstName("Guy");
        coach3.setLastName("Carbonneau");

        PersonalVitals coachPersonalVitals3 = new PersonalVitals();
        coachPersonalVitals3.setAge(47);
        coachPersonalVitals3.setHeight(1.91);
        coachPersonalVitals3.setWeight(191);

        CoachVitals coachVitals3 = new CoachVitals();
        coachVitals3.setPersonalVitals(coachPersonalVitals3);
        coachVitals3.setHockeyTeam(team3);
        team3.getCoaches().add(coach3);
        coach3.setVitals(coachVitals3);

        //////// Coach 4 ////////
        HockeyCoach coach4 = new HockeyCoach();
        coach4.setFirstName("Walter");
        coach4.setLastName("Mullen");

        PersonalVitals coachPersonalVitals4 = new PersonalVitals();
        coachPersonalVitals4.setAge(67);
        coachPersonalVitals4.setHeight(1.94);
        coachPersonalVitals4.setWeight(187);

        CoachVitals coachVitals4 = new CoachVitals();
        coachVitals4.setPersonalVitals(coachPersonalVitals4);
        coachVitals4.setHockeyTeam(team1);
        team1.getCoaches().add(coach4);
        coach4.setVitals(coachVitals4);

        //////// Coach 5 ////////
        HockeyCoach coach5 = new HockeyCoach();
        coach5.setFirstName("Ben");
        coach5.setLastName("Gasket");

        PersonalVitals coachPersonalVitals5 = new PersonalVitals();
        coachPersonalVitals5.setAge(33);
        coachPersonalVitals5.setHeight(1.67);
        coachPersonalVitals5.setWeight(155);

        CoachVitals coachVitals5 = new CoachVitals();
        coachVitals5.setPersonalVitals(coachPersonalVitals5);
        coachVitals5.setHockeyTeam(team2);
        team2.getCoaches().add(coach5);
        coach5.setVitals(coachVitals5);

        //////// Coach 6 ////////
        HockeyCoach coach6 = new HockeyCoach();
        coach6.setFirstName("Jim");
        coach6.setLastName("Balogna");

        PersonalVitals coachPersonalVitals6 = new PersonalVitals();
        coachPersonalVitals6.setAge(37);
        coachPersonalVitals6.setHeight(1.77);
        coachPersonalVitals6.setWeight(179);

        CoachVitals coachVitals6 = new CoachVitals();
        coachVitals6.setPersonalVitals(coachPersonalVitals5);
        coachVitals6.setHockeyTeam(team3);
        team3.getCoaches().add(coach6);
        coach6.setVitals(coachVitals6);

        EntityManager em = createEntityManager();
        //////// Commit the new objects ////////
        beginTransaction(em);

        try{
            em.persist(team1);
            teamIDs[0] = team1.getId();
            em.persist(team2);
            teamIDs[1] = team2.getId();
            em.persist(team3);
            teamIDs[2] = team3.getId();

            em.persist(player1);
            em.persist(player2);
            em.persist(player3);
            em.persist(player4);
            em.persist(player5);
            em.persist(player6);

            em.persist(coach1);
            em.persist(coach2);
            em.persist(coach3);
            em.persist(coach4);
            em.persist(coach5);
            em.persist(coach6);

            commitTransaction(em);
        } catch (RuntimeException ex) {
            closeEntityManagerAndTransaction(em);
            throw ex;
        }

        em = createEntityManager();
        // Check the cache for the objects
        checkTeam(teamIDs[0], em);
        checkTeam(teamIDs[1], em);
        checkTeam(teamIDs[2], em);

        // Initialize the identity map to make sure they were persisted
        clearCache();

        em = createEntityManager();
        em.clear();

        checkTeam(teamIDs[0], em);
        checkTeam(teamIDs[1], em);
        checkTeam(teamIDs[2], em);

        // Verify the order by on coaches worked for team 1 (teamIDs[0])
        HockeyTeam team = em.find(HockeyTeam.class, teamIDs[0]);

        if (team.getCoaches().get(0).getVitals().getPersonalVitals().getAge() != 67) {
            throw new TestErrorException("The order by specification on age for hockey coaches was not observed: " + team.getCoaches());
        }
    }

    private void checkTeam(int id, EntityManager em) {
        HockeyTeam team = em.find(HockeyTeam.class, id);
        if (team == null){
            throw new TestErrorException("Hockey team with ID: " + id + ", was not created.");
        }

        if (team.getPlayers().size() != 2) {
            throw new TestErrorException("Hockey team with ID: " + id + ", did not have 2 players, had: " + team.getPlayers().size());
        }

        if (team.getCoaches().size() != 2) {
            throw new TestErrorException("Hockey team with ID: " + id + ", did not have 2 coach, had: " + team.getCoaches().size());
        }
    }

    public void testNestedAggregatePrimaryKey() {
        clearCache();

        Torso torso;

        EntityManagerFactory emf = getEntityManagerFactory();
        EntityManager em = createEntityManager();
        try {
            Body body = new Body();
            torso = new Torso();
            Heart heart = new Heart();
            heart.setSize(8);
            torso.setHeart(heart);
            body.setTorso(torso);

            beginTransaction(em);
            em.persist(body);
            commitTransaction(em);
        } catch (Exception e) {
            throw new TestErrorException("Exception caught when persisting the new body: " + e.getMessage());
        } finally {
            closeEntityManager(em);
        }

        em = createEntityManager();
        Exception m_testException = null;
        DatabaseSessionImpl m_session = getDatabaseSession();
        Body m_refreshedBody = null;
        // Try to read the body back, clear the cache first.
        try {
            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();
            m_refreshedBody = em.find(Body.class, torso);
        } catch (Exception e) {
            m_testException = e;
        }

        if (m_testException != null) {
            throw new TestErrorException("Exception caught reading back the persisted body: " + m_testException);
        }

        if (m_refreshedBody == null) {
            throw new TestErrorException("Unable to read back the persisted body");
        }

        ClassDescriptor descriptor = getDatabaseSession().getClassDescriptor(Body.class);
        Object pks = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(m_refreshedBody, m_session);
        Torso createdTorso = (Torso) descriptor.getCMPPolicy().createPrimaryKeyInstanceFromId(pks, m_session);
        assertTrue("PK's do not match.", m_refreshedBody.getTorso().equals(createdTorso));

        PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
        assertTrue("PersistenceUnitUtil returned incorrect identifier", torso.equals(util.getIdentifier(m_refreshedBody)));
    }

    public void testAggregateReadOnlyMapKey() {
        clearCache();

        HockeyPlayer player = new HockeyPlayer();
        player.setFirstName("Guy");
        player.setLastName("Flower");

        PersonalVitals personalVitals2 = new PersonalVitals();
        personalVitals2.setAge(45);
        personalVitals2.setHeight(1.80);
        personalVitals2.setWeight(185);

        TeamVitals teamVitals2 = new TeamVitals();
        teamVitals2.setJerseyNumber(70);
        teamVitals2.setPosition("Right wing");

        Vitals vitals2 = new Vitals();
        vitals2.setPersonalVitals(personalVitals2);
        vitals2.setTeamVitals(teamVitals2);
        player.setVitals(vitals2);

        HockeyCoach coach = new HockeyCoach();
        coach.setFirstName("Scott");
        coach.setLastName("Arrowman");

        PersonalVitals coachPersonalVitals1 = new PersonalVitals();
        coachPersonalVitals1.setAge(65);
        coachPersonalVitals1.setHeight(1.85);
        coachPersonalVitals1.setWeight(200);

        CoachVitals coachVitals1 = new CoachVitals();
        coachVitals1.setPersonalVitals(coachPersonalVitals1);
        coach.setVitals(coachVitals1);

        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.persist(player);
            em.persist(coach);
            commitTransaction(em);

            Object playerId = player.getPlayerId();
            Object coachId = coach.getId();

            clearCache();
            em.clear();

            beginTransaction(em);
            player = em.find(HockeyPlayer.class, player.getPlayerId());
            coach = em.find(HockeyCoach.class, coach.getId());

            coach.addFavouritePlayer(player);
            commitTransaction(em);

            beginTransaction(em);
            player = em.find(HockeyPlayer.class, playerId);
            coach = em.find(HockeyCoach.class, coachId);
            if (player != null){
                em.remove(player);
            }
            if (coach != null){
                em.remove(coach);
            }
            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
    }

    public void testComplexAggregateJoin() {
        clearCache();

        HockeyTeam team1 = new HockeyTeam();
        team1.setName("Axemen");
        team1.setAwayColor("Red");
        team1.setHomeColor("White");
        team1.setLevel("Division 5");

        ////////Player 1 ////////
        HockeyPlayer player1 = new HockeyPlayer();
        player1.setFirstName("Guy");
        player1.setLastName("Pelletier");

        PersonalVitals personalVitals1 = new PersonalVitals();
        personalVitals1.setAge(29);
        personalVitals1.setHeight(1.80);
        personalVitals1.setWeight(180);

        TeamVitals teamVitals1 = new TeamVitals();

        teamVitals1.setJerseyNumber(20);
        teamVitals1.setPosition("Goalie");
        teamVitals1.getRoles().add(new Role("Stop pucks!"));

        Vitals vitals1 = new Vitals();
        vitals1.setPersonalVitals(personalVitals1);
        vitals1.setTeamVitals(teamVitals1);
        player1.setVitals(vitals1);


        ////////Coach 1 ////////
        HockeyCoach coach1 = new HockeyCoach();
        coach1.setFirstName("Don");
        coach1.setLastName("Hyslop");

        PersonalVitals coachPersonalVitals1 = new PersonalVitals();
        coachPersonalVitals1.setAge(55);
        coachPersonalVitals1.setHeight(1.85);
        coachPersonalVitals1.setWeight(200);

        CoachVitals coachVitals1 = new CoachVitals();
        coachVitals1.setPersonalVitals(coachPersonalVitals1);
        coach1.setVitals(coachVitals1);

        ////////persist the new objects ////////

        EntityManager em = createEntityManager();
        beginTransaction(em);
        em.persist(team1);

        em.persist(player1);
        em.persist(coach1);

        //setup relationships:
        teamVitals1.setHockeyTeam(team1);
        team1.getPlayers().add(player1);
        team1.getCoaches().add(coach1);
        coachVitals1.setHockeyTeam(team1);

        em.flush();

        DatabaseSessionImpl m_session = getDatabaseSession();
        List hockeyCoachResults = null;
        List controledCoachList =  null;
        List controledPlayerList = null;
        List hockeyPlayerResults = null;
        try {
            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();

            Query query1 = em.createQuery("Select a from HockeyCoach a where a.id = "+coach1.getId());
            query1.setHint(QueryHints.LEFT_FETCH, "a.vitals.hockeyTeam");
            hockeyCoachResults = query1.getResultList();

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();

            Query query2 = em.createQuery("Select z from HockeyPlayer z where z.playerId = "+player1.getPlayerId());
            //query2.setHint(QueryHints.LEFT_FETCH, "z.coach");
            query2.setHint(QueryHints.LEFT_FETCH, "z.vitals.teamVitals.hockeyTeam.coaches");
            hockeyPlayerResults = query2.getResultList();

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();

            HockeyCoach expectedCoach = em.find(HockeyCoach.class, coach1.getId());
            expectedCoach.getVitals().getHockeyTeam();
            controledCoachList = new ArrayList<HockeyCoach>(1);
            controledCoachList.add(expectedCoach);

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();

            HockeyPlayer expectedPlayer = em.find(HockeyPlayer.class, player1.getPlayerId());
            expectedPlayer.getVitals().getTeamVitals().getHockeyTeam().getCoaches().size();
            controledPlayerList = new ArrayList<HockeyPlayer>(1);
            controledPlayerList.add(expectedPlayer);

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();
        } finally  {
            try {
                closeEntityManagerAndTransaction(em);
            } catch (RuntimeException re){
                //ignore
            }
        }

        String errorMsg = JoinedAttributeTestHelper.compareCollections(controledCoachList, hockeyCoachResults, m_session.getClassDescriptor(HockeyCoach.class), m_session);
        if (errorMsg.length() > 0) {
            throw new TestErrorException(errorMsg);
        }

        errorMsg = JoinedAttributeTestHelper.compareCollections(controledPlayerList, hockeyPlayerResults, m_session.getClassDescriptor(HockeyPlayer.class), m_session);
        if (errorMsg.length() > 0) {
            throw new TestErrorException(errorMsg);
        }
    }

    public void testComplexAggregateBatch() {
        clearCache();

        HockeyTeam team1 = new HockeyTeam();
        team1.setName("Axemen");
        team1.setAwayColor("Red");
        team1.setHomeColor("White");
        team1.setLevel("Division 5");

        HockeyTeam team2 = new HockeyTeam();
        team2.setName("Ducks");
        team2.setAwayColor("Black");
        team2.setHomeColor("Red");
        team2.setLevel("Division 4");

        ////////Player 1 ////////
        HockeyPlayer player1 = new HockeyPlayer();
        player1.setFirstName("Guy");
        player1.setLastName("Pelletier");

        PersonalVitals personalVitals1 = new PersonalVitals();
        personalVitals1.setAge(29);
        personalVitals1.setHeight(1.80);
        personalVitals1.setWeight(180);

        TeamVitals teamVitals1 = new TeamVitals();

        teamVitals1.setJerseyNumber(20);
        teamVitals1.setPosition("Goalie");
        teamVitals1.getRoles().add(new Role("Stop pucks!"));

        Vitals vitals1 = new Vitals();
        vitals1.setPersonalVitals(personalVitals1);
        vitals1.setTeamVitals(teamVitals1);
        player1.setVitals(vitals1);


        ////////Coach 1 ////////
        HockeyCoach coach1 = new HockeyCoach();
        coach1.setFirstName("Don");
        coach1.setLastName("Hyslop");

        PersonalVitals coachPersonalVitals1 = new PersonalVitals();
        coachPersonalVitals1.setAge(55);
        coachPersonalVitals1.setHeight(1.85);
        coachPersonalVitals1.setWeight(200);

        CoachVitals coachVitals1 = new CoachVitals();
        coachVitals1.setPersonalVitals(coachPersonalVitals1);
        coach1.setVitals(coachVitals1);

        ////////Coach 2 ////////
        HockeyCoach coach2 = new HockeyCoach();
        coach2.setFirstName("Bob");
        coach2.setLastName("Jones");

        PersonalVitals coachPersonalVitals2 = new PersonalVitals();
        coachPersonalVitals2.setAge(44);
        coachPersonalVitals2.setHeight(1.95);
        coachPersonalVitals2.setWeight(250);

        CoachVitals coachVitals2 = new CoachVitals();
        coachVitals2.setPersonalVitals(coachPersonalVitals2);
        coach2.setVitals(coachVitals2);

        ////////persist the new objects ////////

        DatabaseSessionImpl m_session = getDatabaseSession();

        // Count SQL.
        QuerySQLTracker counter = new QuerySQLTracker(m_session);

        EntityManager em = createEntityManager();

        beginTransaction(em);
        em.persist(team1);
        em.persist(team2);

        em.persist(player1);
        em.persist(coach1);
        em.persist(coach2);

        //setup relationships:
        teamVitals1.setHockeyTeam(team1);
        team1.getPlayers().add(player1);
        team1.getCoaches().add(coach1);
        team2.getCoaches().add(coach2);
        coachVitals1.setHockeyTeam(team1);
        coachVitals2.setHockeyTeam(team2);

        em.flush();
        try {
            counter.getSqlStatements().clear();

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();

            Query query1 = em.createQuery("Select a from HockeyCoach a");
            query1.setHint(QueryHints.BATCH, "a.vitals.hockeyTeam");
            List<HockeyCoach> hockeyCoachResults = query1.getResultList();
            for (HockeyCoach coach : hockeyCoachResults) {
                coach.getVitals().getHockeyTeam();
            }

            if (isWeavingEnabled() && counter.getSqlStatements().size() != 2) {
                fail("Should have been 2 queries but was: " + counter.getSqlStatements().size());
            }

            counter.getSqlStatements().clear();

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();

            query1 = em.createQuery("Select a from HockeyCoach a");
            query1.setHint(QueryHints.BATCH, "a.vitals.hockeyTeam");
            query1.setHint(QueryHints.BATCH_TYPE, BatchFetchType.IN);
            hockeyCoachResults = query1.getResultList();
            for (HockeyCoach coach : hockeyCoachResults) {
                coach.getVitals().getHockeyTeam();
            }

            if (isWeavingEnabled() && counter.getSqlStatements().size() != 2) {
                fail("Should have been 2 queries but was: " + counter.getSqlStatements().size());
            }

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();

            counter.getSqlStatements().clear();

            query1 = em.createQuery("Select a from HockeyCoach a");
            query1.setHint(QueryHints.BATCH, "a.vitals.hockeyTeam");
            query1.setHint(QueryHints.BATCH_TYPE, BatchFetchType.EXISTS);
            hockeyCoachResults = query1.getResultList();
            for (HockeyCoach coach : hockeyCoachResults) {
                coach.getVitals().getHockeyTeam();
            }

            if (isWeavingEnabled() && counter.getSqlStatements().size() != 2) {
                fail("Should have been 2 queries but was: " + counter.getSqlStatements().size());
            }

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();

            Query query2 = em.createQuery("Select z from HockeyPlayer z where z.playerId <> 0");
            query2.setHint(QueryHints.BATCH, "z.vitals.teamVitals.hockeyTeam.coaches");
            List<HockeyPlayer> hockeyPlayerResults = query2.getResultList();
            for (HockeyPlayer player : hockeyPlayerResults) {
                player.getVitals().getTeamVitals().getHockeyTeam().getCoaches();
            }

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();

            query2 = em.createQuery("Select z from HockeyPlayer z where z.playerId <> 0");
            query2.setHint(QueryHints.BATCH, "z.vitals.teamVitals.hockeyTeam.coaches");
            query2.setHint(QueryHints.BATCH_TYPE, BatchFetchType.IN);
            hockeyPlayerResults = query2.getResultList();
            for (HockeyPlayer player : hockeyPlayerResults) {
                player.getVitals().getTeamVitals().getHockeyTeam().getCoaches();
            }

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();

            query2 = em.createQuery("Select z from HockeyPlayer z where z.playerId <> 0");
            query2.setHint(QueryHints.BATCH, "z.vitals.teamVitals.hockeyTeam.coaches");
            query2.setHint(QueryHints.BATCH_TYPE, BatchFetchType.EXISTS);
            hockeyPlayerResults = query2.getResultList();
            for (HockeyPlayer player : hockeyPlayerResults) {
                player.getVitals().getTeamVitals().getHockeyTeam().getCoaches();
            }

            em.clear();
            m_session.getIdentityMapAccessor().initializeAllIdentityMaps();
        } finally  {
            try {
                closeEntityManagerAndTransaction(em);
            } catch (RuntimeException re){
                //ignore
            }
            if (counter != null) {
                counter.remove();
            }
        }
    }

    public void testAggregateFieldAttributeOverrides() {
        clearCache();
        DatabaseSessionImpl m_session = getDatabaseSession();

        EntityManager em = createEntityManager();

        beginTransaction(em);

        Place place = new Place();
        place.setCountryCode("US");
        place.setName("Nowhere");
        place.setAddress1(new Location("12 Main Street", "US"));
        place.setAddress2(new Location("34 Easy Street", "US"));

        em.persist(place);

        em.flush();

        rollbackTransaction(em);
    }
    
    /**
     * Bug 474956 RepeatableUnitOfWork linked by Embeddable in shared cache in specific scenario
     * Test the invalidation and refresh of a parent object with an Embeddable instantiated
     * with non-null values. After associating the parent with another object, the Embeddable
     * should not reference a UnitOfWork (via a change listener) within the shared cache.
     */
    public void testInvalidateAndRefreshEmbeddableParent() {
        // test depends on weaving
        if (!isWeavingEnabled()) {
            warning("Test depends on weaving and change tracking");
            return;
        }
        
        HockeyPuck puck = null;
        HockeyRink rink = null;
        
        // setup
        clearCache();
        
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            
            puck = new HockeyPuck();
            puck.setId(1);
            puck.setName("MrWraparound");
            puck.getSponsor().setName("ACME Cloud Computing Company, Inc.");
            puck.getSponsor().setSponsorshipValue(1000000);
            em.persist(puck);
            
            commitTransaction(em);
        } finally {
            closeEntityManager(em);
        }
        
        // test
        em = createEntityManager();
        try {
            // 1. invalidate existing Entity in the cache
            JpaHelper.getDatabaseSession(getEntityManagerFactory()).getIdentityMapAccessor().invalidateObject(puck.getId(), HockeyPuck.class);
            assertFalse("Existing cached HockeyPuck should not be valid", 
                JpaHelper.getDatabaseSession(getEntityManagerFactory()).getIdentityMapAccessor().isValid(puck.getId(), HockeyPuck.class));
            
            beginTransaction(em);
            
            // 2. create new Entity and persist
            rink = new HockeyRink();
            rink.setId(1);
            em.persist(rink);
            
            // 3. load existing Entity
            puck = em.createQuery("select object(p) from HockeyPuck p where p.id = " + puck.getId(), HockeyPuck.class).getSingleResult();
            assertNotNull("HockeyPuck loaded should not be null", puck);
            
            // 4. associate loaded existing Entity with persisted new Entity
            rink.setPuck(puck);
            
            commitTransaction(em);
        } finally {
            closeEntityManager(em);
        }
        
        // verify, go directly to the shared cache for the parent Entity
        try {
            HockeyPuck cachedPuck = (HockeyPuck)JpaHelper.getDatabaseSession(getEntityManagerFactory()).getIdentityMapAccessor().getFromIdentityMap(puck.getId(), HockeyPuck.class);
            HockeySponsor sponsor = cachedPuck.getSponsor();
            if (sponsor instanceof ChangeTracker) {
                PropertyChangeListener listener = ((ChangeTracker)sponsor)._persistence_getPropertyChangeListener();
                // listener can be null
                if (listener != null && listener instanceof AttributeChangeListener) {
                    assertNull("UnitOfWork referenced in Embeddable referenced by an object in the shared cache", ((AttributeChangeListener)listener).getUnitOfWork());
                }
            } else {
                fail("Config error: HockeyPuck/HockeySponsor is not change tracked");
            }
        } finally {
            // reset
            em = createEntityManager();
            beginTransaction(em);
            
            if (puck != null) {
                puck = em.find(HockeyPuck.class, puck.getId());
                if (puck != null) {
                    em.remove(puck);
                }
            }
            if (rink != null) {
                rink = em.find(HockeyRink.class, rink.getId());
                if (rink != null) {
                    em.remove(rink);
                }
            }
            
            commitTransaction(em);
            closeEntityManager(em);
        }
    }

}
