/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.openjpa.persistence.util; import java.sql.Date; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Random; import javax.persistence.EntityManager; import javax.persistence.PersistenceUnitUtil; import org.apache.openjpa.persistence.OpenJPAEntityManager; import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; import org.apache.openjpa.persistence.OpenJPAPersistence; import org.apache.openjpa.persistence.test.SingleEMFTestCase; public class TestPersistenceUnitUtil extends SingleEMFTestCase{ public void setUp() { setUp(CLEAR_TABLES, EagerEntity.class, LazyEmbed.class, LazyEntity.class, EagerEmbed.class, RelEntity.class, EagerEmbedRel.class, MapEntity.class, MapKeyEmbed.class, MapValEntity.class, OneToEntity.class, ToManyLazy.class, ToManyEager.class); } /* * Verifies an entity and its persistent attributes are in the proper * load state. */ public void testIsLoadedEager() { verifyIsLoadedEagerState(true); } /* * Verifies an entity and its persistent attributes are in the proper * not loaded state. */ public void testNotLoadedLazy() { verifyIsLoadedEagerState(false); } /* * Verifies an entity and its persistent attributes are in the proper * loaded state. */ public void testIsLoadedLazy() { verifyIsLoadedLazyState(true); } /* * Verifies an entity and its persistent attributes are in the proper * NOT_LOADED state. */ public void testNotLoadedEager() { verifyIsLoadedEagerState(false); } /** * Verifies the use of PersistenceUnitUtil with multiple PU's. */ public void testMultiplePUs() { OpenJPAEntityManagerFactorySPI emf1 = (OpenJPAEntityManagerFactorySPI)OpenJPAPersistence. createEntityManagerFactory("PUtil1", "org/apache/openjpa/persistence/util/" + "persistence.xml"); assertNotNull(emf1); OpenJPAEntityManagerFactorySPI emf2 = (OpenJPAEntityManagerFactorySPI)OpenJPAPersistence. createEntityManagerFactory("PUtil2", "org/apache/openjpa/persistence/util/" + "persistence.xml"); assertNotNull(emf2); assertNotSame(emf, emf1); assertNotSame(emf1, emf2); PersistenceUnitUtil puu = emf.getPersistenceUnitUtil(); PersistenceUnitUtil puu1 = emf1.getPersistenceUnitUtil(); PersistenceUnitUtil puu2 = emf2.getPersistenceUnitUtil(); assertNotSame(puu, puu1); assertNotSame(puu, puu2); assertNotSame(puu1, puu2); EntityManager em = emf.createEntityManager(); EntityManager em1 = emf1.createEntityManager(); EntityManager em2 = emf2.createEntityManager(); verifyPULoadState(em, puu, puu1, puu2); verifyPULoadState(em1, puu1, puu, puu2); verifyPULoadState(em2, puu2, puu, puu1); em.close(); em1.close(); em2.close(); if (emf1 != null) { emf1.close(); } if (emf2 != null) { emf2.close(); } } private void verifyPULoadState(EntityManager em, PersistenceUnitUtil...puu) { EagerEntity ee = createEagerEntity(); assertEquals(false, puu[0].isLoaded(ee)); assertEquals(false, puu[0].isLoaded(ee, "id")); assertEquals(false, puu[1].isLoaded(ee)); assertEquals(false, puu[1].isLoaded(ee, "id")); assertEquals(false, puu[2].isLoaded(ee)); assertEquals(false, puu[2].isLoaded(ee, "id")); em.getTransaction().begin(); em.persist(ee); em.getTransaction().commit(); assertEquals(true, puu[0].isLoaded(ee)); assertEquals(true, puu[0].isLoaded(ee, "id")); assertEquals(false, puu[1].isLoaded(ee)); assertEquals(false, puu[1].isLoaded(ee, "id")); assertEquals(false, puu[2].isLoaded(ee)); assertEquals(false, puu[2].isLoaded(ee, "id")); } private void verifyIsLoadedEagerState(boolean loaded) { PersistenceUnitUtil puu = emf.getPersistenceUnitUtil(); assertSame(emf, puu); EntityManager em = emf.createEntityManager(); EagerEntity ee = createEagerEntity(); // Vfy LoadState is false for the unmanaged entity assertEquals(false, puu.isLoaded(ee)); assertEquals(false, puu.isLoaded(ee, "id")); em.getTransaction().begin(); em.persist(ee); em.getTransaction().commit(); em.clear(); if (loaded) ee = em.find(EagerEntity.class, ee.getId()); else ee = em.getReference(EagerEntity.class, ee.getId()); assertEquals(loaded, puu.isLoaded(ee)); assertEquals(loaded, puu.isLoaded(ee, "id")); assertEquals(loaded, puu.isLoaded(ee, "name")); assertEquals(loaded, puu.isLoaded(ee, "eagerEmbed")); assertEquals(false, puu.isLoaded(ee, "transField")); em.close(); } private void verifyIsLoadedLazyState(boolean loaded) { PersistenceUnitUtil puu = emf.getPersistenceUnitUtil(); assertSame(emf, puu); EntityManager em = emf.createEntityManager(); LazyEntity le = createLazyEntity(); // Vfy LoadState is false for the unmanaged entity assertEquals(false, puu.isLoaded(le)); assertEquals(false, puu.isLoaded(le,"id")); em.getTransaction().begin(); em.persist(le); em.getTransaction().commit(); em.clear(); // Use find or getReference based upon expected state if (loaded) le = em.find(LazyEntity.class, le.getId()); else le = em.getReference(LazyEntity.class, le.getId()); assertEquals(loaded, puu.isLoaded(le)); assertEquals(loaded, puu.isLoaded(le, "id")); // Name is lazy fetch so it should not be loaded assertEquals(false, puu.isLoaded(le, "name")); assertEquals(loaded, puu.isLoaded(le, "lazyEmbed")); assertEquals(false, puu.isLoaded(le, "transField")); em.close(); } /* * Verifies that an entity and attributes are considered loaded if they * are assigned by the application. */ public void testIsApplicationLoaded() { PersistenceUnitUtil puu = emf.getPersistenceUnitUtil(); assertSame(emf, puu); EntityManager em = emf.createEntityManager(); EagerEntity ee = createEagerEntity(); em.getTransaction().begin(); em.persist(ee); em.getTransaction().commit(); em.clear(); ee = em.getReference(EagerEntity.class, ee.getId()); assertNotNull(ee); assertEagerLoadState(puu, ee, false); ee.setName("AppEagerName"); EagerEmbed emb = createEagerEmbed(); ee.setEagerEmbed(emb); // Assert fields are loaded via application loading assertEagerLoadState(puu, ee, true); // Vfy the set values are applied to the entity assertEquals("AppEagerName", ee.getName()); assertEquals(emb, ee.getEagerEmbed()); em.close(); } public void testPCMapEager() { PersistenceUnitUtil puu = emf.getPersistenceUnitUtil(); EntityManager em = emf.createEntityManager(); MapValEntity mve = new MapValEntity(); mve.setIntVal(10); MapKeyEmbed mke = new MapKeyEmbed(); mke.setFirstName("Jane"); mke.setLastName("Doe"); MapEntity me = new MapEntity(); assertEquals(false, puu.isLoaded(me)); assertEquals(false, puu.isLoaded(me, "mapValEntity")); assertEquals(false, puu.isLoaded(me, "mapEntities")); assertEquals(false, puu.isLoaded(mve)); // Create a circular ref me.setMapValEntity(mve); mve.setMapEntity(me); HashMap<MapKeyEmbed, MapValEntity> hm = new HashMap<MapKeyEmbed, MapValEntity>(); hm.put(mke, mve); me.setMapEntities(hm); em.getTransaction().begin(); em.persist(me); em.getTransaction().commit(); assertEquals(true, puu.isLoaded(me)); assertEquals(true, puu.isLoaded(me, "mapValEntity")); assertEquals(true, puu.isLoaded(me, "mapEntities")); assertEquals(true, puu.isLoaded(mve)); em.close(); } /* * Verify load state is not loaded for null relationships or relationships * set to null. */ public void testSetNullLazyRelationship() { PersistenceUnitUtil puu = emf.getPersistenceUnitUtil(); EntityManager em = emf.createEntityManager(); try { OneToEntity ote = new OneToEntity(); assertFalse(puu.isLoaded(ote, "toManyLazy")); em.getTransaction().begin(); em.persist(ote); em.getTransaction().commit(); em.clear(); ote = em.find(OneToEntity.class, ote.getId()); // Field is lazy and not immediately loaded by the application assertFalse(puu.isLoaded(ote, "toManyLazy")); // Force load the lazy field ote.getToManyLazy(); assertTrue(puu.isLoaded(ote, "toManyLazy")); OneToEntity ote2 = new OneToEntity(); em.getTransaction().begin(); em.persist(ote2); em.getTransaction().commit(); // Field gets set to loaded upon commit assertTrue(puu.isLoaded(ote2, "toManyLazy")); em.clear(); ote2 = em.find(OneToEntity.class, ote2.getId()); // Field is lazy and not immediately loaded by the application assertFalse(puu.isLoaded(ote2, "toManyLazy")); // Load by application List<ToManyLazy> tmes = new ArrayList<ToManyLazy>(); for (int i = 0; i < 5; i++) { tmes.add(new ToManyLazy("ToMany" + i)); } em.getTransaction().begin(); ote2.setToManyLazy(tmes); // App loaded before commit assertTrue(puu.isLoaded(ote2, "toManyLazy")); em.getTransaction().commit(); // Still loaded after commit assertTrue(puu.isLoaded(ote2, "toManyLazy")); // Set to null - still loaded per spec. em.getTransaction().begin(); ote2.setToManyLazy(null); // Considered loaded before commit assertTrue(puu.isLoaded(ote2, "toManyLazy")); em.getTransaction().commit(); //Loaded after commit assertTrue(puu.isLoaded(ote2, "toManyLazy")); } finally { if (em.getTransaction().isActive()) { em.getTransaction().rollback(); } } em.close(); } public void testSetNullEagerRelationship() { PersistenceUnitUtil puu = emf.getPersistenceUnitUtil(); EntityManager em = emf.createEntityManager(); try { OneToEntity ote = new OneToEntity(); assertFalse(puu.isLoaded(ote, "toManyEager")); em.getTransaction().begin(); em.persist(ote); em.getTransaction().commit(); em.clear(); ote = em.find(OneToEntity.class, ote.getId()); // Field is eager and is immediately loaded by the application assertTrue(puu.isLoaded(ote, "toManyEager")); OneToEntity ote2 = new OneToEntity(); em.getTransaction().begin(); em.persist(ote2); // Field is null by default, but after persist, it is treated as loaded. assertTrue(puu.isLoaded(ote2, "toManyEager")); em.getTransaction().commit(); // Field gets set to loaded upon commit assertTrue(puu.isLoaded(ote2, "toManyEager")); em.clear(); ote2 = em.find(OneToEntity.class, ote2.getId()); // Field is eager and is immediately loaded by the application assertTrue(puu.isLoaded(ote2, "toManyEager")); // Load by application List<ToManyEager> tmes = new ArrayList<ToManyEager>(); for (int i = 0; i < 5; i++) { tmes.add(new ToManyEager("ToMany" + i)); } em.getTransaction().begin(); ote2.setToManyEager(tmes); // App loaded before commit assertTrue(puu.isLoaded(ote2, "toManyEager")); em.getTransaction().commit(); // Still loaded after commit assertTrue(puu.isLoaded(ote2, "toManyEager")); // Set to null - still loaded per spec. em.getTransaction().begin(); ote2.setToManyEager(null); // Entity is considered loaded before commit assertTrue(puu.isLoaded(ote2)); // Attribute is considered loaded before commit assertTrue(puu.isLoaded(ote2, "toManyEager")); em.getTransaction().commit(); //Loaded after commit assertTrue(puu.isLoaded(ote2, "toManyEager")); } finally { if (em.getTransaction().isActive()) { em.getTransaction().rollback(); } } em.close(); } public void testBasicTypeNotLoaded() { PersistenceUnitUtil puu = emf.getPersistenceUnitUtil(); EntityManager em = emf.createEntityManager(); EagerEntity ee = createEagerEntity(); int id = ee.getId(); em.getTransaction().begin(); em.persist(ee); em.getTransaction().commit(); em.clear(); // name is not eagerly loaded, only eagerEmbed is eagerly loaded OpenJPAEntityManager kem = OpenJPAPersistence.cast(em); kem.getFetchPlan().resetFetchGroups().removeFetchGroup("default") .addField(EagerEntity.class, "eagerEmbed"); ee = em.find(EagerEntity.class, id); assertEquals(true, puu.isLoaded(ee)); } private EagerEntity createEagerEntity() { EagerEntity ee = new EagerEntity(); ee.setId(new Random().nextInt()); ee.setName("EagerEntity"); EagerEmbed emb = createEagerEmbed(); ee.setEagerEmbed(emb); return ee; } private EagerEmbed createEagerEmbed() { EagerEmbed emb = new EagerEmbed(); emb.setEndDate(new Date(System.currentTimeMillis())); emb.setStartDate(new Date(System.currentTimeMillis())); return emb; } private LazyEntity createLazyEntity() { LazyEntity le = new LazyEntity(); le.setId(new Random().nextInt()); le.setName("LazyEntity"); LazyEmbed emb = new LazyEmbed(); emb.setEndDate(new Date(System.currentTimeMillis())); emb.setStartDate(new Date(System.currentTimeMillis())); le.setLazyEmbed(emb); RelEntity re = new RelEntity(); re.setName("My ent"); ArrayList<RelEntity> rel = new ArrayList<RelEntity>(); rel.add(new RelEntity()); return le; } private void assertEagerLoadState(PersistenceUnitUtil pu, Object ent, boolean state) { assertEquals(state, pu.isLoaded(ent)); assertEquals(state, pu.isLoaded(ent, "id")); assertEquals(state, pu.isLoaded(ent, "name")); assertEquals(state, pu.isLoaded(ent, "eagerEmbed")); assertEquals(false, pu.isLoaded(ent, "transField")); } }