Index: resource/eclipselink-cacheable-model/server/persistence.xml
===================================================================
--- resource/eclipselink-cacheable-model/server/persistence.xml (revision 9150)
+++ resource/eclipselink-cacheable-model/server/persistence.xml (working copy)
@@ -96,7 +96,11 @@
org.eclipse.persistence.testing.models.jpa.cacheable.SubCacheableFalseEntity
org.eclipse.persistence.testing.models.jpa.cacheable.SubCacheableNoneEntity
org.eclipse.persistence.testing.models.jpa.cacheable.CacheableForceProtectedEntity
- org.eclipse.persistence.testing.models.jpa.cacheable.ProtectedRelationsipsEntity
+ org.eclipse.persistence.testing.models.jpa.cacheable.ProtectedRelationshipsEntity
+ org.eclipse.persistence.testing.models.jpa.cacheable.ForceProtectedEntityWithComposite
+ org.eclipse.persistence.testing.models.jpa.cacheable.ProtectedEmbeddable
+ org.eclipse.persistence.testing.models.jpa.cacheable.SharedEmbeddable
+ org.eclipse.persistence.testing.models.jpa.cacheable.CacheableRelationshipsEntity
true
DISABLE_SELECTIVE
Index: src/org/eclipse/persistence/testing/models/jpa/cacheable/CacheableRelationshipsEntity.java
===================================================================
--- src/org/eclipse/persistence/testing/models/jpa/cacheable/CacheableRelationshipsEntity.java (revision 9150)
+++ src/org/eclipse/persistence/testing/models/jpa/cacheable/CacheableRelationshipsEntity.java (working copy)
@@ -134,6 +134,9 @@
public void addCacheableFalseDetail(CacheableFalseDetail cacheableFalseDetail) {
cacheableFalseDetails.add(cacheableFalseDetail);
}
+ public void removeCacheableFalseDetail(CacheableFalseDetail cacheableFalseDetail) {
+ getCacheableFalseDetails().remove(cacheableFalseDetail);
+ }
/* element collection with ebeddable (false protected)*/
@ElementCollection
@CollectionTable(
Index: src/org/eclipse/persistence/testing/tests/jpa/cacheable/CacheableModelJunitTestAll.java
===================================================================
--- src/org/eclipse/persistence/testing/tests/jpa/cacheable/CacheableModelJunitTestAll.java (revision 9150)
+++ src/org/eclipse/persistence/testing/tests/jpa/cacheable/CacheableModelJunitTestAll.java (working copy)
@@ -17,11 +17,18 @@
******************************************************************************/
package org.eclipse.persistence.testing.tests.jpa.cacheable;
+import java.util.List;
+import java.util.ArrayList;
import junit.framework.*;
+import javax.persistence.EntityManager;
+
+import org.eclipse.persistence.config.EntityManagerProperties;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
+import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableFalseEntity;
+import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableFalseDetail;
import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableTableCreator;
/*
@@ -50,6 +57,8 @@
if (! JUnitTestCase.isJPA10()) {
suite.addTest(new CacheableModelJunitTestAll("testSetup"));
suite.addTest(new CacheableModelJunitTestAll("testCachingOnALL"));
+ suite.addTest(new CacheableModelJunitTestAll("testDetailsOrder_Shared"));
+ suite.addTest(new CacheableModelJunitTestAll("testDetailsOrder_Shared_BeginEarlyTransaction"));
}
return suite;
}
@@ -96,7 +105,115 @@
ClassDescriptor xmlNoneSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_NONE");
assertFalse("SubCacheableTrueEntity (ALL) from XML has caching turned off", usesNoCache(xmlNoneSubEntityDescriptor));
}
+
+ 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 ? "MulitPU-1" : "NONE";
+ 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 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);
+ }
+ }
+ }
+
/**
* Convenience method.
*/
Index: src/org/eclipse/persistence/testing/tests/jpa/cacheable/CacheableModelJunitTestDisableSelective.java
===================================================================
--- src/org/eclipse/persistence/testing/tests/jpa/cacheable/CacheableModelJunitTestDisableSelective.java (revision 9150)
+++ src/org/eclipse/persistence/testing/tests/jpa/cacheable/CacheableModelJunitTestDisableSelective.java (working copy)
@@ -18,6 +18,7 @@
package org.eclipse.persistence.testing.tests.jpa.cacheable;
import java.util.HashMap;
+import java.util.List;
import javax.persistence.CacheRetrieveMode;
import javax.persistence.CacheStoreMode;
@@ -29,14 +30,24 @@
import org.eclipse.persistence.config.CacheUsage;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.descriptors.ClassDescriptor;
+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.junit.JUnitTestCase;
import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableTableCreator;
import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableTrueEntity;
+import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableFalseDetail;
import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableFalseEntity;
+import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableProtectedEntity;
+import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableForceProtectedEntity;
import org.eclipse.persistence.testing.models.jpa.cacheable.ChildCacheableFalseEntity;
import org.eclipse.persistence.testing.models.jpa.cacheable.SubCacheableFalseEntity;
import org.eclipse.persistence.testing.models.jpa.cacheable.SubCacheableNoneEntity;
+import org.eclipse.persistence.testing.models.jpa.cacheable.ForceProtectedEntityWithComposite;
+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;
/*
* The test is testing against "MulitPU-4" persistence unit which has to be DISABLE_SELECTIVE
@@ -45,6 +56,10 @@
private static int m_cacheableTrueEntity1Id;
private static int m_cacheableTrueEntity2Id;
private static int m_childCacheableFalseEntityId;
+ private static int m_cacheableForceProtectedEntity1Id;
+ private static int m_cacheableProtectedEntityId;
+ private static int m_forcedProtectedEntityCompositId;
+ private static int m_cacheableRelationshipsEntityId;
public CacheableModelJunitTestDisableSelective() {
super();
@@ -195,6 +210,25 @@
suite.addTest(new CacheableModelJunitTestDisableSelective("testEMPropertiesOnCommit1"));
suite.addTest(new CacheableModelJunitTestDisableSelective("testEMPropertiesOnCommit2"));
suite.addTest(new CacheableModelJunitTestDisableSelective("testInheritanceCacheable"));
+
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testLoadMixedCacheTree"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testIsolatedIsolation"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testProtectedIsolation"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testProtectedCaching"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testReadOnlyTree"));
+
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testUpdateForceProtectedBasic"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testUpdateForceProtectedOneToOne"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testUpdateProtectedBasic"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testUpdateProtectedOneToMany"));
+
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testProtectedRelationshipsMetadata"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testForceProtectedFromEmbeddable"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testEmbeddableProtectedCaching"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testUpdateProtectedManyToOne"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testUpdateProtectedManyToMany"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testUpdateProtectedElementCollection"));
+ suite.addTest(new CacheableModelJunitTestDisableSelective("testIsolationBeforeEarlyTxBegin"));
}
return suite;
}
@@ -734,7 +768,21 @@
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);
@@ -745,6 +793,29 @@
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);
} catch (Exception e) {
fail("Error occurred creating some entities");
@@ -803,7 +874,432 @@
}
}
}
+
+ 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 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(){
+ //Nested transaction not supported
+ if (! isOnServer()) {
+ EntityManager em = createDSEntityManager();
+ beginTransaction(em);
+ try{
+ ForceProtectedEntityWithComposite cte = em.find(ForceProtectedEntityWithComposite.class, m_forcedProtectedEntityCompositId);
+ CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId);
+ System.out.println("====the size of the collection is 1--" + cre.getProtectedEmbeddables().size());
+ ProtectedEmbeddable pe = cte.getProtectedEmbeddable();
+
+ ServerSession session = em.unwrap(ServerSession.class);
+ 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());
+ System.out.println("====the size of the collection is 2--" + cachedCRE.getProtectedEmbeddables().size());
+ //follwoing 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);
+ }
+ }
+ }
+
+ 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);
+ assertTrue("A protected ManyToOne relationship was 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);
+ }
+ }
+
+ 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);
+ em.flush();
+ //commitTransaction(em);
+ CacheableRelationshipsEntity cre = em.find(CacheableRelationshipsEntity.class, m_cacheableRelationshipsEntityId);
+ CacheableRelationshipsEntity cachedCRE = (CacheableRelationshipsEntity) session.getIdentityMapAccessor().getFromIdentityMap(cre);
+ assertTrue("A protected OneToMany relationship was merged into the shared cache", cachedCRE.getCacheableFalses() == null || cachedCRE.getCacheableFalses().isEmpty());
+ commitTransaction(em);
+
+ 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 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 cacheableFalses = cre.getCacheableFalses();
+ assertNotNull("Did not load collections of CacheableRelationshipsEntity related(OneToMany) CacheableFalseEntity", cacheableFalses);
+ List 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 cacheableFalseDetails = cre.getCacheableFalseDetails();
+ assertNotNull("Did not load collections of CacheableRelationshipsEntity related(ManyToMany) CacheableFalseDetail", cacheableFalseDetails);
+ List 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 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()){
+ assertNull("An protected relationship in OneToMany was found in the shared cache", cpe1);
+ }
+ assertNull("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 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 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 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 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 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 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);
+ assertTrue("A protected OneToMany relationship was 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);
+ }
+ }
+
/**
* Convenience method.
*/
Index: src/org/eclipse/persistence/testing/tests/jpa/cacheable/CacheableModelJunitTestNone.java
===================================================================
--- src/org/eclipse/persistence/testing/tests/jpa/cacheable/CacheableModelJunitTestNone.java (revision 9150)
+++ src/org/eclipse/persistence/testing/tests/jpa/cacheable/CacheableModelJunitTestNone.java (working copy)
@@ -17,11 +17,18 @@
******************************************************************************/
package org.eclipse.persistence.testing.tests.jpa.cacheable;
+import java.util.List;
+import java.util.ArrayList;
import junit.framework.*;
+import javax.persistence.EntityManager;
+
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.sessions.server.ServerSession;
+import org.eclipse.persistence.config.EntityManagerProperties;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
+import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableFalseEntity;
+import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableFalseDetail;
import org.eclipse.persistence.testing.models.jpa.cacheable.CacheableTableCreator;
/*
@@ -50,6 +57,8 @@
if (! JUnitTestCase.isJPA10()) {
suite.addTest(new CacheableModelJunitTestNone("testSetup"));
suite.addTest(new CacheableModelJunitTestNone("testCachingOnNONE"));
+ suite.addTest(new CacheableModelJunitTestNone("testDetailsOrder_Isolated"));
+ suite.addTest(new CacheableModelJunitTestNone("testDetailsOrder_Isolated_BeginEarlyTransaction"));
}
return suite;
}
@@ -96,7 +105,115 @@
ClassDescriptor xmlNoneSubEntityDescriptor = session.getDescriptorForAlias("XML_SUB_CACHEABLE_NONE");
assertTrue("SubCacheableTrueEntity (NONE) from XML has caching turned on", usesNoCache(xmlNoneSubEntityDescriptor));
}
+
+ public void testDetailsOrder_Isolated() {
+ testDetailsOrder(false, false);
+ }
+ public void testDetailsOrder_Isolated_BeginEarlyTransaction() {
+ testDetailsOrder(false, 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" : "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 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);
+ }
+ }
+ }
+
/**
* Convenience method.
*/