| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * Copyright (c) 1998, 2018 IBM Corporation. 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: |
| // 06/16/2009-2.0 Guy Pelletier |
| // - 277039: JPA 2.0 Cache Usage Settings |
| // 07/16/2009-2.0 Guy Pelletier |
| // - 277039: JPA 2.0 Cache Usage Settings |
| // 06/09/2010-2.0.3 Guy Pelletier |
| // - 313401: shared-cache-mode defaults to NONE when the element value is unrecognized |
| // 06/19/2014-2.6: - Tomas Kraus (Oracle) |
| // - 437578: Tests to verify @Cacheable inheritance in JPA 2.1 |
| // 12/03/2015-2.6 Dalia Abo Sheasha |
| // - 483582: Add the jakarta.persistence.sharedCache.mode property |
| package org.eclipse.persistence.testing.tests.jpa.cacheable; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import jakarta.persistence.Cache; |
| import jakarta.persistence.CacheRetrieveMode; |
| import jakarta.persistence.CacheStoreMode; |
| import jakarta.persistence.Cacheable; |
| import jakarta.persistence.EntityManager; |
| import jakarta.persistence.EntityManagerFactory; |
| import jakarta.persistence.EntityTransaction; |
| import jakarta.persistence.Query; |
| |
| import junit.framework.*; |
| |
| import org.eclipse.persistence.config.CacheUsage; |
| import org.eclipse.persistence.config.EntityManagerProperties; |
| import org.eclipse.persistence.config.HintValues; |
| import org.eclipse.persistence.config.PersistenceUnitProperties; |
| import org.eclipse.persistence.config.QueryHints; |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.expressions.ExpressionBuilder; |
| import org.eclipse.persistence.indirection.IndirectList; |
| import org.eclipse.persistence.mappings.DatabaseMapping; |
| import org.eclipse.persistence.mappings.ObjectReferenceMapping; |
| import org.eclipse.persistence.sessions.server.ServerSession; |
| import org.eclipse.persistence.testing.framework.QuerySQLTracker; |
| import org.eclipse.persistence.testing.framework.junit.JUnitTestCase; |
| import org.eclipse.persistence.testing.framework.junit.JUnitTestCaseHelper; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableFalseDetail; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableFalseDetailWithBackPointer; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableFalseEntity; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableForceProtectedEntity; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableProtectedEntity; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableTableCreator; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableTrueDerivedIDEntity; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableTrueDerivedIDPK; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableTrueEntity; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.ChildCacheableFalseEntity; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.ForceProtectedEntityWithComposite; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.ProductFalse; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.ProductHardwareFalse; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.ProductHardwareTrue; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.ProductSoftwareFalse; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.ProductSoftwareTrue; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.ProductTrue; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.ProtectedEmbeddable; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.ProtectedRelationshipsEntity; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.SharedEmbeddable; |
| import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableRelationshipsEntity; |
| |
| /* |
| * By default the tests in this suite assume the "DISABLE_SELECTIVE" persistence |
| * unit. |
| * |
| * If you want to test against a different PU be sure to ask for it accordingly. |
| * |
| * The list of Cacheable PU's available are: |
| * "NONE" |
| * "ALL" |
| * "ENABLE_SELECTIVE" |
| * "DISABLE_SELECTIVE" |
| * "UNSPECIFIED" |
| */ |
| public class CacheableModelJunitTest extends JUnitTestCase { |
| protected static int m_cacheableTrueEntity1Id; |
| protected static int m_cacheableForceProtectedEntity1Id; |
| protected static int m_cacheableTrueEntity2Id; |
| protected static int m_childCacheableFalseEntityId; |
| protected static int m_cacheableProtectedEntityId; |
| protected static int m_forcedProtectedEntityCompositId; |
| protected static int m_cacheableRelationshipsEntityId; |
| |
| public CacheableModelJunitTest() { |
| super(); |
| } |
| |
| public CacheableModelJunitTest(String name) { |
| super(name); |
| } |
| |
| /** |
| * Convenience method. Default PU is DISABLE_SELETIVE |
| */ |
| public void clearDSCache() { |
| clearCache("DISABLE_SELECTIVE"); |
| } |
| |
| /** |
| * Convenience method. |
| */ |
| public void closeEM(EntityManager em) { |
| if (em.isOpen()) { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Convenience method. |
| */ |
| public EntityManager createDSEntityManager() { |
| return createEntityManager("DISABLE_SELECTIVE"); |
| } |
| |
| /** |
| * Convenience method - Executes a straight up find on the EM provided or |
| * a new one. |
| */ |
| protected CacheableTrueEntity findCacheableTrueEntity(EntityManager em, int id) { |
| if (em == null) { |
| EntityManager myEm = createDSEntityManager(); |
| CacheableTrueEntity entity = myEm.find(CacheableTrueEntity.class, id); |
| closeEM(myEm); |
| return entity; |
| } else { |
| return em.find(CacheableTrueEntity.class, id); |
| } |
| } |
| |
| /** |
| * Convenience method - Executes the select query using retrieve BYPASS |
| * and store BYPASS on a new entity manager or the one provided. |
| */ |
| protected CacheableTrueEntity findCacheableTrueEntity_BYPASS_BYPASS(EntityManager em, int id) { |
| return findCacheableTrueEntityUsingQuery(em, "findCacheableTrueEntityByPK_BYPASS_BYPASS", id); |
| } |
| |
| /** |
| * Convenience method - Executes the select query using retrieve BYPASS |
| * and store USE on a new entity manager or the one provided. |
| */ |
| protected CacheableTrueEntity findCacheableTrueEntity_BYPASS_USE(EntityManager em, int id) { |
| return findCacheableTrueEntityUsingQuery(em, "findCacheableTrueEntityByPK_RETRIEVE_BYPASS_STORE_USE", id); |
| } |
| |
| /** |
| * Convenience method - Executes the select query using retrieve USE |
| * and store BYPASS on a new entity manager or the one provided. |
| */ |
| protected CacheableTrueEntity findCacheableTrueEntity_USE_BYPASS(EntityManager em, int id) { |
| return findCacheableTrueEntityUsingQuery(em, "findCacheableTrueEntityByPK_RETRIEVE_USE_STORE_BYPASS", id); |
| } |
| |
| /** |
| * Convenience method - Executes the select query on a new entity manager |
| * or the one provided. |
| */ |
| protected CacheableTrueEntity findCacheableTrueEntityUsingQuery(EntityManager em, String query, int id) { |
| CacheableTrueEntity entity = null; |
| |
| EntityManager emToUse; |
| if (em == null) { |
| // Create a new EM ... |
| emToUse = createDSEntityManager(); |
| } else { |
| // Use the em provided but do not close it. |
| emToUse = em; |
| } |
| |
| try { |
| boolean commit = false; |
| if (!isTransactionActive(emToUse)) { |
| beginTransaction(emToUse); |
| commit = true; |
| } |
| entity = (CacheableTrueEntity) emToUse.createNamedQuery(query).setParameter("id", id).getSingleResult(); |
| if (commit) { |
| commitTransaction(emToUse); |
| } |
| } catch (Exception e) { |
| fail("Error executing query: " + e); |
| } finally { |
| if (em == null) { |
| closeEM(emToUse); |
| } |
| } |
| |
| return entity; |
| } |
| |
| /** |
| * Convenience method. |
| */ |
| public ServerSession getDSServerSession() { |
| return getPUServerSession("DISABLE_SELECTIVE"); |
| } |
| |
| /** |
| * Convenience method. |
| */ |
| public ServerSession getPUServerSession(String puName) { |
| return JUnitTestCase.getServerSession(puName); |
| } |
| |
| /** |
| * Convenience method. |
| */ |
| public ServerSession getPUServerSession(String puName, Map properties) { |
| return JUnitTestCase.getServerSession(puName, properties); |
| } |
| |
| @Override |
| public void setUp() { |
| clearDSCache(); |
| } |
| |
| public static Test suite() { |
| TestSuite suite = new TestSuite(); |
| suite.setName("CacheableModelJunitTest"); |
| |
| if (! JUnitTestCase.isJPA10()) { |
| suite.addTest(new CacheableModelJunitTest("testSetup")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnALL")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnALLProperty")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnNONE")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnNONEProperty")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnNONEPropertyEMF")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnNONEPropertyConflict")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnENABLE_SELECTIVE")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnENABLE_SELECTIVEProperty")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnDISABLE_SELECTIVE")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnDISABLE_SELECTIVEProperty")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnUNSPECIFIED")); |
| suite.addTest(new CacheableModelJunitTest("testCachingOnUNSPECIFIEDProperty")); |
| |
| // Test cache retrieve mode of BYPASS and USE through the EM. |
| suite.addTest(new CacheableModelJunitTest("testCreateEntities")); |
| |
| suite.addTest(new CacheableModelJunitTest("testFindWithEMProperties")); |
| suite.addTest(new CacheableModelJunitTest("testFindWithFindProperties")); |
| |
| suite.addTest(new CacheableModelJunitTest("testRefreshWithEMProperties")); |
| suite.addTest(new CacheableModelJunitTest("testRefreshWithRefreshProperties")); |
| |
| // Test various usage scenarios .. |
| suite.addTest(new CacheableModelJunitTest("testRetrieveBYPASSStoreUSE1")); |
| suite.addTest(new CacheableModelJunitTest("testRetrieveBYPASSStoreUSE2")); |
| suite.addTest(new CacheableModelJunitTest("testRetrieveUSEStoreBYPASS1")); |
| suite.addTest(new CacheableModelJunitTest("testRetrieveUSEStoreBYPASS2")); |
| suite.addTest(new CacheableModelJunitTest("testRetrieveBYPASSStoreBYPASS1")); |
| suite.addTest(new CacheableModelJunitTest("testRetrieveBYPASSStoreBYPASS2")); |
| suite.addTest(new CacheableModelJunitTest("testMultipleEMQueries")); |
| suite.addTest(new CacheableModelJunitTest("testEMPropertiesOnCommit1")); |
| suite.addTest(new CacheableModelJunitTest("testEMPropertiesOnCommit2")); |
| suite.addTest(new CacheableModelJunitTest("testInheritanceCacheable")); |
| |
| suite.addTest(new CacheableModelJunitTest("testDetailsOrder_Isolated")); |
| suite.addTest(new CacheableModelJunitTest("testDetailsOrder_Isolated_BeginEarlyTransaction")); |
| suite.addTest(new CacheableModelJunitTest("testDetailsOrder_Shared")); |
| suite.addTest(new CacheableModelJunitTest("testDetailsOrder_Shared_BeginEarlyTransaction")); |
| suite.addTest(new CacheableModelJunitTest("testLoadMixedCacheTree")); |
| suite.addTest(new CacheableModelJunitTest("testIsolatedIsolation")); |
| suite.addTest(new CacheableModelJunitTest("testProtectedIsolation")); |
| suite.addTest(new CacheableModelJunitTest("testProtectedCaching")); |
| suite.addTest(new CacheableModelJunitTest("testProtectedIsolationWithLockOnCloneFalse")); |
| suite.addTest(new CacheableModelJunitTest("testReadOnlyTree")); |
| |
| suite.addTest(new CacheableModelJunitTest("testUpdateForceProtectedBasic")); |
| suite.addTest(new CacheableModelJunitTest("testUpdateForceProtectedOneToOne")); |
| suite.addTest(new CacheableModelJunitTest("testUpdateProtectedBasic")); |
| suite.addTest(new CacheableModelJunitTest("testUpdateProtectedOneToMany")); |
| |
| suite.addTest(new CacheableModelJunitTest("testProtectedRelationshipsMetadata")); |
| suite.addTest(new CacheableModelJunitTest("testForceProtectedFromEmbeddable")); |
| suite.addTest(new CacheableModelJunitTest("testEmbeddableProtectedCaching")); |
| suite.addTest(new CacheableModelJunitTest("testEmbeddableProtectedReadOnly")); |
| suite.addTest(new CacheableModelJunitTest("testUpdateProtectedManyToOne")); |
| suite.addTest(new CacheableModelJunitTest("testUpdateProtectedManyToMany")); |
| suite.addTest(new CacheableModelJunitTest("testUpdateProtectedElementCollection")); |
| suite.addTest(new CacheableModelJunitTest("testIsolationBeforeEarlyTxBegin")); |
| suite.addTest(new CacheableModelJunitTest("testForeignKeyUpdateInNonCachedOnMergeNewObject")); |
| |
| // Bug 340074 |
| suite.addTest(new CacheableModelJunitTest("testFindWithLegacyFindProperties")); |
| suite.addTest(new CacheableModelJunitTest("testFindWithEMLegacyProperties")); |
| suite.addTest(new CacheableModelJunitTest("testMergeNonCachedWithRelationship")); |
| suite.addTest(new CacheableModelJunitTest("testIndirectCollectionRefreshBehavior")); |
| suite.addTest(new CacheableModelJunitTest("testDerivedIDProtectedRead")); |
| |
| // Bug 408262 |
| suite.addTest(new CacheableModelJunitTest("testRefreshProtectedEntityInEarlyTransaction")); |
| |
| // Bug 530680 |
| suite.addTest(new CacheableModelJunitTest("testUpdateSharedElementCollection")); |
| } |
| 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 CacheableTableCreator().replaceTables(JUnitTestCase.getServerSession()); |
| clearDSCache(); |
| } |
| |
| /** |
| * Test EM properties on commit. |
| */ |
| public void testEMPropertiesOnCommit1() { |
| EntityManager em1 = createDSEntityManager(); |
| |
| // Find the entity and put it in the cache .. |
| CacheableTrueEntity cachedEntity = findCacheableTrueEntity(em1, m_cacheableTrueEntity1Id); |
| String staleName = cachedEntity.getName(); |
| |
| // Create a new Entity to delete |
| beginTransaction(em1); |
| CacheableTrueEntity entityToDelete = new CacheableTrueEntity(); |
| entityToDelete.setName("entityToDelete"); |
| em1.persist(entityToDelete); |
| int entityToDeleteId = entityToDelete.getId(); |
| commitTransaction(em1); |
| |
| beginTransaction(em1); |
| // No need to clear the EM, just set the new property to BYPASS. |
| em1.setProperty(QueryHints.CACHE_STORE_MODE, CacheStoreMode.BYPASS); |
| CacheableTrueEntity entity = findCacheableTrueEntity(em1, m_cacheableTrueEntity1Id); |
| String updatedName = "testEMPropertiesOnCommit1"; |
| entity.setName(updatedName); |
| |
| CacheableTrueEntity deletedEntity1 = findCacheableTrueEntity(em1, entityToDeleteId); |
| em1.remove(deletedEntity1); |
| commitTransaction(em1); |
| closeEM(em1); |
| |
| EntityManager em2 = createDSEntityManager(); |
| beginTransaction(em2); |
| try { |
| CacheableTrueEntity entity2 = findCacheableTrueEntity_USE_BYPASS(em2, m_cacheableTrueEntity1Id); |
| assertTrue("The shared cache was updated when the EM property CacheStoreMode = BYPASS", entity2.getName().equals(staleName)); |
| |
| em2.refresh(entity2); |
| assertTrue("The entity was not refreshed with the updated name.", entity2.getName().equals(updatedName)); |
| |
| HashMap props = new HashMap(); |
| props.put(QueryHints.CACHE_RETRIEVE_MODE, CacheRetrieveMode.USE); |
| props.put(QueryHints.CACHE_STORE_MODE, CacheStoreMode.BYPASS); |
| CacheableTrueEntity deletedEntity2 = em2.find(CacheableTrueEntity.class, entityToDeleteId, props); |
| assertTrue("The deleted entity was removed from the cache", deletedEntity2 == null); |
| |
| deletedEntity2 = em2.find(CacheableTrueEntity.class, entityToDeleteId); |
| assertTrue("The deleted entity was removed from the database", deletedEntity2 == null); |
| } finally { |
| closeEntityManagerAndTransaction(em2); |
| } |
| } |
| |
| /** |
| * Test EM properties on commit. |
| */ |
| public void testEMPropertiesOnCommit2() { |
| EntityManager em1 = createDSEntityManager(); |
| |
| // Find the entities and put them in the shared cache ... |
| CacheableTrueEntity cachedEntity1 = findCacheableTrueEntity(em1, m_cacheableTrueEntity1Id); |
| CacheableTrueEntity cachedEntity2 = findCacheableTrueEntity(em1, m_cacheableTrueEntity2Id); |
| String staleName = cachedEntity2.getName(); |
| |
| String updatedName = "testEMPropertiesOnCommit2"; |
| |
| beginTransaction(em1); |
| // No need to clear the EM, just set the new property to BYPASS. |
| em1.setProperty(QueryHints.CACHE_STORE_MODE, CacheStoreMode.BYPASS); |
| // Update entity1 through a query that uses cache store mode USE. |
| Query query = em1.createQuery("UPDATE JPA_CACHEABLE_TRUE e SET e.name = :name " + "WHERE e.id = :id ").setParameter("name", updatedName).setParameter("id", m_cacheableTrueEntity1Id); |
| query.setHint(QueryHints.CACHE_STORE_MODE, CacheStoreMode.USE); |
| query.executeUpdate(); |
| |
| // Update entity2 manually. |
| CacheableTrueEntity entity2 = findCacheableTrueEntity(em1, m_cacheableTrueEntity2Id); |
| entity2.setName(updatedName); |
| commitTransaction(em1); |
| closeEM(em1); |
| |
| // Verify the cache in a separate entity manager. |
| EntityManager em2 = createDSEntityManager(); |
| beginTransaction(em2); |
| try { |
| CacheableTrueEntity entity21 = findCacheableTrueEntity_USE_BYPASS(em2, m_cacheableTrueEntity1Id); |
| assertTrue("The shared cache should have been updated", entity21.getName().equals(updatedName)); |
| |
| CacheableTrueEntity entity22 = findCacheableTrueEntity_USE_BYPASS(em2, m_cacheableTrueEntity2Id); |
| assertTrue("The shared cache should NOT have been updated", entity22.getName().equals(staleName)); |
| |
| em2.refresh(entity22); |
| assertTrue("The entity was not refreshed with the updated name.", entity22.getName().equals(updatedName)); |
| } finally { |
| closeEntityManagerAndTransaction(em2); |
| } |
| } |
| |
| /** |
| * Test find using entity manager properties |
| */ |
| public void testFindWithEMProperties() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| EntityManager em = createDSEntityManager(); |
| |
| // Put the entity in the UOW and shared cache. |
| CacheableTrueEntity cachedEntity = findCacheableTrueEntity(em, m_cacheableTrueEntity1Id); |
| |
| // Update the entity name in the shared cash through a different EM. |
| updateCacheableTrueEntityNameInSharedCache("testCacheRetrieveModeBypassOnFindThroughEMProperties"); |
| |
| // This should pick up the entity from the shared cache |
| EntityManager em2 = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity2 = em2.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| assertTrue("The shared cache was not updated.", cachedEntity2.getName().equals("testCacheRetrieveModeBypassOnFindThroughEMProperties")); |
| closeEM(em2); |
| |
| // This setting should be ignored on a refresh operation ... |
| em.setProperty(QueryHints.CACHE_RETRIEVE_MODE, CacheRetrieveMode.USE); |
| |
| // Set the refresh property. |
| em.setProperty(QueryHints.CACHE_STORE_MODE, CacheStoreMode.REFRESH); |
| |
| // Re-issue the find on the original EM. |
| CacheableTrueEntity entity = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| assertTrue("CacheableTrueEntity should have been refreshed.", entity.getName().equals("testCacheRetrieveModeBypassOnFindThroughEMProperties")); |
| assertTrue("CacheableTrueEntity from UOW should have been refreshed.", cachedEntity.getName().equals(entity.getName())); |
| assertTrue("Entity returned should be the same instance from the UOW cache", cachedEntity == entity); |
| |
| closeEM(em); |
| } |
| } |
| |
| /** |
| * Test find using entity manager properties (legacy) |
| */ |
| public void testFindWithEMLegacyProperties() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| EntityManager em = createDSEntityManager(); |
| |
| // Put the entity in the UOW and shared cache. |
| CacheableTrueEntity cachedEntity = findCacheableTrueEntity(em, m_cacheableTrueEntity1Id); |
| |
| // Update the entity name in the shared cash through a different EM. |
| updateCacheableTrueEntityNameInSharedCache("testCacheRetrieveModeBypassOnFindThroughEMProperties"); |
| |
| // This should pick up the entity from the shared cache |
| EntityManager em2 = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity2 = em2.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| assertTrue("The shared cache was not updated.", cachedEntity2.getName().equals("testCacheRetrieveModeBypassOnFindThroughEMProperties")); |
| closeEM(em2); |
| |
| // This setting should be ignored on a refresh operation ... |
| em.setProperty("jakarta.persistence.cacheRetrieveMode", CacheRetrieveMode.USE); // legacy property |
| |
| // Set the refresh property. |
| em.setProperty("jakarta.persistence.cacheStoreMode", CacheStoreMode.REFRESH); // legacy property |
| |
| // Re-issue the find on the original EM. |
| CacheableTrueEntity entity = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| assertTrue("CacheableTrueEntity should have been refreshed.", entity.getName().equals("testCacheRetrieveModeBypassOnFindThroughEMProperties")); |
| assertTrue("CacheableTrueEntity from UOW should have been refreshed.", cachedEntity.getName().equals(entity.getName())); |
| assertTrue("Entity returned should be the same instance from the UOW cache", cachedEntity == entity); |
| |
| closeEM(em); |
| } |
| } |
| |
| /** |
| * Test find using find properties |
| */ |
| public void testFindWithFindProperties() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| EntityManager em = createDSEntityManager(); |
| |
| // Put the entity in the UOW and shared cache. |
| CacheableTrueEntity cachedEntity = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| |
| // Update the entity name, but BYPASS updating the shared cache through a different EM. |
| updateCacheableTrueEntityNameAndBypassStore("testCacheRetrieveModeBypassOnFindThroughFindProperties"); |
| |
| // This should pick up the entity from the shared cache (which should not of been updated |
| EntityManager em2 = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity2 = em2.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| assertFalse("The shared cache was updated.", cachedEntity2.getName().equals("testCacheRetrieveModeBypassOnFindThroughFindProperties")); |
| closeEM(em2); |
| |
| // This setting should be ignored on a refresh operation ... |
| em.setProperty(QueryHints.CACHE_RETRIEVE_MODE, CacheRetrieveMode.USE); |
| |
| // Set the refresh property. |
| HashMap properties = new HashMap(); |
| properties.put(QueryHints.CACHE_STORE_MODE, CacheStoreMode.REFRESH); |
| |
| // Re-issue the find on the original EM. |
| CacheableTrueEntity entity = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id, properties); |
| assertTrue("CacheableTrueEntity should have been refreshed.", entity.getName().equals("testCacheRetrieveModeBypassOnFindThroughFindProperties")); |
| assertTrue("CacheableTrueEntity from UOW should have been refreshed.", cachedEntity.getName().equals(entity.getName())); |
| assertTrue("Entity returned should be the same instance from the UOW cache", cachedEntity == entity); |
| |
| closeEM(em); |
| } |
| } |
| |
| /** |
| * Test find using find properties (legacy) |
| */ |
| public void testFindWithLegacyFindProperties() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| EntityManager em = createDSEntityManager(); |
| |
| // Put the entity in the UOW and shared cache. |
| CacheableTrueEntity cachedEntity = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| |
| // Update the entity name, but BYPASS updating the shared cache through a different EM. |
| updateCacheableTrueEntityNameAndBypassStore("testCacheRetrieveModeBypassOnFindThroughFindProperties"); |
| |
| // This should pick up the entity from the shared cache (which should not of been updated |
| EntityManager em2 = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity2 = em2.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| assertFalse("The shared cache was updated.", cachedEntity2.getName().equals("testCacheRetrieveModeBypassOnFindThroughFindProperties")); |
| closeEM(em2); |
| |
| // This setting should be ignored on a refresh operation ... |
| em.setProperty("jakarta.persistence.cacheRetrieveMode", CacheRetrieveMode.USE); |
| |
| // Set the refresh property. |
| HashMap properties = new HashMap(); |
| properties.put("jakarta.persistence.cacheStoreMode", CacheStoreMode.REFRESH); |
| |
| // Re-issue the find on the original EM. |
| CacheableTrueEntity entity = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id, properties); |
| assertTrue("CacheableTrueEntity should have been refreshed.", entity.getName().equals("testCacheRetrieveModeBypassOnFindThroughFindProperties")); |
| assertTrue("CacheableTrueEntity from UOW should have been refreshed.", cachedEntity.getName().equals(entity.getName())); |
| assertTrue("Entity returned should be the same instance from the UOW cache", cachedEntity == entity); |
| |
| closeEM(em); |
| } |
| } |
| |
| /** |
| * Test refresh using EM properties |
| */ |
| public void testRefreshWithEMProperties() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| // This will put the entity in the cache. |
| EntityManager em = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| // Update the database manually through a different EM |
| String updatedName = "testRefreshWithEMProperties"; |
| updateCacheableTrueEntityNameInSharedCache(updatedName); |
| |
| // This setting should be ignored on a refresh operation ... |
| em.setProperty(QueryHints.CACHE_RETRIEVE_MODE, CacheRetrieveMode.USE); |
| beginTransaction(em); |
| try{ |
| cachedEntity = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| em.refresh(cachedEntity); |
| commitTransaction(em); |
| }catch(Exception ex){ |
| ex.printStackTrace(); |
| if (isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| }finally{ |
| closeEM(em); |
| } |
| assertTrue("CacheableTrueEntity should have been refreshed.", cachedEntity.getName().equals(updatedName)); |
| } |
| |
| } |
| |
| /** |
| * Test refresh using refresh properties. |
| */ |
| public void testRefreshWithRefreshProperties() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| // This will put the entity in the cache. |
| EntityManager em = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| |
| // Update the database manually through a different EM |
| String updatedName = "testRefreshWithRefreshProperties"; |
| updateCacheableTrueEntityNameInSharedCache(updatedName); |
| |
| HashMap properties = new HashMap(); |
| // This setting should be ignored on a refresh operation ... |
| properties.put(QueryHints.CACHE_RETRIEVE_MODE, CacheRetrieveMode.USE); |
| beginTransaction(em); |
| try{ |
| cachedEntity = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| em.refresh(cachedEntity, properties); |
| commitTransaction(em); |
| }catch(Exception ex){ |
| if (isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| }finally{ |
| closeEM(em); |
| } |
| assertTrue("CacheableTrueEntity should have been refreshed.", cachedEntity.getName().equals(updatedName)); |
| } |
| } |
| |
| /** |
| * Test: Using named query (when updated object in shared cache) |
| * CacheRetrieveMode = BYPASS |
| * CacheStoreMode = BYPASS |
| */ |
| public void testRetrieveBYPASSStoreBYPASS1() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| // Put the entity in the EM UOW and shared cache. |
| EntityManager em = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity = findCacheableTrueEntity(em, m_cacheableTrueEntity1Id); |
| |
| // Update the entity name in the shared cache through a different EM. |
| String updatedName = "testRetrieveBYPASSStoreBYPASS1"; |
| updateCacheableTrueEntityNameInSharedCache(updatedName); |
| |
| // Execute find by pk query using Retrieve BYPASS, Store BYPASS on EM. |
| // It should return the same entity. |
| CacheableTrueEntity entity1 = findCacheableTrueEntity_BYPASS_BYPASS(em, m_cacheableTrueEntity1Id); |
| assertTrue("The entity instances must be the same", entity1 == cachedEntity); |
| assertTrue("The name should not of been refreshed", entity1.getName().equals(cachedEntity.getName())); |
| |
| // Issue a find using refresh on EM, should pick up the updated name. |
| HashMap properties = new HashMap(); |
| properties.put(QueryHints.CACHE_STORE_MODE, CacheStoreMode.REFRESH); |
| CacheableTrueEntity entity1b = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id, properties); |
| assertTrue("CacheableTrueEntity should of been refreshed.", entity1b.getName().equals(updatedName)); |
| closeEM(em); |
| |
| // On a different EM execute a find by pk using Retrieve BYPASS, |
| // Store BYPASS, we should get the updated name. |
| CacheableTrueEntity entity2 = findCacheableTrueEntity_BYPASS_BYPASS(null, m_cacheableTrueEntity1Id); |
| assertTrue("CacheableTrueEntity should have been refreshed.", entity2.getName().equals(updatedName)); |
| } |
| } |
| |
| /** |
| * Test: Using named query (when updated object NOT in shared cache) |
| * CacheRetrieveMode = BYPASS |
| * CacheStoreMode = BYPASS |
| */ |
| public void testRetrieveBYPASSStoreBYPASS2() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| // Put the entity in the EM UOW and shared cache. |
| EntityManager em = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity = findCacheableTrueEntity(em, m_cacheableTrueEntity1Id); |
| |
| // Update the entity name in the shared cache through a different EM. |
| String updatedName = "testRetrieveBYPASSStoreBYPASS2"; |
| updateCacheableTrueEntityNameAndBypassStore(updatedName); |
| |
| // Execute find by pk query using Retrieve BYPASS, Store BYPASS on EM. |
| // It should return the same entity. |
| CacheableTrueEntity entity1a = findCacheableTrueEntity_BYPASS_BYPASS(em, m_cacheableTrueEntity1Id); |
| assertTrue("The entity returned should match the cached instance", entity1a == cachedEntity); |
| assertTrue("CacheableTrueEntity should have been refreshed.", entity1a.getName().equals(cachedEntity.getName())); |
| |
| // On a different EM issue a find (using internal EclipseLink defaults) |
| CacheableTrueEntity entity2 = findCacheableTrueEntity(null, m_cacheableTrueEntity1Id); |
| assertTrue("CacheableTrueEntity should not of been refreshed.", entity2.getName().equals(entity1a.getName())); |
| |
| // Issue a find on EM1 using REFRESH. |
| HashMap properties = new HashMap(); |
| properties.put(QueryHints.CACHE_STORE_MODE, CacheStoreMode.REFRESH); |
| CacheableTrueEntity entity1b = em.find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id, properties); |
| assertTrue("CacheableTrueEntity should be from the shared cache.", entity1b.getName().equals(updatedName)); |
| |
| closeEM(em); |
| } |
| } |
| |
| /** |
| * Test: Named query using retrieve BYPASS and store USE (when updated object in shared cache). |
| */ |
| public void testRetrieveBYPASSStoreUSE1() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| // Put the entity in the EM UOW and shared cache. |
| EntityManager em = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity = findCacheableTrueEntity(em, m_cacheableTrueEntity1Id); |
| |
| // Update the entity name in the shared cache through a different EM. |
| String updatedName = "testRetrieveBYPASSStoreUSE1"; |
| updateCacheableTrueEntityNameInSharedCache(updatedName); |
| |
| // Execute find by pk query using Retrieve BYPASS, Store USE on EM. |
| // It should return the same entity. |
| CacheableTrueEntity entity1 = findCacheableTrueEntity_BYPASS_USE(em, m_cacheableTrueEntity1Id); |
| assertTrue("The entity instances must be the same", entity1 == cachedEntity); |
| assertTrue("The name should not of been refreshed", entity1.getName().equals(cachedEntity.getName())); |
| |
| // Execute find by pk query using Retrieve USE, Store BYPASS on a |
| // different EM. The entity returned should have been read from the |
| // shared cache with the updated name. |
| CacheableTrueEntity entity2 = findCacheableTrueEntity_USE_BYPASS(null, m_cacheableTrueEntity1Id); |
| assertTrue("CacheableTrueEntity should have the name from the shared cache.", entity2.getName().equals(updatedName)); |
| |
| closeEM(em); |
| } |
| } |
| |
| /** |
| * Test: Using a named query with BYPASS and USE (when updated object not in shared cache) |
| */ |
| public void testRetrieveBYPASSStoreUSE2() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| // Put the entity in the EM UOW and shared cache. |
| EntityManager em = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity = findCacheableTrueEntity(em, m_cacheableTrueEntity1Id); |
| |
| // Update the database manually through a different EM and bypass |
| // updating the shared cache. |
| String updatedName = "testRetrieveBYPASSStoreUSE2"; |
| updateCacheableTrueEntityNameAndBypassStore(updatedName); |
| |
| // Execute find by pk query using Retrieve BYPASS, Store USE on EM. |
| // It should return the same entity. As an optimization in this case, |
| // the Store USE will update the shared cache. |
| CacheableTrueEntity entity1 = findCacheableTrueEntity_BYPASS_USE(em, m_cacheableTrueEntity1Id); |
| assertTrue("The entity instances must be the same", entity1 == cachedEntity); |
| assertTrue("The name should not of been refreshed", entity1.getName().equals(cachedEntity.getName())); |
| closeEM(em); |
| |
| // A find on a new EM should return the value from the shared cache |
| // which should have been updated with the Store USE value above |
| CacheableTrueEntity entity2 = findCacheableTrueEntity(null, m_cacheableTrueEntity1Id); |
| assertTrue("CacheableTrueEntity should have the name from the shared cache.", entity2.getName().equals(updatedName)); |
| } |
| } |
| |
| /** |
| * Test: Named query using retrieve USE and store BYPASS (when updated object in shared cache). |
| */ |
| public void testRetrieveUSEStoreBYPASS1() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| // Put the entity in the UOW and shared cache for EM1 |
| EntityManager em = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity = findCacheableTrueEntity(em, m_cacheableTrueEntity1Id); |
| |
| // Update the entity name in the shared cash through a different EM. |
| String updatedName = "testRetrieveUSEStoreBYPASS1"; |
| updateCacheableTrueEntityNameInSharedCache(updatedName); |
| |
| // Execute find by pk query using Retrieve USE, Store BYPASS on EM. |
| // It should return the same entity. |
| CacheableTrueEntity entity1 = findCacheableTrueEntity_USE_BYPASS(em, m_cacheableTrueEntity1Id); |
| assertTrue("The entity returned should match the cached instance", entity1 == cachedEntity); |
| assertTrue("CacheableTrueEntity should not have been refreshed.", entity1.getName().equals(cachedEntity.getName())); |
| closeEM(em); |
| |
| // Execute a find by pk query using Retrieve USE, Store BYPASS on a |
| // different EM. The entity returned should have been read from the |
| // shared cache with the updated name. |
| CacheableTrueEntity entity2 = findCacheableTrueEntity_USE_BYPASS(null, m_cacheableTrueEntity1Id); |
| assertTrue("CacheableTrueEntity should have the name from the shared cache.", entity2.getName().equals(updatedName)); |
| } |
| } |
| |
| /** |
| * Test: Named query using retrieve USE and store BYPASS (when updated object NOT in shared cache). |
| */ |
| public void testRetrieveUSEStoreBYPASS2() { |
| // Cannot create parallel entity managers in the server. |
| if (! isOnServer()) { |
| // Put the entity in the UOW and shared cache for EM1 |
| EntityManager em1 = createDSEntityManager(); |
| CacheableTrueEntity cachedEntity = findCacheableTrueEntity(em1, m_cacheableTrueEntity1Id); |
| |
| // Update the database manually through a different EM and bypass |
| // updating the shared cache. |
| String updatedName = "testRetrieveUSEStoreBYPASS2"; |
| updateCacheableTrueEntityNameAndBypassStore(updatedName); |
| |
| // Execute find by pk query using Retrieve USE, Store BYPASS on EM. |
| // It should return the same entity. |
| CacheableTrueEntity entity1 = findCacheableTrueEntity_USE_BYPASS(em1, m_cacheableTrueEntity1Id); |
| assertTrue("The entity returned should match the cached instance", entity1 == cachedEntity); |
| assertTrue("CacheableTrueEntity should not have been refreshed.", entity1.getName().equals(cachedEntity.getName())); |
| closeEM(em1); |
| |
| // Issue a find on a different EM. The entity should come from the |
| // shared cache and have a stale name. |
| EntityManager em2 = createDSEntityManager(); |
| CacheableTrueEntity entity2 = findCacheableTrueEntity(em2, m_cacheableTrueEntity1Id); |
| assertTrue("CacheableTrueEntity should have the name from the shared cache.", entity2.getName().equals(entity1.getName())); |
| |
| // Now refresh the entity, should get the updated name. |
| em2.refresh(entity2); |
| assertTrue("CacheableTrueEntity should have the name from database.", entity2.getName().equals(updatedName)); |
| closeEM(em2); |
| } |
| } |
| |
| /** |
| * Test EM properties on commit. |
| */ |
| public void testInheritanceCacheable() { |
| EntityManager em1 = createDSEntityManager(); |
| |
| beginTransaction(em1); |
| CacheableTrueEntity cacheableEntity1 = new CacheableTrueEntity(); |
| cacheableEntity1.setName("cacheableEntity"); |
| em1.persist(cacheableEntity1); |
| ChildCacheableFalseEntity nonCacheableEntity1 = new ChildCacheableFalseEntity(); |
| nonCacheableEntity1.setName("nonCacheableEntity"); |
| em1.persist(nonCacheableEntity1); |
| commitTransaction(em1); |
| |
| closeEM(em1); |
| |
| EntityManager em2 = createDSEntityManager(); |
| HashMap props = new HashMap(); |
| props.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly); |
| |
| CacheableTrueEntity cacheableEntity2 = em2.find(CacheableTrueEntity.class, cacheableEntity1.getId(), props); |
| CacheableTrueEntity nonCacheableEntity2a = em2.find(CacheableTrueEntity.class, nonCacheableEntity1.getId(), props); |
| ChildCacheableFalseEntity nonCacheableEntity2b = em2.find(ChildCacheableFalseEntity.class, nonCacheableEntity1.getId(), props); |
| |
| assertFalse("CacheableTrueEntity was not in the cache", cacheableEntity2 == null); |
| assertTrue("ChildCacheableFalseEntity was in the cache", nonCacheableEntity2a == null); |
| assertTrue("ChildCacheableFalseEntity was in the cache", nonCacheableEntity2b == null); |
| |
| closeEM(em2); |
| } |
| |
| public void testMultipleEMQueries() { |
| // Get the object in the shared cache. |
| CacheableTrueEntity cachedEntity = createDSEntityManager().find(CacheableTrueEntity.class, m_cacheableTrueEntity1Id); |
| |
| // Update the database manually through a different EM and bypass |
| // updating the shared cache. |
| String updatedName = "testMultipleEMQueries"; |
| updateCacheableTrueEntityNameAndBypassStore(updatedName); |
| |
| // Execute find by pk query using Retrieve USE, Store BYPASS. The entity |
| // returned should have been read from the shared cache with the stale name. |
| CacheableTrueEntity entity1 = findCacheableTrueEntity_USE_BYPASS(null, m_cacheableTrueEntity1Id); |
| assertFalse("CacheableTrueEntity should not have the updated name.", entity1.getName().equals(updatedName)); |
| |
| // Execute find by pk query using Retrieve BYPASS, Store USE. The entity |
| // returned should have been read from the database and the shared cache |
| // should have been updated. |
| CacheableTrueEntity entity2 = findCacheableTrueEntity_BYPASS_USE(null, m_cacheableTrueEntity1Id); |
| assertTrue("CacheableTrueEntity should have the updated name.", entity2.getName().equals(updatedName)); |
| |
| // Execute find by pk query using Retrieve USE, Store BYPASS. The entity |
| // returned should have been read from the shared cache with the updated name. |
| CacheableTrueEntity entity3 = findCacheableTrueEntity_USE_BYPASS(null, m_cacheableTrueEntity1Id); |
| assertTrue("CacheableTrueEntity should have the updated name.", entity3.getName().equals(updatedName)); |
| } |
| |
| /** |
| * Verifies the cacheable settings when caching (from persistence.xml) is set to ALL using {@code <shared-cache-mode>}. |
| */ |
| public void testCachingOnALL() { |
| assertCachingOnALL(getPUServerSession("ALL")); |
| } |
| |
| /** |
| * Verifies the cacheable settings when caching (from persistence.xml) is set to ALL using jakarta.persistence.sharedCache.mode property. |
| */ |
| public void testCachingOnALLProperty() { |
| assertCachingOnALL(getPUServerSession("ALL-Property")); |
| } |
| |
| public void assertCachingOnALL(ServerSession session) { |
| ClassDescriptor falseEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_FALSE"); |
| assertFalse("CacheableFalseEntity (ALL) from annotations has caching turned off", usesNoCache(falseEntityDescriptor)); |
| |
| ClassDescriptor trueEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_TRUE"); |
| assertFalse("CacheableTrueEntity (ALL) from annotations has caching turned off", usesNoCache(trueEntityDescriptor)); |
| |
| ClassDescriptor protectedEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_PROTECTED"); |
| assertFalse("CacheableProtectedEntity (ALL) from annotations has caching turned off", usesNoCache(protectedEntityDescriptor)); |
| |
| ClassDescriptor childFalseEntityDescriptor = session.getDescriptorForAlias("JPA_CHILD_CACHEABLE_FALSE"); |
| assertFalse("ChildCacheableFalseEntity (ALL) from annotations has caching turned off", usesNoCache(childFalseEntityDescriptor)); |
| |
| ClassDescriptor falseSubEntityDescriptor = session.getDescriptorForAlias("JPA_SUB_CACHEABLE_FALSE"); |
| assertFalse("SubCacheableFalseEntity (ALL) from annotations has caching turned off", usesNoCache(falseSubEntityDescriptor)); |
| |
| // Should pick up true from the mapped superclass. |
| ClassDescriptor noneSubEntityDescriptor = session.getDescriptorForAlias("JPA_SUB_CACHEABLE_NONE"); |
| assertFalse("SubCacheableNoneEntity (ALL) from annotations has caching turned off", usesNoCache(noneSubEntityDescriptor)); |
| |
| ClassDescriptor xmlFalseEntityDescriptor = session.getDescriptorForAlias("XML_CACHEABLE_FALSE"); |
| assertFalse("CacheableFalseEntity (ALL) from XML has caching turned off", usesNoCache(xmlFalseEntityDescriptor)); |
| |
| ClassDescriptor xmlTrueEntityDescriptor = session.getDescriptorForAlias("XML_CACHEABLE_TRUE"); |
| assertFalse("CacheableTrueEntity (ALL) from XML has caching turned ff", usesNoCache(xmlTrueEntityDescriptor)); |
| |
| ClassDescriptor xmlFalseSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_FALSE"); |
| assertFalse("SubCacheableFalseEntity (ALL) from XML has caching turned off", usesNoCache(xmlFalseSubEntityDescriptor)); |
| |
| // Should pick up true from the mapped superclass. |
| ClassDescriptor xmlNoneSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_NONE"); |
| assertFalse("SubCacheableTrueEntity (ALL) from XML has caching turned off", usesNoCache(xmlNoneSubEntityDescriptor)); |
| } |
| |
| /** |
| * Verifies the cacheable settings when caching (from persistence.xml) is set to NONE using {@code <shared-cache-mode>}. |
| */ |
| public void testCachingOnNONE() { |
| assertCachingOnNONE(getPUServerSession("NONE")); |
| } |
| |
| /** |
| * Verifies the cacheable settings when caching (from persistence.xml) is set to NONE using jakarta.persistence.sharedCache.mode property. |
| */ |
| public void testCachingOnNONEProperty() { |
| assertCachingOnNONE(getPUServerSession("NONE-Property")); |
| } |
| |
| /** |
| * Verifies the cacheable settings when passing the jakarta.persistence.sharedCache.mode property |
| * as NONE when creating an EntityManagerFactory. |
| */ |
| public void testCachingOnNONEPropertyEMF() { |
| Map<String, String> properties = new HashMap<String, String>(); |
| properties.putAll(JUnitTestCaseHelper.getDatabaseProperties()); |
| properties.put(PersistenceUnitProperties.SHARED_CACHE_MODE, "NONE"); |
| assertCachingOnNONE(getPUServerSession("CacheUnlisted", properties)); |
| } |
| |
| /** |
| * Verifies that when the {@code <shared-cache-mode>} and jakarta.persistence.sharedCache.mode property |
| * are set, the jakarta.persistence.sharedCache.mode property will win. In the persistence.xml, |
| * jakarta.persistence.sharedCache.mode property is set to NONE while {@code <shared-cache-mode>} is set to |
| * ALL. |
| */ |
| public void testCachingOnNONEPropertyConflict() { |
| assertCachingOnNONE(getPUServerSession("NONE-Property-Conflict")); |
| } |
| |
| public void assertCachingOnNONE(ServerSession session) { |
| ClassDescriptor falseEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_FALSE"); |
| assertTrue("CacheableFalseEntity (NONE) from annotations has caching turned on", usesNoCache(falseEntityDescriptor)); |
| |
| ClassDescriptor trueEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_TRUE"); |
| assertTrue("CacheableTrueEntity (NONE) from annotations has caching turned on", usesNoCache(trueEntityDescriptor)); |
| |
| ClassDescriptor protectedEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_PROTECTED"); |
| assertTrue("CacheableProtectedEntity (ALL) from annotations has caching turned off", usesNoCache(protectedEntityDescriptor)); |
| |
| ClassDescriptor childFalseEntityDescriptor = session.getDescriptorForAlias("JPA_CHILD_CACHEABLE_FALSE"); |
| assertTrue("ChildCacheableFalseEntity (NONE) from annotations has caching turned on", usesNoCache(childFalseEntityDescriptor)); |
| |
| ClassDescriptor falseSubEntityDescriptor = session.getDescriptorForAlias("JPA_SUB_CACHEABLE_FALSE"); |
| assertTrue("SubCacheableFalseEntity (NONE) from annotations has caching turned on", usesNoCache(falseSubEntityDescriptor)); |
| |
| // Should pick up true from the mapped superclass. |
| ClassDescriptor noneSubEntityDescriptor = session.getDescriptorForAlias("JPA_SUB_CACHEABLE_NONE"); |
| assertTrue("SubCacheableNoneEntity (NONE) from annotations has caching turned on", usesNoCache(noneSubEntityDescriptor)); |
| |
| ClassDescriptor xmlFalseEntityDescriptor = session.getDescriptorForAlias("XML_CACHEABLE_FALSE"); |
| assertTrue("CacheableFalseEntity (NONE) from XML has caching turned on", usesNoCache(xmlFalseEntityDescriptor)); |
| |
| ClassDescriptor xmlTrueEntityDescriptor = session.getDescriptorForAlias("XML_CACHEABLE_TRUE"); |
| assertTrue("CacheableTrueEntity (NONE) from XML has caching turned on", usesNoCache(xmlTrueEntityDescriptor)); |
| |
| ClassDescriptor xmlFalseSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_FALSE"); |
| assertTrue("SubCacheableFalseEntity (NONE) from XML has caching turned on", usesNoCache(xmlFalseSubEntityDescriptor)); |
| |
| // Should pick up true from the mapped superclass. |
| ClassDescriptor xmlNoneSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_NONE"); |
| assertTrue("SubCacheableTrueEntity (NONE) from XML has caching turned on", usesNoCache(xmlNoneSubEntityDescriptor)); |
| } |
| |
| /** |
| * Verifies the cacheable settings when caching (from persistence.xml) is set to ENABLE_SELECTIVE using {@code <shared-cache-mode>}. |
| */ |
| public void testCachingOnENABLE_SELECTIVE() { |
| assertCachingOnENABLE_SELECTIVE(getPUServerSession("ENABLE_SELECTIVE")); |
| } |
| |
| /** |
| * Verifies the cacheable settings when caching (from persistence.xml) is set to ENABLE_SELECTIVE using jakarta.persistence.sharedCache.mode property. |
| */ |
| public void testCachingOnENABLE_SELECTIVEProperty() { |
| assertCachingOnENABLE_SELECTIVE(getPUServerSession("ENABLE_SELECTIVE-Property")); |
| } |
| |
| public void assertCachingOnENABLE_SELECTIVE(ServerSession session) { |
| ClassDescriptor falseEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_FALSE"); |
| assertTrue("CacheableFalseEntity (ENABLE_SELECTIVE) from annotations has caching turned on", usesNoCache(falseEntityDescriptor)); |
| |
| ClassDescriptor trueEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_TRUE"); |
| assertFalse("CacheableTrueEntity (ENABLE_SELECTIVE) from annotations has caching turned off", usesNoCache(trueEntityDescriptor)); |
| |
| ClassDescriptor childFalseEntityDescriptor = session.getDescriptorForAlias("JPA_CHILD_CACHEABLE_FALSE"); |
| assertTrue("ChildCacheableFalseEntity (ENABLE_SELECTIVE) from annotations has caching turned on", usesNoCache(childFalseEntityDescriptor)); |
| |
| ClassDescriptor falseSubEntityDescriptor = session.getDescriptorForAlias("JPA_SUB_CACHEABLE_FALSE"); |
| assertTrue("SubCacheableFalseEntity (ENABLE_SELECTIVE) from annotations has caching turned on", usesNoCache(falseSubEntityDescriptor)); |
| |
| // Should pick up true from the mapped superclass. |
| ClassDescriptor noneSubEntityDescriptor = session.getDescriptorForAlias("JPA_SUB_CACHEABLE_NONE"); |
| assertFalse("SubCacheableNoneEntity (ENABLE_SELECTIVE) from annotations has caching turned off", usesNoCache(noneSubEntityDescriptor)); |
| |
| ClassDescriptor xmlFalseEntityDescriptor = session.getDescriptorForAlias("XML_CACHEABLE_FALSE"); |
| assertTrue("CacheableFalseEntity (ENABLE_SELECTIVE) from XML has caching turned on", usesNoCache(xmlFalseEntityDescriptor)); |
| |
| ClassDescriptor xmlTrueEntityDescriptor = session.getDescriptorForAlias("XML_CACHEABLE_TRUE"); |
| assertFalse("CacheableTrueEntity (ENABLE_SELECTIVE) from XML has caching turned off", usesNoCache(xmlTrueEntityDescriptor)); |
| |
| ClassDescriptor xmlFalseSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_FALSE"); |
| assertTrue("SubCacheableFalseEntity (ENABLE_SELECTIVE) from XML has caching turned on", usesNoCache(xmlFalseSubEntityDescriptor)); |
| |
| // Should pick up true from the mapped superclass. |
| ClassDescriptor xmlNoneSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_NONE"); |
| assertFalse("SubCacheableNoneEntity (ENABLE_SELECTIVE) from XML has caching turned off", usesNoCache(xmlNoneSubEntityDescriptor)); |
| } |
| |
| /** |
| * Verifies the cacheable settings when caching (from persistence.xml) is set to DISABLE_SELECTIVE using {@code <shared-cache-mode>}. |
| */ |
| public void testCachingOnDISABLE_SELECTIVE() { |
| assertCachingOnDISABLE_SELECTIVE(getPUServerSession("DISABLE_SELECTIVE")); |
| } |
| |
| /** |
| * Verifies the cacheable settings when caching (from persistence.xml) is set to DISABLE_SELECTIVE using jakarta.persistence.sharedCache.mode property. |
| */ |
| public void testCachingOnDISABLE_SELECTIVEProperty() { |
| assertCachingOnDISABLE_SELECTIVE(getPUServerSession("DISABLE_SELECTIVE-Property")); |
| } |
| |
| public void assertCachingOnDISABLE_SELECTIVE(ServerSession session) { |
| ClassDescriptor falseEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_FALSE"); |
| assertTrue("CacheableFalseEntity (DISABLE_SELECTIVE) from annotations has caching turned on", usesNoCache(falseEntityDescriptor)); |
| |
| ClassDescriptor trueEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_TRUE"); |
| assertFalse("CacheableTrueEntity (DISABLE_SELECTIVE) from annotations has caching turned off", usesNoCache(trueEntityDescriptor)); |
| |
| ClassDescriptor childFalseEntityDescriptor = session.getDescriptorForAlias("JPA_CHILD_CACHEABLE_FALSE"); |
| assertTrue("ChildCacheableFalseEntity (DISABLE_SELECTIVE) from annotations has caching turned on", usesNoCache(childFalseEntityDescriptor)); |
| |
| ClassDescriptor falseSubEntityDescriptor = session.getDescriptorForAlias("JPA_SUB_CACHEABLE_FALSE"); |
| assertTrue("SubCacheableFalseEntity (DISABLE_SELECTIVE) from annotations has caching turned on", usesNoCache(falseSubEntityDescriptor)); |
| |
| // Should pick up true from the mapped superclass. |
| ClassDescriptor noneSubEntityDescriptor = session.getDescriptorForAlias("JPA_SUB_CACHEABLE_NONE"); |
| assertFalse("SubCacheableNoneEntity (DISABLE_SELECTIVE) from annotations has caching turned off", usesNoCache(noneSubEntityDescriptor)); |
| |
| ClassDescriptor xmlFalseEntityDescriptor = session.getDescriptorForAlias("XML_CACHEABLE_FALSE"); |
| assertTrue("CacheableFalseEntity (DISABLE_SELECTIVE) from XML has caching turned on", usesNoCache(xmlFalseEntityDescriptor)); |
| |
| ClassDescriptor xmlTrueEntityDescriptor = session.getDescriptorForAlias("XML_CACHEABLE_TRUE"); |
| assertFalse("CacheableTrueEntity (DISABLE_SELECTIVE) from XML has caching turned off", usesNoCache(xmlTrueEntityDescriptor)); |
| |
| ClassDescriptor xmlFalseSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_FALSE"); |
| assertTrue("SubCacheableFalseEntity (DISABLE_SELECTIVE) from XML has caching turned on", usesNoCache(xmlFalseSubEntityDescriptor)); |
| |
| // Should pick up true from the mapped superclass. |
| ClassDescriptor xmlNoneSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_NONE"); |
| assertFalse("SubCacheableNoneEntity (DISABLE_SELECTIVE) from XML has caching turned off", usesNoCache(xmlNoneSubEntityDescriptor)); |
| } |
| |
| /** |
| * Verifies the cacheable settings when caching (from persistence.xml) is set to UNSPECIFIED using {@code <shared-cache-mode>}. |
| */ |
| public void testCachingOnUNSPECIFIED() { |
| assertCachingOnUNSPECIFIED(getPUServerSession("UNSPECIFIED")); |
| } |
| |
| /** |
| * Verifies the cacheable settings when caching (from persistence.xml) is set to UNSPECIFIED using jakarta.persistence.sharedCache.mode property. |
| */ |
| public void testCachingOnUNSPECIFIEDProperty() { |
| assertCachingOnUNSPECIFIED(getPUServerSession("UNSPECIFIED-Property")); |
| } |
| |
| public void assertCachingOnUNSPECIFIED(ServerSession session) { |
| ClassDescriptor falseEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_FALSE"); |
| assertTrue("CacheableFalseEntity (UNSPECIFIED) from annotations has caching turned on", usesNoCache(falseEntityDescriptor)); |
| |
| ClassDescriptor trueEntityDescriptor = session.getDescriptorForAlias("JPA_CACHEABLE_TRUE"); |
| assertFalse("CacheableTrueEntity (UNSPECIFIED) from annotations has caching turned off", usesNoCache(trueEntityDescriptor)); |
| |
| ClassDescriptor childFalseEntityDescriptor = session.getDescriptorForAlias("JPA_CHILD_CACHEABLE_FALSE"); |
| assertTrue("ChildCacheableFalseEntity (UNSPECIFIED) from annotations has caching turned on", usesNoCache(childFalseEntityDescriptor)); |
| |
| ClassDescriptor falseSubEntityDescriptor = session.getDescriptorForAlias("JPA_SUB_CACHEABLE_FALSE"); |
| assertTrue("SubCacheableFalseEntity (UNSPECIFIED) from annotations has caching turned on", usesNoCache(falseSubEntityDescriptor)); |
| |
| // Should pick up true from the mapped superclass. |
| ClassDescriptor noneSubEntityDescriptor = session.getDescriptorForAlias("JPA_SUB_CACHEABLE_NONE"); |
| assertFalse("SubCacheableNoneEntity (UNSPECIFIED) from annotations has caching turned off", usesNoCache(noneSubEntityDescriptor)); |
| |
| ClassDescriptor xmlFalseEntityDescriptor = session.getDescriptorForAlias("XML_CACHEABLE_FALSE"); |
| assertTrue("CacheableFalseEntity (UNSPECIFIED) from XML has caching turned on", usesNoCache(xmlFalseEntityDescriptor)); |
| |
| ClassDescriptor xmlTrueEntityDescriptor = session.getDescriptorForAlias("XML_CACHEABLE_TRUE"); |
| assertFalse("CacheableTrueEntity (UNSPECIFIED) from XML has caching turned off", usesNoCache(xmlTrueEntityDescriptor)); |
| |
| ClassDescriptor xmlFalseSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_FALSE"); |
| assertTrue("SubCacheableFalseEntity (UNSPECIFIED) from XML has caching turned on", usesNoCache(xmlFalseSubEntityDescriptor)); |
| |
| // Should pick up true from the mapped superclass. |
| ClassDescriptor xmlNoneSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_NONE"); |
| assertFalse("SubCacheableNoneEntity (UNSPECIFIED) from XML has caching turned off", usesNoCache(xmlNoneSubEntityDescriptor)); |
| } |
| |
| public void testCreateEntities() { |
| EntityManager em = null; |
| |
| try { |
| if (!isOnServer()) { |
| em = createEntityManager("DISABLE_SELECTIVE"); |
| } else { |
| em = createEntityManager("MulitPU-4"); |
| } |
| beginTransaction(em); |
| |
| CacheableTrueEntity cacheableTrueEntity = new CacheableTrueEntity(); |
| cacheableTrueEntity.setName("testCreateEntities"); |
| em.persist(cacheableTrueEntity); |
| m_cacheableTrueEntity1Id = cacheableTrueEntity.getId(); |
| |
| CacheableForceProtectedEntity cacheableForceProtectedEntity = new CacheableForceProtectedEntity(); |
| cacheableForceProtectedEntity.setName("testCreateEntities"); |
| em.persist(cacheableForceProtectedEntity); |
| m_cacheableForceProtectedEntity1Id = cacheableForceProtectedEntity.getId(); |
| |
| CacheableFalseEntity cacheableFalseEntity = new CacheableFalseEntity(); |
| em.persist(cacheableFalseEntity); |
| |
| cacheableForceProtectedEntity.setCacheableFalse(cacheableFalseEntity); |
| |
| CacheableProtectedEntity cacheableProtectedEntity = new CacheableProtectedEntity(); |
| em.persist(cacheableProtectedEntity); |
| m_cacheableProtectedEntityId = cacheableProtectedEntity.getId(); |
| cacheableFalseEntity.setProtectedEntity(cacheableProtectedEntity); |
| |
| CacheableTrueEntity cacheableTrueEntity2 = new CacheableTrueEntity(); |
| cacheableTrueEntity2.setName("testCreateEntities"); |
| em.persist(cacheableTrueEntity2); |
| m_cacheableTrueEntity2Id = cacheableTrueEntity2.getId(); |
| |
| ChildCacheableFalseEntity childCacheableFalseEntity = new ChildCacheableFalseEntity(); |
| childCacheableFalseEntity.setName("testCreateEntities"); |
| em.persist(childCacheableFalseEntity); |
| m_childCacheableFalseEntityId = childCacheableFalseEntity.getId(); |
| |
| ForceProtectedEntityWithComposite fpewc = new ForceProtectedEntityWithComposite(); |
| fpewc.setName("testCreateEntities"); |
| ProtectedEmbeddable pe = new ProtectedEmbeddable(); |
| fpewc.setProtectedEmbeddable(pe); |
| CacheableFalseEntity cfe = new CacheableFalseEntity(); |
| pe.setCacheableFalseEntity(cfe); |
| SharedEmbeddable se = new SharedEmbeddable(); |
| fpewc.setSharedEmbeddable(se); |
| em.persist(fpewc); |
| m_forcedProtectedEntityCompositId = fpewc.getId(); |
| em.persist(cfe); |
| CacheableFalseDetail cacheableFalseDetailEntity = new CacheableFalseDetail(); |
| em.persist(cacheableFalseDetailEntity); |
| |
| CacheableRelationshipsEntity prse = new CacheableRelationshipsEntity(); |
| prse.setName("Test OneToMany"); |
| prse.addCacheableFalse(cacheableFalseEntity); |
| prse.addCacheableProtected(cacheableProtectedEntity); |
| prse.setCacheableFPE(cacheableForceProtectedEntity); |
| prse.addCacheableFalseDetail(cacheableFalseDetailEntity); |
| prse.addProtectedEmbeddable(pe); |
| em.persist(prse); |
| m_cacheableRelationshipsEntityId = prse.getId(); |
| commitTransaction(em); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| public void testDetailsOrder_Isolated() { |
| testDetailsOrder(false, false); |
| } |
| |
| public void testDetailsOrder_Isolated_BeginEarlyTransaction() { |
| testDetailsOrder(false, true); |
| } |
| |
| public void testDetailsOrder_Shared() { |
| testDetailsOrder(true, false); |
| } |
| |
| public void testDetailsOrder_Shared_BeginEarlyTransaction() { |
| testDetailsOrder(true, true); |
| } |
| |
| /* |
| * @param useSharedCache if true both Entity and Detail use shared cache (otherwise both use isolated cache) |
| * @param beginEarlyTransaction if true both EntityManagers that read back objects to verify order will beginEarlyTransaction |
| */ |
| void testDetailsOrder(boolean useSharedCache, boolean beginEarlyTransaction) { |
| String puName = useSharedCache ? "ALL" : "NONE"; |
| if (isOnServer()) { |
| puName = useSharedCache ? "MulitPU-1" : "MulitPU-2"; |
| } |
| int entityId; |
| int nDetails = 2; |
| |
| // create entity and details, persist them |
| EntityManager em = createEntityManager(puName); |
| try { |
| beginTransaction(em); |
| CacheableFalseEntity entity = new CacheableFalseEntity(); |
| for(int i=0; i < nDetails; i++) { |
| CacheableFalseDetail detail = new CacheableFalseDetail(); |
| detail.setDescription(Integer.toString(i)); |
| entity.getDetails().add(detail); |
| } |
| em.persist(entity); |
| commitTransaction(em); |
| entityId = entity.getId(); |
| } finally { |
| if(isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| |
| try { |
| // verify that the order is correct, then reverse the order |
| clearCache(puName); |
| em = createEntityManager(puName); |
| try { |
| beginTransaction(em); |
| if(beginEarlyTransaction) { |
| em.setProperty(EntityManagerProperties.JOIN_EXISTING_TRANSACTION, "true"); |
| } |
| // verify that the order is correct |
| CacheableFalseEntity entity = em.find(CacheableFalseEntity.class, entityId); |
| assertTrue("Read back wrong number of details", nDetails == entity.getDetails().size()); |
| for(int i=0; i < nDetails; i++) { |
| CacheableFalseDetail detail = entity.getDetails().get(i); |
| int iExpected = Integer.parseInt(detail.getDescription()); |
| assertTrue("Wrong index " + i + "; was expected " + iExpected, i == iExpected); |
| } |
| |
| // reverse the order |
| List<CacheableFalseDetail> copyDetails = new ArrayList(entity.getDetails()); |
| entity.getDetails().clear(); |
| for(int i=nDetails-1; i >= 0; i--) { |
| entity.getDetails().add(copyDetails.get(i)); |
| } |
| commitTransaction(em); |
| } finally { |
| if(isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| |
| // verify that the order is still correct |
| clearCache(puName); |
| em = createEntityManager(puName); |
| try { |
| beginTransaction(em); |
| if(beginEarlyTransaction) { |
| em.setProperty(EntityManagerProperties.JOIN_EXISTING_TRANSACTION, "true"); |
| } |
| CacheableFalseEntity entity = em.find(CacheableFalseEntity.class, entityId); |
| assertTrue("After reverse read back wrong number of details", nDetails == entity.getDetails().size()); |
| for(int i=0; i < nDetails; i++) { |
| CacheableFalseDetail detail = entity.getDetails().get(i); |
| // the order has been reversed |
| int iExpected = nDetails - Integer.parseInt(detail.getDescription()) - 1; |
| assertTrue("After reverse wrong index " + i + "; was expected " + iExpected, i == iExpected); |
| } |
| } finally { |
| if(isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| } finally { |
| // clean up |
| em = createEntityManager(puName); |
| try { |
| beginTransaction(em); |
| CacheableFalseEntity entity = em.find(CacheableFalseEntity.class, entityId); |
| em.remove(entity); |
| commitTransaction(em); |
| } finally { |
| if(isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| } |
| } |
| |
| public void testLoadMixedCacheTree(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| CacheableForceProtectedEntity cte = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| assertNotNull("Did not load the CacheableTrue Entity", cte); |
| CacheableFalseEntity cfe = cte.getCacheableFalse(); |
| assertNotNull("Did not load the CacheableFalse related Entity", cfe); |
| CacheableProtectedEntity cpe = cfe.getProtectedEntity(); |
| assertNotNull("Did not load the Cacheable Protected related Entity", cpe); |
| CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| assertNotNull("Did not load the CacheableRelationshipsEntity", cre); |
| List<CacheableFalseEntity> cacheableFalses = cre.getCacheableFalses(); |
| assertNotNull("Did not load collections of CacheableRelationshipsEntity related(OneToMany) CacheableFalseEntity", cacheableFalses); |
| List<CacheableProtectedEntity> cacheableProtects = cre.getCacheableProtecteds(); |
| assertNotNull("Did not load collections of CacheableRelationshipsEntity related(OneToMany) CacheableProtectedEntity", cacheableProtects); |
| CacheableForceProtectedEntity cfpe = cre.getCacheableFPE(); |
| assertNotNull("Did not load the CacheableRelationshipsEntity related(ManyToOne) CacheableForceProtectedEntity", cfpe); |
| List<CacheableFalseDetail> cacheableFalseDetails = cre.getCacheableFalseDetails(); |
| assertNotNull("Did not load collections of CacheableRelationshipsEntity related(ManyToMany) CacheableFalseDetail", cacheableFalseDetails); |
| List<ProtectedEmbeddable> protectedEmbed = cre.getProtectedEmbeddables(); |
| assertNotNull("Did not load collections of CacheableRelationshipsEntity related(ElementCollection) ProtectedEmbeddable", protectedEmbed); |
| }finally{ |
| rollbackTransaction(em); |
| closeEM(em); |
| } |
| } |
| |
| public void testIsolatedIsolation(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| CacheableForceProtectedEntity cte = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| CacheableFalseEntity cfe = cte.getCacheableFalse(); |
| assertNull("An isolated Entity was found in the shared cache", em.unwrap(ServerSession.class).getIdentityMapAccessor().getFromIdentityMap(cfe)); |
| CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| for (CacheableFalseEntity cfe1 : cre.getCacheableFalses()){ |
| assertNull("An isolated Entity in many side of OneToMany relationship was found in the shared cache", em.unwrap(ServerSession.class).getIdentityMapAccessor().getFromIdentityMap(cfe1)); |
| } |
| for (CacheableFalseDetail cfde1 : cre.getCacheableFalseDetails()){ |
| assertNull("An isolated Entity in many side of ManyToMany relationship was found in the shared cache", em.unwrap(ServerSession.class).getIdentityMapAccessor().getFromIdentityMap(cfde1)); |
| } |
| }finally{ |
| rollbackTransaction(em); |
| closeEM(em); |
| } |
| } |
| |
| public void testProtectedIsolationWithLockOnCloneFalse(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| ClassDescriptor descriptor = null; |
| try{ |
| ServerSession session = em.unwrap(ServerSession.class); |
| descriptor = session.getDescriptor(CacheableForceProtectedEntity.class); |
| descriptor.setShouldLockForClone(false); |
| session.readObject(CacheableForceProtectedEntity.class, new ExpressionBuilder().get("id").equal(m_cacheableForceProtectedEntity1Id)); |
| CacheableForceProtectedEntity cte = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| CacheableFalseEntity cfe = cte.getCacheableFalse(); |
| assertNotNull("Failed to load protected relationship when setShouldLockForClone is set to false", cfe); |
| CacheableProtectedEntity cpe = cfe.getProtectedEntity(); |
| assertNotNull("Failed to load protected relationship when setShouldLockForClone is set to false", cpe); |
| }finally{ |
| if (descriptor != null){ |
| descriptor.setShouldLockForClone(true); |
| } |
| rollbackTransaction(em); |
| |
| closeEM(em); |
| } |
| |
| } |
| |
| public void testProtectedIsolation(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| CacheableForceProtectedEntity cte = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| CacheableFalseEntity cfe = cte.getCacheableFalse(); |
| CacheableProtectedEntity cpe = cfe.getProtectedEntity(); |
| ServerSession session = em.unwrap(ServerSession.class); |
| assertNull("An protected relationshipwas found in the shared cache", ((CacheableForceProtectedEntity)session.getIdentityMapAccessor().getFromIdentityMap(cte)).getCacheableFalse()); |
| CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| for (CacheableProtectedEntity cpe1 : ((CacheableRelationshipsEntity)session.getIdentityMapAccessor().getFromIdentityMap(cre)).getCacheableProtecteds()){ |
| assertNotNull("An protected relationship in OneToMany was not found in the shared cache", cpe1); |
| } |
| assertNotNull("An protected relationship in ManyToOne was found in the shared cache", ((CacheableRelationshipsEntity)session.getIdentityMapAccessor().getFromIdentityMap(cre)).getCacheableFPE()); |
| for (ProtectedEmbeddable cpe2 : ((CacheableRelationshipsEntity)session.getIdentityMapAccessor().getFromIdentityMap(cre)).getProtectedEmbeddables()){ |
| assertNull("An protected relationship in ElementCollection was found in the shared cache", cpe2); |
| } |
| }finally{ |
| rollbackTransaction(em); |
| closeEM(em); |
| } |
| |
| } |
| |
| public void testForceProtectedFromEmbeddable(){ |
| EntityManager em = createDSEntityManager(); |
| ClassDescriptor forcedProtectedDescriptor = em.unwrap(ServerSession.class).getDescriptor(ForceProtectedEntityWithComposite.class); |
| ClassDescriptor protectedEmbeddableDesc = forcedProtectedDescriptor.getMappingForAttributeName("protectedEmbeddable").getReferenceDescriptor(); |
| ClassDescriptor sharedEmbeddableDesc = forcedProtectedDescriptor.getMappingForAttributeName("sharedEmbeddable").getReferenceDescriptor(); |
| assertFalse("Isolation of Entity not altered when embeddable has noncacheable relationship", forcedProtectedDescriptor.isSharedIsolation()); |
| assertFalse("Isolation of Embeddable not altered when embeddable has noncacheable relationship", protectedEmbeddableDesc.isSharedIsolation()); |
| assertFalse("Isolation of Embeddable not altered when Parent Entity is Protected", sharedEmbeddableDesc.isSharedIsolation()); |
| } |
| |
| public void testEmbeddableProtectedCaching(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| ForceProtectedEntityWithComposite cte = em.find(ForceProtectedEntityWithComposite.class, m_forcedProtectedEntityCompositId); |
| CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| ProtectedEmbeddable pe = cte.getProtectedEmbeddable(); |
| |
| ServerSession session = em.unwrap(ServerSession.class); |
| commitTransaction(em); |
| closeEM(em); |
| ForceProtectedEntityWithComposite cachedCPE = (ForceProtectedEntityWithComposite) session.getIdentityMapAccessor().getFromIdentityMap(cte); |
| CacheableRelationshipsEntity cachedCRE = (CacheableRelationshipsEntity) session.getIdentityMapAccessor().getFromIdentityMap(cre); |
| assertNotNull("ForceProtectedEntityWithComposite was not found in the cache", cachedCPE); |
| assertNotNull("CacheableRelationshipsEntity was not found in the cache", cachedCRE); |
| cachedCPE.getProtectedEmbeddable().setName("NewName"+System.currentTimeMillis()); |
| //following code is commented out due to bug 336651 |
| //cachedCRE.getProtectedEmbeddables().get(0).setName("NewName"+System.currentTimeMillis()); |
| em = createDSEntityManager(); |
| beginTransaction(em); |
| ForceProtectedEntityWithComposite managedCPE = em.find(ForceProtectedEntityWithComposite.class, cte.getId()); |
| CacheableRelationshipsEntity managedCRE = em.find(CacheableRelationshipsEntity.class, cre.getId()); |
| assertEquals("Cache was not used for Protected Isolation", cachedCPE.getProtectedEmbeddable().getName(),managedCPE.getProtectedEmbeddable().getName()); |
| //follwoing code is commented out due to bug 336651 |
| //assertEquals("Cache was not used for Protected Isolation", cachedCRE.getProtectedEmbeddables().get(0).getName(),managedCRE.getProtectedEmbeddables().get(0).getName()); |
| } finally { |
| rollbackTransaction(em); |
| closeEM(em); |
| } |
| } |
| |
| // Bug 347168 |
| public void testEmbeddableProtectedReadOnly(){ |
| EntityManager em = createDSEntityManager(); |
| Map properties = new HashMap(); |
| properties.put(QueryHints.READ_ONLY, "true"); |
| ForceProtectedEntityWithComposite cte = null; |
| try{ |
| cte = em.find(ForceProtectedEntityWithComposite.class, m_forcedProtectedEntityCompositId, properties); |
| } catch (Exception e){ |
| fail("Exception while trying to do a read-only find to an protected entity with an embeddable: " + e.getMessage()); |
| } |
| assertNotNull("Protected entity did not have aggregate when read back.", cte.getProtectedEmbeddable()); |
| } |
| |
| public void testProtectedCaching(){ |
| //Nested transaction not supported |
| if (! isOnServer()) { |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| CacheableForceProtectedEntity cte = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| CacheableFalseEntity cfe = cte.getCacheableFalse(); |
| CacheableProtectedEntity cpe = cfe.getProtectedEntity(); |
| CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| List<CacheableProtectedEntity> cacheableProtects = cre.getCacheableProtecteds(); |
| CacheableForceProtectedEntity cfpe = cre.getCacheableFPE(); |
| ServerSession session = em.unwrap(ServerSession.class); |
| closeEM(em); |
| CacheableProtectedEntity cachedCPE = (CacheableProtectedEntity) session.getIdentityMapAccessor().getFromIdentityMap(cpe); |
| assertNotNull("CacheableProtectedEntity was not found in the cache", cachedCPE); |
| CacheableForceProtectedEntity cachedCFPE = (CacheableForceProtectedEntity) session.getIdentityMapAccessor().getFromIdentityMap(cfpe); |
| assertNotNull("CacheableForceProtectedEntity from ManyToOne relationship was not found in the cache", cachedCFPE); |
| for (CacheableProtectedEntity cpe1 : cacheableProtects){ |
| CacheableProtectedEntity cachedCPE1 = (CacheableProtectedEntity) session.getIdentityMapAccessor().getFromIdentityMap(cpe1); |
| assertNotNull("CacheableProtectedEntity from OneToMany relationship was not found in the cache", cachedCPE1); |
| } |
| cachedCPE.setName("NewName"+System.currentTimeMillis()); |
| cachedCFPE.setName("NewName"+System.currentTimeMillis()); |
| em = createDSEntityManager(); |
| beginTransaction(em); |
| CacheableProtectedEntity managedCPE = em.find(CacheableProtectedEntity.class, cpe.getId()); |
| CacheableForceProtectedEntity managedCFPE = em.find(CacheableForceProtectedEntity.class, cfpe.getId()); |
| assertEquals("Cache was not used for Protected Isolation", cachedCPE.getName(),managedCPE.getName()); |
| assertEquals("Cache was not used for Protected Isolation", cachedCFPE.getName(),managedCFPE.getName()); |
| }finally{ |
| rollbackTransaction(em); |
| closeEM(em); |
| } |
| } |
| } |
| |
| public void testProtectedRelationshipsMetadata(){ |
| EntityManager em = createDSEntityManager(); |
| ServerSession session = em.unwrap(ServerSession.class); |
| ClassDescriptor descriptor = session.getDescriptor(ProtectedRelationshipsEntity.class); |
| for (DatabaseMapping mapping : descriptor.getMappings()){ |
| if (!mapping.isDirectToFieldMapping()){ |
| assertTrue("Relationship NONCacheable metadata was not processed correctly", !mapping.isCacheable()); |
| } |
| } |
| descriptor = session.getDescriptorForAlias("XML_ROTECTED_RELATIONSHIPS"); |
| for (DatabaseMapping mapping : descriptor.getMappings()){ |
| if (!mapping.isDirectToFieldMapping()){ |
| assertTrue("Relationship NONCacheable metadata was not processed correctly", !mapping.isCacheable()); |
| } |
| } |
| closeEM(em); |
| |
| } |
| |
| public void testReadOnlyTree(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| Query q = em.createQuery("Select c from JPA_CACHEABLE_FORCE_PROTECTED c"); |
| q.setHint(QueryHints.READ_ONLY, "true"); |
| CacheableForceProtectedEntity cte = (CacheableForceProtectedEntity) q.getResultList().get(0); |
| assertNotNull("Did not load the CacheableTrue Entity", cte); |
| CacheableFalseEntity cfe = cte.getCacheableFalse(); |
| assertNotNull("Did not load the CacheableFalse related Entity", cfe); |
| CacheableProtectedEntity cpe = cfe.getProtectedEntity(); |
| assertNotNull("Did not load the Cacheable Protected related Entity", cpe); |
| Query q1 = em.createQuery("Select c from JPA_CACHEABLE_RELATIONSHIPS c"); |
| q1.setHint(QueryHints.READ_ONLY, "true"); |
| CacheableRelationshipsEntity cre = (CacheableRelationshipsEntity) q1.getResultList().get(0); |
| for (CacheableFalseEntity cfe1 : cre.getCacheableFalses()){ |
| assertNotNull("Did not load the CacheableFalse related Entity in OneToMany relationship", cfe1); |
| } |
| for (CacheableProtectedEntity cpe1 : cre.getCacheableProtecteds()){ |
| assertNotNull("Did not load the CacheableProtected related Entity in OneToMany relationship", cpe1); |
| } |
| CacheableForceProtectedEntity cfpe = cre.getCacheableFPE(); |
| assertNotNull("Did not load the Cacheable Force Protected related Entity in ManyToOne relationship", cfpe); |
| for (CacheableFalseDetail cfde : cre.getCacheableFalseDetails()){ |
| assertNotNull("Did not load the CacheableFalse Details related Entity in ManyToMany relationship", cfde); |
| } |
| }finally{ |
| rollbackTransaction(em); |
| closeEM(em); |
| } |
| } |
| |
| public void testUpdateForceProtectedOneToOne(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| int cfeID = 0; |
| try{ |
| CacheableForceProtectedEntity cte = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| CacheableFalseEntity oldcfe = cte.getCacheableFalse(); |
| ServerSession session = em.unwrap(ServerSession.class); |
| CacheableFalseEntity cfe = new CacheableFalseEntity(); |
| em.persist(cfe); |
| cfeID = cfe.getId(); |
| cte.setCacheableFalse(cfe); |
| commitTransaction(em); |
| CacheableForceProtectedEntity cachedCPE = (CacheableForceProtectedEntity) session.getIdentityMapAccessor().getFromIdentityMap(cte); |
| assertNull("A protected OneToOne relationship was merged into the shared cache", cachedCPE.getCacheableFalse()); |
| ObjectReferenceMapping orm = (ObjectReferenceMapping) session.getDescriptor(CacheableForceProtectedEntity.class).getMappingForAttributeName("cacheableFalse"); |
| Object cacheableFalsefk = session.getIdentityMapAccessorInstance().getCacheKeyForObject(cte).getProtectedForeignKeys().get(orm.getSelectFields().get(0)); |
| assertEquals("FK update not cached", cfe.getId(), cacheableFalsefk); |
| beginTransaction(em); |
| cte.setCacheableFalse(oldcfe); |
| cfe = em.find(CacheableFalseEntity.class, cfeID); |
| em.remove(cfe); |
| commitTransaction(em); |
| }finally{ |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEM(em); |
| } |
| } |
| |
| public void testUpdateForceProtectedBasic(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| CacheableForceProtectedEntity cte = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| String newName = "SomeNewName" + System.currentTimeMillis(); |
| cte.setName(newName); |
| commitTransaction(em); |
| ServerSession session = em.unwrap(ServerSession.class); |
| CacheableForceProtectedEntity cachedCPE = (CacheableForceProtectedEntity) session.getIdentityMapAccessor().getFromIdentityMap(cte); |
| assertEquals("A Basic mapping in a Protected class was not merged into the shared cache. Expected: "+ newName + " found: "+ cachedCPE.getName(), cachedCPE.getName(), newName); |
| }finally{ |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEM(em); |
| } |
| } |
| |
| public void testUpdateProtectedBasic(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| CacheableProtectedEntity cte = em.find(CacheableProtectedEntity.class, m_cacheableProtectedEntityId); |
| ServerSession session = em.unwrap(ServerSession.class); |
| String newName = "SomeNewName" + System.currentTimeMillis(); |
| cte.setName(newName); |
| commitTransaction(em); |
| CacheableProtectedEntity cachedCPE = (CacheableProtectedEntity) session.getIdentityMapAccessor().getFromIdentityMap(cte); |
| assertEquals("A Basic mapping in a Protected class was not merged into the shared cache", newName, cachedCPE.getName()); |
| }finally{ |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEM(em); |
| } |
| } |
| |
| public void testUpdateProtectedOneToMany(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| int cfeID = 0; |
| try{ |
| CacheableForceProtectedEntity cte = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| ServerSession session = em.unwrap(ServerSession.class); |
| CacheableProtectedEntity cfe = new CacheableProtectedEntity(); |
| em.persist(cfe); |
| cfeID = cfe.getId(); |
| cfe.setForcedProtected(cte); |
| cte.getCacheableProtecteds().add(cfe); |
| commitTransaction(em); |
| |
| CacheableForceProtectedEntity cachedCPE = (CacheableForceProtectedEntity) session.getIdentityMapAccessor().getFromIdentityMap(cte); |
| assertFalse("A protected OneToMany relationship was not merged into the shared cache", cachedCPE.getCacheableProtecteds() == null || cachedCPE.getCacheableProtecteds().isEmpty()); |
| beginTransaction(em); |
| cte.getCacheableProtecteds().clear(); |
| cfe.setForcedProtected(null); |
| cfe = em.find(CacheableProtectedEntity.class, cfeID); |
| em.remove(cfe); |
| commitTransaction(em); |
| }finally{ |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEM(em); |
| } |
| } |
| |
| public void testUpdateProtectedManyToOne(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| int creID = 0; |
| try{ |
| CacheableForceProtectedEntity cfpe = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| ServerSession session = em.unwrap(ServerSession.class); |
| CacheableRelationshipsEntity cre = new CacheableRelationshipsEntity(); |
| em.persist(cre); |
| creID = cre.getId(); |
| cre.setCacheableFPE(cfpe); |
| commitTransaction(em); |
| |
| CacheableRelationshipsEntity cachedCRE = (CacheableRelationshipsEntity) session.getIdentityMapAccessor().getFromIdentityMap(cre); |
| assertFalse("A protected ManyToOne relationship was not merged into the shared cache", cachedCRE.getCacheableFPE() == null); |
| beginTransaction(em); |
| cre = em.find(CacheableRelationshipsEntity.class, creID); |
| em.remove(cre); |
| commitTransaction(em); |
| }finally{ |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEM(em); |
| } |
| } |
| |
| public void testUpdateProtectedManyToMany(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| int cfdID1 = 0, cfdID2 = 0; |
| try{ |
| CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| ServerSession session = em.unwrap(ServerSession.class); |
| CacheableFalseDetail cfd1 = new CacheableFalseDetail(); |
| CacheableFalseDetail cfd2 = new CacheableFalseDetail(); |
| em.persist(cfd1); |
| em.persist(cfd2); |
| cfdID1 = cfd1.getId(); |
| cfdID2 = cfd2.getId(); |
| cre.addCacheableFalseDetail(cfd1); |
| cre.addCacheableFalseDetail(cfd2); |
| commitTransaction(em); |
| |
| CacheableRelationshipsEntity cachedCRE = (CacheableRelationshipsEntity) session.getIdentityMapAccessor().getFromIdentityMap(cre); |
| assertTrue("A protected ManyToMany relationship was merged into the shared cache", cachedCRE.getCacheableFalseDetails() == null || cachedCRE.getCacheableFalseDetails().isEmpty()); |
| beginTransaction(em); |
| cre.getCacheableFalseDetails().clear(); |
| cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| cfd1 = em.find(CacheableFalseDetail.class, cfdID1); |
| cfd2 = em.find(CacheableFalseDetail.class, cfdID2); |
| cre.removeCacheableFalseDetail(cfd1); |
| cre.removeCacheableFalseDetail(cfd2); |
| em.remove(cfd1); |
| em.remove(cfd2); |
| commitTransaction(em); |
| }finally{ |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEM(em); |
| } |
| } |
| |
| public void testUpdateProtectedElementCollection(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| ServerSession session = em.unwrap(ServerSession.class); |
| ProtectedEmbeddable cem1 = new ProtectedEmbeddable(); |
| ProtectedEmbeddable cem2 = new ProtectedEmbeddable(); |
| cre.addProtectedEmbeddable(cem1); |
| cre.addProtectedEmbeddable(cem2); |
| commitTransaction(em); |
| |
| CacheableRelationshipsEntity cachedCRE = (CacheableRelationshipsEntity) session.getIdentityMapAccessor().getFromIdentityMap(cre); |
| assertTrue("A protected ElementCollection relationship was merged into the shared cache", cachedCRE.getProtectedEmbeddables() == null || cachedCRE.getProtectedEmbeddables().isEmpty()); |
| beginTransaction(em); |
| cre.getProtectedEmbeddables().clear(); |
| commitTransaction(em); |
| }finally{ |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEM(em); |
| } |
| } |
| |
| //Bug #530680 |
| public void testUpdateSharedElementCollection() { |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| ServerSession session = em.unwrap(ServerSession.class); |
| SharedEmbeddable cem1 = new SharedEmbeddable(); |
| cem1.setName("origName1"); |
| SharedEmbeddable cem2 = new SharedEmbeddable(); |
| cem2.setName("origName2"); |
| cre.addSharedEmbeddable(cem1); |
| cre.addSharedEmbeddable(cem2); |
| commitTransaction(em); |
| |
| CacheableRelationshipsEntity cachedCRE = (CacheableRelationshipsEntity) session.getIdentityMapAccessor().getFromIdentityMap(cre); |
| assertTrue("A shared ElementCollection relationship was not merged into the shared cache", cachedCRE.getSharedEmbeddables() != null && !cachedCRE.getSharedEmbeddables().isEmpty()); |
| |
| CacheableRelationshipsEntity cre2 = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| beginTransaction(em); |
| em.detach(cre2); |
| cre2.getSharedEmbeddables().remove(0); |
| em.merge(cre2); |
| commitTransaction(em); |
| |
| session = em.unwrap(ServerSession.class); |
| CacheableRelationshipsEntity cachedCRE2 = (CacheableRelationshipsEntity) session.getIdentityMapAccessor().getFromIdentityMap(cre2); |
| assertEquals("Changes in shared ElementCollection relationship were not merged into the shared cache", 1, cachedCRE2.getSharedEmbeddables().size()); |
| |
| beginTransaction(em); |
| cre.getSharedEmbeddables().clear(); |
| commitTransaction(em); |
| }finally{ |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| closeEM(em); |
| } |
| } |
| |
| public void testIsolationBeforeEarlyTxBegin(){ |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| int cfeID = 0; |
| try { |
| CacheableForceProtectedEntity cte = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| ServerSession session = em.unwrap(ServerSession.class); |
| CacheableProtectedEntity cfe = new CacheableProtectedEntity(); |
| em.persist(cfe); |
| cfeID = cfe.getId(); |
| cfe.setForcedProtected(cte); |
| cte.getCacheableProtecteds().add(cfe); |
| commitTransaction(em); |
| |
| CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId); |
| assertNotNull("CacheableRelationshipsEntity from find should not be null", cre); |
| CacheableRelationshipsEntity cachedCRE = (CacheableRelationshipsEntity) session.getIdentityMapAccessor().getFromIdentityMap(cre); |
| assertNotNull("CacheableRelationshipsEntity from cache should not be null", cachedCRE); |
| assertTrue("A protected OneToMany relationship was merged into the shared cache", cachedCRE.getCacheableFalses() == null || cachedCRE.getCacheableFalses().isEmpty()); |
| } finally { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| try { |
| beginTransaction(em); |
| |
| CacheableForceProtectedEntity cte = em.find(CacheableForceProtectedEntity.class, m_cacheableForceProtectedEntity1Id); |
| CacheableProtectedEntity cfe = em.find(CacheableProtectedEntity.class, cfeID); |
| cte.getCacheableProtecteds().clear(); |
| cfe.setForcedProtected(null); |
| em.remove(cfe); |
| |
| commitTransaction(em); |
| } catch (Exception e) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| } |
| closeEM(em); |
| } |
| } |
| |
| /** |
| * Convenience method. This will not update the entity in the shared cache. |
| */ |
| protected void updateCacheableTrueEntityNameAndBypassStore(String name) { |
| EntityManager em = createDSEntityManager(); |
| |
| try { |
| beginTransaction(em); |
| Query query = em.createQuery("UPDATE JPA_CACHEABLE_TRUE e SET e.name = :name " + "WHERE e.id = :id ").setParameter("name", name).setParameter("id", m_cacheableTrueEntity1Id); |
| query.setHint(QueryHints.CACHE_STORE_MODE, CacheStoreMode.BYPASS); |
| query.executeUpdate(); |
| commitTransaction(em); |
| } catch (Exception e) { |
| fail("Error updating the entity through JPQL: " + e); |
| } finally { |
| closeEM(em); |
| } |
| } |
| |
| /** |
| * Convenience method. This will update the entity in the shared cache. |
| */ |
| protected void updateCacheableTrueEntityNameInSharedCache(String name) { |
| updateCacheableTrueEntityNameInSharedCache(name, null); |
| } |
| |
| /** |
| * Convenience method. This will update the entity in the shared cache. |
| */ |
| protected void updateCacheableTrueEntityNameInSharedCache(String name, EntityManager em) { |
| EntityManager emToUse; |
| |
| if (em == null) { |
| emToUse = createDSEntityManager(); |
| } else { |
| emToUse = em; |
| } |
| |
| try { |
| beginTransaction(emToUse); |
| emToUse.createQuery("UPDATE JPA_CACHEABLE_TRUE e SET e.name = :name " + "WHERE e.id = :id ").setParameter("name", name).setParameter("id", m_cacheableTrueEntity1Id).executeUpdate(); |
| commitTransaction(emToUse); |
| } catch (Exception e) { |
| fail("Error updating the entity through JPQL: " + e); |
| } finally { |
| if (em == null) { |
| closeEM(emToUse); |
| } |
| } |
| } |
| |
| // Bug 345478 - Incorrect foreign key parameter set when retrieving an eager @OneToMany |
| public void testMergeNonCachedWithRelationship(){ |
| // create entity and details, persist them |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| CacheableFalseEntity entity = new CacheableFalseEntity(); |
| em.persist(entity); |
| commitTransaction(em); |
| em.clear(); |
| CacheableFalseDetailWithBackPointer detail = null; |
| try{ |
| detail = new CacheableFalseDetailWithBackPointer(); |
| detail.setEntity(entity); |
| List<CacheableFalseDetailWithBackPointer> details = new ArrayList<CacheableFalseDetailWithBackPointer>(); |
| details.add(detail); |
| entity.setDetailsBackPointer(details); |
| detail.setDescription("test"); |
| beginTransaction(em); |
| detail = em.merge(detail); |
| commitTransaction(em); |
| |
| beginTransaction(em); |
| detail = em.find(detail.getClass(), detail.getId()); |
| em.refresh(detail); |
| commitTransaction(em); |
| |
| assertTrue("detail does not have it's entity.", detail.getEntity() != null); |
| assertTrue("detail's entity does not have the backpointer.", detail.getEntity().getDetailsBackPointer().size() == 1); |
| } finally { |
| beginTransaction(em); |
| detail = em.merge(detail); |
| em.remove(detail.getEntity()); |
| em.remove(detail); |
| commitTransaction(em); |
| closeEM(em); |
| } |
| |
| } |
| |
| // Bug392542 - Test Foreign Key update of detached while merging new object with |
| // reference to a detatched object with cascade merge. |
| public void testForeignKeyUpdateInNonCachedOnMergeNewObject(){ |
| // create entity and details, persist them |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| try{ |
| CacheableFalseDetailWithBackPointer detail = new CacheableFalseDetailWithBackPointer(); |
| detail.setDescription("test"); |
| detail = em.merge(detail); |
| em.flush(); |
| |
| em.clear(); |
| |
| CacheableFalseEntity entity = new CacheableFalseEntity(); |
| List<CacheableFalseDetailWithBackPointer> details = new ArrayList<CacheableFalseDetailWithBackPointer>(); |
| details.add(detail); |
| entity.setDetailsBackPointer(details); |
| detail.setEntity(entity); |
| entity = em.merge(entity); |
| em.flush(); |
| |
| em.clear(); |
| |
| // Verify Foreign Key Update. |
| CacheableFalseDetailWithBackPointer falseDetail = em.find(detail.getClass(), detail.getId()); |
| |
| assertTrue("Foreign Key is not updated in detail.", falseDetail.getEntity() != null); |
| assertTrue("Foreign Key updated, but doesn't match.", falseDetail.getEntity().getId() == entity.getId()); |
| } finally { |
| rollbackTransaction(em); |
| closeEM(em); |
| |
| } |
| } |
| |
| // Bug 347190 |
| public void testIndirectCollectionRefreshBehavior(){ |
| QuerySQLTracker counter = new QuerySQLTracker(getServerSession()); |
| EntityManager em = createEntityManager(); |
| try{ |
| beginTransaction(em); |
| |
| CacheableFalseEntity entity = new CacheableFalseEntity(); |
| CacheableFalseDetailWithBackPointer detail = new CacheableFalseDetailWithBackPointer(); |
| |
| List<CacheableFalseDetailWithBackPointer> details = new ArrayList<CacheableFalseDetailWithBackPointer>(); |
| details.add(detail); |
| entity.setDetailsBackPointer(details); |
| detail.setEntity(entity); |
| |
| em.persist(entity); |
| |
| em.flush(); |
| em.clear(); |
| counter.getSqlStatements().clear(); |
| Query query = em.createQuery("SELECT e from JPA_CACHEABLE_FALSE e where e.id = :id").setParameter("id", entity.getId()); |
| query.setHint(QueryHints.REFRESH, HintValues.TRUE); |
| entity = (CacheableFalseEntity)query.getResultList().get(0); |
| IndirectList list = (IndirectList)entity.getDetailsBackPointer(); |
| assertFalse(list.isInstantiated()); |
| assertEquals(2, counter.getSqlStatements().size()); |
| } finally{ |
| rollbackTransaction(em); |
| counter.remove(); |
| closeEntityManager(em); |
| } |
| } |
| |
| // Bug 352533 |
| public void testDerivedIDProtectedRead(){ |
| EntityManager em = createEntityManager(); |
| CacheableFalseEntity cf = null; |
| CacheableTrueDerivedIDEntity ctdid = null; |
| try{ |
| beginTransaction(em); |
| cf = new CacheableFalseEntity(); |
| em.persist(cf); |
| em.flush(); |
| |
| ctdid = new CacheableTrueDerivedIDEntity("desc1", cf); |
| em.persist(ctdid); |
| commitTransaction(em); |
| em.clear(); |
| |
| ctdid = em.find(CacheableTrueDerivedIDEntity.class, new CacheableTrueDerivedIDPK(ctdid.getPk().getDescription(), cf.getId())); |
| assertNotNull("The protected cached relationship was not properly retrieved", ctdid.getCacheableFalse()); |
| } finally { |
| if (isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| beginTransaction(em); |
| cf = em.find(CacheableFalseEntity.class, cf.getId()); |
| ctdid = em.find(ctdid.getClass(), ctdid.getPk()); |
| em.remove(cf); |
| em.remove(ctdid); |
| commitTransaction(em); |
| } |
| |
| } |
| |
| //Bug 408262 - Refresh of Protected Entity in early transaction refreshes Entity in shared cache |
| public void testRefreshProtectedEntityInEarlyTransaction() { |
| CacheableForceProtectedEntity entity = null; |
| try { |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| |
| entity = new CacheableForceProtectedEntity(); |
| entity.setName("original"); |
| |
| em.persist(entity); |
| assertEquals("original", entity.getName()); |
| |
| commitTransaction(em); |
| assertEquals("original", entity.getName()); |
| |
| em = createDSEntityManager(); |
| beginTransaction(em); |
| |
| entity = em.find(CacheableForceProtectedEntity.class, entity.getId()); |
| entity.setName("modified"); |
| |
| em.flush(); |
| |
| em.refresh(entity); // problem occurs in refresh |
| assertNotNull(entity); |
| assertEquals("modified", entity.getName()); |
| |
| rollbackTransaction(em); |
| |
| em = createDSEntityManager(); |
| |
| entity = em.find(CacheableForceProtectedEntity.class, entity.getId()); |
| |
| closeEM(em); |
| |
| assertNotNull(entity); |
| assertEquals("Entity found should have an unmodified name post-rollback", "original", entity.getName()); |
| } finally { |
| if (entity != null) { |
| EntityManager em = createDSEntityManager(); |
| beginTransaction(em); |
| entity = em.find(CacheableForceProtectedEntity.class, entity.getId()); |
| if (entity != null) { |
| em.remove(entity); |
| } |
| commitTransaction(em); |
| closeEM(em); |
| } |
| } |
| } |
| |
| /** |
| * Test caching with <code>@Cacheable(false)</code> in parent class, <code>@Cacheable(true)</code> in child class |
| * and another child class which just inherits <code>@Cacheable</code> value from parent class. |
| * There is following class structure with <code>@Cacheable</code> settings:<ul> |
| * <li><code>ProductFalse</code> with <code>@Cacheable(false)</code></li> |
| * <li><code>ProductHardwareTrue</code> with <code>@Cacheable(false)</code> extends <code>ProductFalse</code></li> |
| * <li><code>ProductSoftwareFalse</code> with <code>@Cacheable</code> value inherited from parent extends <code>ProductFalse</code></li></ul> |
| * Abstract code to be reused in child test classes to verify caching for ENABLE_SELECTIVE |
| * and DISABLE_SELECTIVE shared cache mode. |
| */ |
| protected void runTestCacheableInheritanceBasedOnFalse(EntityManagerFactory emf, EntityManager em) { |
| try { |
| assertNotNull("Could not create EntityManager", em); |
| EntityTransaction tx = em.getTransaction(); |
| assertNotNull("Could not get transaction", tx); |
| tx.begin(); |
| ProductFalse pf = new ProductFalse(1, 2); |
| em.persist(pf); |
| ProductHardwareTrue pht = new ProductHardwareTrue(2, 3, 1); |
| em.persist(pht); |
| ProductSoftwareFalse psf = new ProductSoftwareFalse(3, 2, 1); |
| em.persist(psf); |
| em.flush(); |
| tx.commit(); |
| int pfId = pf.getId(); |
| int phtId = pht.getId(); |
| int psfId = psf.getId(); |
| Cache cache = emf.getCache(); |
| assertNotNull("Could not get cache", cache); |
| boolean isPf = cache.contains(ProductFalse.class, pfId); |
| boolean isPht = cache.contains(ProductHardwareTrue.class, phtId); |
| boolean isPsf = cache.contains(ProductSoftwareFalse.class, psfId); |
| assertFalse("ProductFalse with @Cacheable(false) shall not be in the cache.", isPf); |
| assertTrue("ProductHardwareTrue with @Cacheable(false) shall be in the cache.", isPht); |
| assertFalse("ProductSoftwareFalse with @Cacheable inherited as false shall not be in the cache.", isPsf); |
| } finally { |
| if (em != null) { |
| em.close(); |
| } |
| } |
| } |
| |
| /** |
| * Test caching with <code>@Cacheable(true)</code> in parent class, <code>@Cacheable(false)</code> in child class |
| * and another child class which just inherits <code>@Cacheable</code> value from parent class. |
| * There is following class structure with <code>@Cacheable</code> settings:<ul> |
| * <li><code>ProductTrue</code> with <code>@Cacheable(true)</code></li> |
| * <li><code>ProductHardwareTrue</code> with <code>@Cacheable(false)</code> extends <code>ProductTrue</code></li> |
| * <li><code>ProductSoftwareFalse</code> with <code>@Cacheable</code> value inherited from parent extends <code>ProductTrue</code></li></ul> |
| * Abstract code to be reused in child test classes to verify caching for ENABLE_SELECTIVE |
| * and DISABLE_SELECTIVE shared cache mode. |
| */ |
| protected void runTestCacheableInheritanceBasedOnTrue(EntityManagerFactory emf, EntityManager em) { |
| try { |
| assertNotNull("Could not create EntityManager", em); |
| EntityTransaction tx = em.getTransaction(); |
| assertNotNull("Could not get transaction", tx); |
| tx.begin(); |
| ProductTrue pt = new ProductTrue(1, 2); |
| em.persist(pt); |
| ProductHardwareFalse phf = new ProductHardwareFalse(2, 3, 1); |
| em.persist(phf); |
| ProductSoftwareTrue pst = new ProductSoftwareTrue(3, 2, 1); |
| em.persist(pst); |
| em.flush(); |
| tx.commit(); |
| int ptId = pt.getId(); |
| int phfId = phf.getId(); |
| int pstId = pst.getId(); |
| Cache cache = emf.getCache(); |
| assertNotNull("Could not get cache", cache); |
| boolean isPt = cache.contains(ProductTrue.class, ptId); |
| boolean isPhf = cache.contains(ProductHardwareFalse.class, phfId); |
| boolean isPst = cache.contains(ProductSoftwareTrue.class, pstId); |
| assertTrue("ProductTrue with @Cacheable(true) shall be in the cache.", isPt); |
| assertFalse("ProductHardwareFalse with @Cacheable(true) shall not be in the cache.", isPhf); |
| assertTrue("ProductSoftwareTrue with @Cacheable inherited as false shall be in the cache.", isPst); |
| } finally { |
| if (em != null) { |
| em.close(); |
| } |
| } |
| } |
| |
| /** |
| * Convenience method. |
| */ |
| protected boolean usesNoCache(ClassDescriptor descriptor) { |
| return descriptor.isIsolated(); |
| } |
| } |