/*
 * Copyright (c) 1998, 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 from Oracle TopLink
//     04/07/2012-2.5 Guy Pelletier
//       - 384275: Customizer from a mapped superclass is not overridden by an entity customizer
package org.eclipse.persistence.testing.tests.jpa.inheritance;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.persistence.config.HintValues;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.invalidation.TimeToLiveCacheInvalidationPolicy;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.indirection.IndirectList;
import org.eclipse.persistence.indirection.IndirectSet;
import org.eclipse.persistence.mappings.CollectionMapping;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.testing.models.jpa.inheritance.AAA;
import org.eclipse.persistence.testing.models.jpa.inheritance.Betta;
import org.eclipse.persistence.testing.models.jpa.inheritance.Bicycle;
import org.eclipse.persistence.testing.models.jpa.inheritance.Bus;
import org.eclipse.persistence.testing.models.jpa.inheritance.CitrusFruit;
import org.eclipse.persistence.testing.models.jpa.inheritance.Company;
import org.eclipse.persistence.testing.models.jpa.inheritance.DDD;
import org.eclipse.persistence.testing.models.jpa.inheritance.Fish;
import org.eclipse.persistence.testing.models.jpa.inheritance.FishTank;
import org.eclipse.persistence.testing.models.jpa.inheritance.InheritanceTableCreator;
import org.eclipse.persistence.testing.models.jpa.inheritance.PerformanceTireInfo;
import org.eclipse.persistence.testing.models.jpa.inheritance.Seed;
import org.eclipse.persistence.testing.models.jpa.inheritance.SeededFruit;
import org.eclipse.persistence.testing.models.jpa.inheritance.SeniorEngineer;
import org.eclipse.persistence.testing.models.jpa.inheritance.SportsCar;
import org.eclipse.persistence.testing.models.jpa.inheritance.Car;
import org.eclipse.persistence.testing.models.jpa.inheritance.Person;
import org.eclipse.persistence.testing.models.jpa.inheritance.PetStore;
import org.eclipse.persistence.testing.models.jpa.inheritance.Engineer;
import org.eclipse.persistence.testing.models.jpa.inheritance.Computer;
import org.eclipse.persistence.testing.models.jpa.inheritance.ComputerPK;
import org.eclipse.persistence.testing.models.jpa.inheritance.Desktop;
import org.eclipse.persistence.testing.models.jpa.inheritance.Laptop;
import org.eclipse.persistence.testing.models.jpa.inheritance.TireInfo;
import org.eclipse.persistence.testing.models.jpa.inheritance.VehicleDirectory;

import junit.framework.Test;
import junit.framework.TestSuite;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceException;
import jakarta.persistence.Query;

public class EntityManagerJUnitTestCase extends JUnitTestCase {

    public EntityManagerJUnitTestCase() {
        super();
    }

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

    public static Test suite() {
        TestSuite suite = new TestSuite();
        suite.setName("EntityManagerJUnitTestCase");
        suite.addTest(new EntityManagerJUnitTestCase("testSetup"));
        suite.addTest(new EntityManagerJUnitTestCase("testOverriddenCustomizer"));
        suite.addTest(new EntityManagerJUnitTestCase("testAddToUninstantiatedSet"));
        suite.addTest(new EntityManagerJUnitTestCase("testAddDuplicateToUninstantiatedSet"));
        suite.addTest(new EntityManagerJUnitTestCase("testAssociationWithEmbeddedIdSubclassEntityInJoinedStrategy"));
        suite.addTest(new EntityManagerJUnitTestCase("testGenericCollectionOnSuperclass"));
        suite.addTest(new EntityManagerJUnitTestCase("testLazyListInstantiationEager"));
        suite.addTest(new EntityManagerJUnitTestCase("testLazyListInstantiationLazy"));
        suite.addTest(new EntityManagerJUnitTestCase("testLazySetInstantiationEager"));
        suite.addTest(new EntityManagerJUnitTestCase("testMapKeyInheritance"));
        suite.addTest(new EntityManagerJUnitTestCase("testPersistPolymorphicRelationship"));
        suite.addTest(new EntityManagerJUnitTestCase("testRemoveInheritedManyToMany"));
        suite.addTest(new EntityManagerJUnitTestCase("testUpateTireInfo"));
        suite.addTest(new EntityManagerJUnitTestCase("testUpateTireInfo"));
        // EL bug 336486
        suite.addTest(new EntityManagerJUnitTestCase("testCacheExpiryInitializationForInheritance"));
        // Bug 404071
        suite.addTest(new EntityManagerJUnitTestCase("testJoinedInheritanceOneToManyJoinFetch"));
        // Bug 415526
        suite.addTest(new EntityManagerJUnitTestCase("testCascadeMergeWithTargetInheritance"));
        // Bug 458177
        suite.addTest(new EntityManagerJUnitTestCase("testJoinedInheritanceWithAbstractSuperclass"));
        // Bug 355721
        suite.addTest(new EntityManagerJUnitTestCase("testJoinedInheritancePersistWithReadOnlyEntity"));

        return suite;
    }

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

    // gf issue 1356 - persisting a polymorphic relationship throws a NPE.
    // The order of persist operations is important for this test.
    public void testPersistPolymorphicRelationship() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Person p = new Person();
        p.setName("Evil Knievel");

        Car c = new SportsCar();
        c.setDescription("Ferrari");
        ((SportsCar) c).setMaxSpeed(200);
        p.setCar(c);

        try {
            em.persist(c);
            em.persist(p);
            commitTransaction(em);

        } catch (Exception exception ) {
            fail("Error persisting polymorphic relationship: " + exception.getMessage());
        } finally {
            closeEntityManager(em);
        }
    }

    public void testCacheExpiryInitializationForInheritance() {
        ServerSession session = JUnitTestCase.getServerSession();

        ClassDescriptor personDescriptor = session.getDescriptor(Person.class); // parent
        ClassDescriptor engineerDescriptor = session.getDescriptor(Engineer.class); // subclass
        ClassDescriptor seniorEngineerDescriptor = session.getDescriptor(SeniorEngineer.class); // subclass of subclass

        // Policy existence check
        assertNotNull("personDescriptor's cacheInvalidationPolicy should not be null",
                personDescriptor.getCacheInvalidationPolicy());
        assertNotNull("engineerDescriptor's cacheInvalidationPolicy should not be null",
                engineerDescriptor.getCacheInvalidationPolicy());
        assertNotNull("seniorEngineerDescriptor's cacheInvalidationPolicy should not be null",
                seniorEngineerDescriptor.getCacheInvalidationPolicy());

        // Policy class check
        assertTrue("personDescriptor's cacheInvalidationPolicy should be TimeToLiveCacheInvalidationPolicy",
                personDescriptor.getCacheInvalidationPolicy() instanceof TimeToLiveCacheInvalidationPolicy);
        assertTrue("engineerDescriptor's cacheInvalidationPolicy should be TimeToLiveCacheInvalidationPolicy",
                engineerDescriptor.getCacheInvalidationPolicy() instanceof TimeToLiveCacheInvalidationPolicy);
        assertTrue("seniorEngineerDescriptor's cacheInvalidationPolicy should be TimeToLiveCacheInvalidationPolicy",
                seniorEngineerDescriptor.getCacheInvalidationPolicy() instanceof TimeToLiveCacheInvalidationPolicy);

        // Subclass clone check
        assertFalse("engineerDescriptor's cacheInvalidationPolicy should be a clone",
                engineerDescriptor.getCacheInvalidationPolicy() == personDescriptor.getCacheInvalidationPolicy());
        assertFalse("seniorEngineerDescriptor's cacheInvalidationPolicy should be a clone",
                seniorEngineerDescriptor.getCacheInvalidationPolicy() == personDescriptor.getCacheInvalidationPolicy());

        // Subclass TTL check
        long ttl = ((TimeToLiveCacheInvalidationPolicy)personDescriptor.getCacheInvalidationPolicy()).getTimeToLive();
        assertEquals("engineerDescriptor's invalidation TTL should be " + ttl,
                ttl, ((TimeToLiveCacheInvalidationPolicy)engineerDescriptor.getCacheInvalidationPolicy()).getTimeToLive());
        assertEquals("seniorEngineerDescriptor's invalidation TTL should be " + ttl,
                ttl, ((TimeToLiveCacheInvalidationPolicy)seniorEngineerDescriptor.getCacheInvalidationPolicy()).getTimeToLive());
    }

    /**
     * Verifies that alias name is not customized from an invalid customizer.
     */
    public void testOverriddenCustomizer() {
        ServerSession session = JUnitTestCase.getServerSession();

        ClassDescriptor computerDescriptor = session.getDescriptor(Computer.class);
        assertFalse("Computer alias was incorrect", computerDescriptor.getAlias().equals("InvalidAliasName"));
    }

    // test if we can associate with a subclass entity
    // whose root entity has EmbeddedId in Joined inheritance strategy
    // Issue: GF#1153 && GF#1586 (desktop amendment)
    public void testAssociationWithEmbeddedIdSubclassEntityInJoinedStrategy() {
        EntityManager em = createEntityManager();
        beginTransaction(em);

        try {
            Engineer engineer = new Engineer();
            em.persist(engineer);

            ComputerPK laptopPK = new ComputerPK("Dell", 10001);
            Laptop laptop = em.find(Laptop.class, laptopPK);
            if (laptop == null){
                laptop = new Laptop(laptopPK);
                em.persist(laptop);
            }

            ComputerPK desktopPK = new ComputerPK("IBM", 10002);
            Desktop desktop = em.find(Desktop.class, desktopPK);
            if (desktop == null){
                desktop = new Desktop(desktopPK);
                em.persist(desktop);
            }

            // associate many-to-many relationships
            engineer.getLaptops().add(laptop);
            engineer.getDesktops().add(desktop);

            commitTransaction(em);
        } catch(RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }

            throw ex;
        } finally {
            closeEntityManager(em);
        }
    }

    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=241979
    public void testUpateTireInfo(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        TireInfo tireInfo = new TireInfo();
        tireInfo.setPressure(35);
        em.persist(tireInfo);
        commitTransaction(em);

        beginTransaction(em);
        TireInfo localTire = em.find(TireInfo.class, tireInfo.getId());
        assertTrue("TireInfo was not persisted with the proper pressure", localTire.getPressure().equals(35));
        localTire.setPressure(40);
        commitTransaction(em);
        em.clear();

        localTire = em.find(TireInfo.class, tireInfo.getId());
        assertTrue("TireInfo was not updated", localTire.getPressure().equals(40));
    }

    //https://bugs.eclipse.org/bugs/show_bug.cgi?id=312253
    // Note: this test will potentially fail in a number of different ways
    // see the above bug for details of the non-derminism
    // also: This test only tests the above bug when weaving is disabled
    // also note: This test is testing for exceptions on the final flush, that
    // is why where are no asserts
    public void testMapKeyInheritance(){
        EntityManager em = createEntityManager();
        beginTransaction(em);

        VehicleDirectory directory = new VehicleDirectory();
        directory.setName("MyVehicles");
        em.persist(directory);

        Company company = new Company();
        company.setName("A Blue Company");
        em.persist(company);
        em.flush();

        Car car = new Car();
        car.setDescription("a Blue Car");
        car.setOwner(company);
        em.persist(car);

        directory.getVehicleDirectory().put(car.getOwner(), car);
        company.getVehicles().add(car);

        try{
            em.flush();
        } catch(RuntimeException e){
            fail("Exception was thrown while flushing a MapKey with inheritance. " + e.getMessage());
        }

        rollbackTransaction(em);;
    }

    public void testRemoveInheritedManyToMany(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            SeniorEngineer eng = new SeniorEngineer();
            eng.setName("Vela");
            em.persist(eng);
            Laptop laptop = new Laptop();
            ComputerPK pk = new ComputerPK("Dell", 2111);
            laptop.setComputerPK(pk);
            em.persist(laptop);
            eng.getLaptops().add(laptop);
            em.flush();

            em.remove(eng);
            em.flush();
        } catch (PersistenceException ex){
            if (ex.getCause() instanceof DatabaseException){
                // An Integrity Constraint Violation was the reason for the initial exception
                fail("SQLException thrown when removing an object that inherits a ManyToMany");
            } else {
                fail("UnexpectedException thrown");
            }
        } finally {
            rollbackTransaction(em);
        }
    }

    // Bug 336133
    public void testGenericCollectionOnSuperclass(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Bus bus = new Bus();
            bus.setDescription("a fast bus");
            PerformanceTireInfo tire = new PerformanceTireInfo();
            tire.setPressure(100);
            bus.getTires().add(tire);
            em.persist(bus);
            em.flush();

            em.clear();
            clearCache();

            bus = em.find(Bus.class, bus.getId());
            assertNotNull("Bus is null.", bus);
            assertTrue("Bus has no tires.", bus.getTires().size() == 1);
        } finally {
            rollbackTransaction(em);
        }

    }

    // bug 325035
    public void testAddToUninstantiatedSet(){
        EntityManager em = createEntityManager();
        beginTransaction(em);

        AAA a = new AAA();
        em.persist(a);

        DDD d = new DDD();
        em.persist(d);

        Set<DDD> ds = new HashSet<DDD>();
        ds.add(d);
        a.setDdds(ds);
        d.setAaa(a);
        commitTransaction(em);

        clearCache();
        try{
            em = createEntityManager();
            beginTransaction(em);
            a = em.getReference(AAA.class, a.getId());
            a.getDdds().add(d);
            d.setAaa(a);
            commitTransaction(em);

            assertTrue("The collection contains too many elements", a.getDdds().size() == 1);

        } finally  {
            em = createEntityManager();
            beginTransaction(em);
            a = em.find(AAA.class, a.getId());
            d = em.find(DDD.class, d.getId());
            em.remove(a);
            em.remove(d);
            commitTransaction(em);
        }
    }

     // bug391833 - Duplicate insert on lazy set with attribute change tracking
    public void testAddDuplicateToUninstantiatedSet(){
        String string1 = "String1";
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            AAA a = new AAA();
            Set<String> ds = new HashSet<String>();
            ds.add(string1);
            a.setStringSet(ds);

            em.persist(a);

            em.flush();
            em.clear();

            a = em.find(AAA.class, a.getId());
            em.refresh(a);
            a.getStringSet().add(string1);

            em.flush();

            assertTrue("The collection contains too many elements", a.getStringSet().size() == 1);

            java.util.List results = em.createQuery("select s from AAA a join a.stringSet s where a.id = "+a.getId()).getResultList();
            assertTrue("The Database contains too many elements", results.size() == 1);
        } finally  {
            if (this.isTransactionActive(em)) {
                this.rollbackTransaction(em);
            }
            this.closeEntityManager(em);
        }
    }

    // bug 325035
    public void testLazySetInstantiationLazy(){
        if (!isWeavingEnabled()){
            return;
        }
        EntityManager em = createEntityManager();
        CollectionMapping mapping = ((CollectionMapping)getServerSession().getProject().getClassDescriptor(AAA.class).getMappingForAttributeName("ddds"));
        Boolean lazyIndirection = mapping.shouldUseLazyInstantiationForIndirectCollection();
        mapping.setUseLazyInstantiationForIndirectCollection(true);
        beginTransaction(em);

        AAA a = new AAA();
        em.persist(a);

        DDD d = new DDD();
        em.persist(d);

        Set<DDD> ds = new HashSet<DDD>();
        ds.add(d);
        a.setDdds(ds);
        d.setAaa(a);
        commitTransaction(em);

        clearCache();
        try{
            em = createEntityManager();
            a = em.find(AAA.class, a.getId());
            a.getDdds().add(new DDD());

            assertTrue("Lazy instantiation was not enabled for IndirectSet.", ((IndirectSet)a.getDdds()).getAddedElements().size() == 1);

        } finally  {
            em = createEntityManager();
            beginTransaction(em);
            a = em.find(AAA.class, a.getId());
            d = em.find(DDD.class, d.getId());
            em.remove(a);
            em.remove(d);
            commitTransaction(em);
            mapping.setUseLazyInstantiationForIndirectCollection(lazyIndirection);
        }
    }

    // bug 325035
    public void testLazySetInstantiationEager(){
        EntityManager em = createEntityManager();
        beginTransaction(em);

        AAA a = new AAA();
        em.persist(a);

        DDD d = new DDD();
        em.persist(d);

        Set<DDD> ds = new HashSet<DDD>();
        ds.add(d);
        a.setDdds(ds);
        d.setAaa(a);
        commitTransaction(em);

        clearCache();
        try{
            em = createEntityManager();
            a = em.find(AAA.class, a.getId());
            a.getDdds().add(new DDD());

            assertTrue("Lazy instantiation was not disabled for IndirectSet.", ((IndirectSet)a.getDdds()).getAddedElements().size() == 0);

        } finally  {
            em = createEntityManager();
            beginTransaction(em);
            a = em.find(AAA.class, a.getId());
            d = em.find(DDD.class, d.getId());
            em.remove(a);
            em.remove(d);
            commitTransaction(em);
        }
    }

    // bug 325035
    public void testLazyListInstantiationLazy(){
        if (!isWeavingEnabled()){
            return;
        }
        EntityManager em = createEntityManager();
        beginTransaction(em);

        Company company = new Company();
        company.setName("ListCo");
        em.persist(company);

        Car car = new Car();
        em.persist(car);

        company.getVehicles().add(car);
        car.setOwner(company);

        commitTransaction(em);

        clearCache();
        try{
            em = createEntityManager();
            company = em.find(Company.class, company.getId());
            company.getVehicles().add(new Car());

            assertTrue("Lazy instantiation was not enabled for IndirectList.", ((IndirectList)company.getVehicles()).getAddedElements().size() == 1);

        } finally  {
            em = createEntityManager();
            beginTransaction(em);
            company = em.find(Company.class, company.getId());
            car = em.find(Car.class, car.getId());
            em.remove(company);
            em.remove(car);
            commitTransaction(em);
        }
    }

    // bug 325035
    public void testLazyListInstantiationEager(){
        EntityManager em = createEntityManager();
        CollectionMapping mapping = ((CollectionMapping)getServerSession().getProject().getClassDescriptor(Company.class).getMappingForAttributeName("vehicles"));
        Boolean lazyIndirection = mapping.shouldUseLazyInstantiationForIndirectCollection();
        mapping.setUseLazyInstantiationForIndirectCollection(false);
        beginTransaction(em);

        Company company = new Company();
        company.setName("ListCo");
        em.persist(company);

        Car car = new Car();
        em.persist(car);

        company.getVehicles().add(car);
        car.setOwner(company);

        commitTransaction(em);

        clearCache();
        try{
            em = createEntityManager();
            company = em.find(Company.class, company.getId());
            company.getVehicles().add(new Car());

            assertTrue("Lazy instantiation was not disabled for IndirectList.", ((IndirectList)company.getVehicles()).getAddedElements().size() == 0);

        } finally  {
            em = createEntityManager();
            beginTransaction(em);
            company = em.find(Company.class, company.getId());
            car = em.find(Car.class, car.getId());
            em.remove(company);
            em.remove(car);
            commitTransaction(em);
            mapping.setUseLazyInstantiationForIndirectCollection(lazyIndirection);
        }
    }

    // Bug 404071
    public void testJoinedInheritanceOneToManyJoinFetch() {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            CitrusFruit fruit = new CitrusFruit();
            fruit.setName("Orange");
            fruit.setGrade(1);
            for (int i = 0; i < 4; i++) {
                fruit.addSeed(new Seed());
            }
            em.persist(fruit);

            commitTransaction(em);
            em.clear();
            clearCache();

            // query on superclass
            SeededFruit fruitRead = em.find(SeededFruit.class, fruit.getId());

            assertNotNull("Fruit should not be null", fruitRead);
            assertNotNull("Fruit's seeds should not be null", fruitRead.getSeeds());
            assertTrue("Fruit's seeds should contain 4 elements", fruitRead.getSeeds().size() == 4);
        } finally {
            closeEntityManager(em);
        }
    }

    // Bug 415526
    public void testCascadeMergeWithTargetInheritance() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            Company company = new Company();
            company.setName("CascadeMerge, Inc");
            em.persist(company);
            em.flush();

            Bicycle bicycle = new Bicycle();
            bicycle.setDescription("road bike");
            company.getVehicles().add(bicycle);
            bicycle.setOwner(company);
            company = em.merge(company);
            em.flush();

            Number bicycleId = company.getVehicles().iterator().next().getId();
            String classDiscriminatorValue = (String)em.createNativeQuery("SELECT VEH_TYPE FROM CMP3_VEHICLE WHERE ID = " + bicycleId).getSingleResult();

            if (classDiscriminatorValue == null) {
                fail("Class discriminator value written into the db for the merged Bicycle is null");
            }
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
    }

    /*
     * Added for Bug 458177
     * - Instantiate a FishTank, unidirectionally lazy-referencing an
     *   abstract Entity (Fish). Persist.
     * - Instantiate a Betta (concrete extension of Fish) and reference
     *   from FishTank's 'fishes' collection. Persist and commit.
     * - Acquire new EM and retrieve cached FishTank. Remove Entity.
     * - This 'simple' operation previously attempted to instantiate the abstract
     *   Fish class during UOW resume (Resulting in InstantiationException).
     */
    public void testJoinedInheritanceWithAbstractSuperclass() {
        Long tankId = null;
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            Betta fish = new Betta();
            fish.setName("swimmy");
            fish.setColor("blue");

            em.persist(fish);

            FishTank fishTank = new FishTank();
            List<Fish> list = new ArrayList<Fish>();
            list.add(fish);
            fishTank.setFishes(list);

            em.persist(fishTank);

            tankId = fishTank.getId();

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

        assertNotNull("FishTank ID should not be null", tankId);

        em = createEntityManager();
        try {
            beginTransaction(em);
            FishTank fishTank = em.find(FishTank.class, tankId);
            assertNotNull("FishTank should not be null", fishTank);

            em.remove(fishTank);

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

    /*
     * Added for Bug 355721
     * - Instantiate and persist (but do not associate) a FishTank Entity and
     *   PetStore Entity.
     * - Clear the EMF cache
     * - Acquire new EM and retrieve the PetStore Entity
     * - Retrieve all FishTank Entities with a RO NamedQuery
     * - Associate the PetStore (lazy unidirectional 1:M) with a FishTank, persist.
     * - This operation previously failed with a ClassCastException.
     */
    public void testJoinedInheritancePersistWithReadOnlyEntity() {
        EntityManager em = createEntityManager();
        Long petStoreId = null;

        try {
            beginTransaction(em);

            FishTank fishTank = new FishTank();
            em.persist(fishTank);

            PetStore petStore = new PetStore();
            petStore.setStoreName("Bob's Fish");
            petStore.setFishTanks(new ArrayList<FishTank>());

            em.persist(petStore);
            petStoreId = petStore.getId();

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

        // cache clear is necessary (reset lazy loading)
        getEntityManagerFactory().getCache().evictAll();

        em = createEntityManager();
        try {
            beginTransaction(em);

            PetStore petStore = em.find(PetStore.class, petStoreId);

            Query query = em.createNamedQuery("findAllFishTanks");
            query.setHint(QueryHints.READ_ONLY, HintValues.TRUE);

            List<FishTank> allFishTanks = query.getResultList();
            FishTank fishTank = allFishTanks.get(0);

            // add read-only entity to referencing unidirectional relationship
            petStore.getFishTanks().add(fishTank);
            em.persist(petStore);

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

}
