You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2008/06/13 03:58:49 UTC

svn commit: r667312 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java

Author: ppoddar
Date: Thu Jun 12 18:58:49 2008
New Revision: 667312

URL: http://svn.apache.org/viewvc?rev=667312&view=rev
Log:
OPENJPA-610: Restored refresh() behavior for clean/new instances.

Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?rev=667312&r1=667311&r2=667312&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Thu Jun 12 18:58:49 2008
@@ -2733,7 +2733,7 @@
             endOperation();
         }
     }
-
+    
     public void refreshAll(Collection objs, OpCallbacks call) {
         if (objs == null || objs.isEmpty())
             return;
@@ -2742,10 +2742,14 @@
         try {
             assertNontransactionalRead();
 
-            for (Iterator itr = objs.iterator(); itr.hasNext();) {
+            for (Iterator itr = objs.iterator(); itr.hasNext();) 
                 gatherCascadeRefresh(itr.next(), call);
-            }
-            refreshInternal(_operating, call);
+            if (_operating.isEmpty())
+            	return;
+            if (_operating.size() == 1)
+            	refreshInternal(_operating.iterator().next(), call);
+            else
+            	refreshInternal(_operating, call);
         } finally {
             endOperation();
         }
@@ -2760,7 +2764,12 @@
             assertNontransactionalRead();
 
             gatherCascadeRefresh(obj, call);
-            refreshInternal(_operating, call);
+            if (_operating.isEmpty())
+            	return;
+            if (_operating.size() == 1)
+            	refreshInternal(_operating.iterator().next(), call);
+            else
+            	refreshInternal(_operating, call);
         } finally {
             endOperation();
         }
@@ -2797,7 +2806,7 @@
         List exceps = null;
         try {
             // collect instances that need a refresh
-            Collection load = new ArrayList(objs.size());
+            Collection load = null;
             StateManagerImpl sm;
             Object obj;
             for (Iterator itr = objs.iterator(); itr.hasNext();) {
@@ -2812,9 +2821,11 @@
                         continue;
 
                     if (sm != null) {
-                        if (sm.isDetached()) {
+                        if (sm.isDetached()) 
                             throw newDetachedException(obj, "refresh");
-                        } else if (sm.beforeRefresh(true)) {
+                        else if (sm.beforeRefresh(true)) {
+                        	if (load == null)
+                        		load = new ArrayList(objs.size());
                             load.add(sm);
                         }
                     } else if (assertPersistenceCapable(obj).pcIsDetached()
@@ -2826,7 +2837,7 @@
             }
 
             // refresh all
-            if (!load.isEmpty()) {
+            if (load != null) {
                 Collection failed = _store.loadAll(load, null,
                     StoreManager.FORCE_LOAD_REFRESH, _fc, null);
                 if (failed != null && !failed.isEmpty())
@@ -2868,6 +2879,36 @@
         throwNestedExceptions(exceps, false);
     }
 
+    /**
+     * Optimization for single-object refresh.
+     */
+    protected void refreshInternal(Object obj, OpCallbacks call) {
+        try {
+            StateManagerImpl sm = getStateManagerImpl(obj, true);
+            if ((processArgument(OpCallbacks.OP_REFRESH, obj, sm, call)
+                & OpCallbacks.ACT_RUN) == 0)
+                return;
+
+            if (sm != null) {
+                if (sm.isDetached())
+                    throw newDetachedException(obj, "refresh");
+                else if (sm.beforeRefresh(false)) {
+                    sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, false);
+                    sm.afterRefresh();
+                }
+                fireLifecycleEvent(sm.getManagedInstance(), null,
+                    sm.getMetaData(), LifecycleEvent.AFTER_REFRESH);
+            } else if (assertPersistenceCapable(obj).pcIsDetached()
+                == Boolean.TRUE)
+                throw newDetachedException(obj, "refresh");
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        }
+    }
+    
+    
     public void retrieveAll(Collection objs, boolean dfgOnly,
         OpCallbacks call) {
         if (objs == null || objs.isEmpty())

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java?rev=667312&r1=667311&r2=667312&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java Thu Jun 12 18:58:49 2008
@@ -19,10 +19,10 @@
 package org.apache.openjpa.persistence.datacache;
 
 import javax.persistence.EntityManager;
-import javax.persistence.EntityNotFoundException;
 import javax.persistence.LockModeType;
 
 import org.apache.openjpa.persistence.EntityManagerImpl;
+import org.apache.openjpa.persistence.EntityNotFoundException;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
 import org.apache.openjpa.persistence.StoreCache;
@@ -54,7 +54,10 @@
 	private static final boolean WITH_DATACACHE = true;
 	private static final boolean CONSISTENT = true;
 	private static final boolean DIRTY = true;
+	private static final boolean REFRESH_FROM_DATACACHE = true;
 	private static final LockModeType NOLOCK = null;
+	private static final Class ENTITY_NOT_FOUND_ERROR = EntityNotFoundException.class;
+	private static final Class NO_ERROR = null;
 
 	private static final String MARKER_DATACACHE = "in DataCache";
 	private static final String MARKER_DATABASE  = "in Database";
@@ -356,68 +359,66 @@
 	String getExpectedMarker(boolean useDataCache, LockModeType lock, 
 			boolean makeDirtyBeforeRefresh) {
 		if (useDataCache) {
-//			return (lock != null && makeDirtyBeforeRefresh)
 			return (lock != null) ? MARKER_DATABASE : MARKER_DATACACHE; 
 		} else {
-//			return (makeDirtyBeforeRefresh) ? MARKER_DATABASE : MARKER_CACHE;
 			return MARKER_DATABASE;
 		}
 	}
 	
 	public void testDirtyRefreshWithNoLockHitsDatabase() {
-		verifyRefresh(WITH_DATACACHE, NOLOCK, DIRTY, false, MARKER_DATABASE);
+		verifyRefresh(WITH_DATACACHE, NOLOCK, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
 	}
 	
 	public void testDirtyRefreshWithNoLockHitsDataCache() {
-		verifyRefresh(WITH_DATACACHE, NOLOCK, DIRTY, true, MARKER_DATACACHE);
+		verifyRefresh(WITH_DATACACHE, NOLOCK, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
 	}
 	
-	public void testCleanRefreshWithNoLockHitsDatabase() {
-		verifyRefresh(WITH_DATACACHE, NOLOCK, !DIRTY, false, MARKER_DATABASE);
+	public void testCleanRefreshWithNoLockDoesNotHitDatabase() {
+		verifyRefresh(WITH_DATACACHE, NOLOCK, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
 	}
 	
 	public void testCleanRefreshWithNoLockHitsDataCache() {
-		verifyRefresh(WITH_DATACACHE, NOLOCK, !DIRTY, true, MARKER_DATACACHE);
+		verifyRefresh(WITH_DATACACHE, NOLOCK, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
 	}
 	
 	public void testDirtyRefreshWithReadLockHitsDatabase() {
-		verifyRefresh(WITH_DATACACHE, LockModeType.READ, DIRTY, true, MARKER_DATABASE);
-		verifyRefresh(WITH_DATACACHE, LockModeType.READ, DIRTY, false, MARKER_DATABASE);
+		verifyRefresh(WITH_DATACACHE, LockModeType.READ, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(WITH_DATACACHE, LockModeType.READ, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
 	}
 	
-	public void testCleanRefreshWithReadLockHitsDatabase() {
-		verifyRefresh(WITH_DATACACHE, LockModeType.READ, !DIRTY, true, MARKER_DATABASE);
-		verifyRefresh(WITH_DATACACHE, LockModeType.READ, !DIRTY, false, MARKER_DATABASE);
+	public void testCleanRefreshWithReadLockDoesNotHitDatabase() {
+		verifyRefresh(WITH_DATACACHE, LockModeType.READ, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
+		verifyRefresh(WITH_DATACACHE, LockModeType.READ, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
 	}
 	
 	public void testDirtyRefreshWithWriteLockHitsDatabase() {
-		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, DIRTY, true, MARKER_DATABASE);
-		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, DIRTY, false, MARKER_DATABASE);
+		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
 	}
 	
-	public void testCleanRefreshWithWriteLockHitsDatabase() {
-		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, !DIRTY, true, MARKER_DATABASE);
-		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, !DIRTY, false, MARKER_DATABASE);
+	public void testCleanRefreshWithWriteLockDoesNotHitDatabase() {
+		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
+		verifyRefresh(WITH_DATACACHE, LockModeType.WRITE, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATACACHE);
 	}
 	
 	public void testDirtyRefreshWithoutDataCacheAlwaysHitsDatabase() {
-		verifyRefresh(!WITH_DATACACHE, NOLOCK, DIRTY, true, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, DIRTY, true, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, DIRTY, true, MARKER_DATABASE);
-		
-		verifyRefresh(!WITH_DATACACHE, NOLOCK, DIRTY, false, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, DIRTY, false, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, DIRTY, false, MARKER_DATABASE);
-	}
-	
-	public void testCleanRefreshWithoutDataCacheAlwaysHitsDatabase() {
-		verifyRefresh(!WITH_DATACACHE, NOLOCK, !DIRTY, true, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, !DIRTY, true, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, !DIRTY, true, MARKER_DATABASE);
-		
-		verifyRefresh(!WITH_DATACACHE, NOLOCK, !DIRTY, false, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, !DIRTY, false, MARKER_DATABASE);
-		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, !DIRTY, false, MARKER_DATABASE);
+		verifyRefresh(!WITH_DATACACHE, NOLOCK, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, DIRTY, REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		
+		verifyRefresh(!WITH_DATACACHE, NOLOCK, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, DIRTY, !REFRESH_FROM_DATACACHE, MARKER_DATABASE);
+	}
+	
+	public void testCleanRefreshWithoutDataCacheDoesNotHitDatabase() {
+		verifyRefresh(!WITH_DATACACHE, NOLOCK, !DIRTY, REFRESH_FROM_DATACACHE, MARKER_CACHE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, !DIRTY, REFRESH_FROM_DATACACHE,  MARKER_CACHE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, !DIRTY, REFRESH_FROM_DATACACHE,  MARKER_CACHE);
+		
+		verifyRefresh(!WITH_DATACACHE, NOLOCK, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_CACHE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.READ, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_CACHE);
+		verifyRefresh(!WITH_DATACACHE, LockModeType.WRITE, !DIRTY, !REFRESH_FROM_DATACACHE, MARKER_CACHE);
 	}
 	
 	/**
@@ -430,7 +431,7 @@
 	 * @param lock
 	 */
 	public void verifyDeleteDetectionOnRefresh(boolean useDataCache, 
-			LockModeType lock) {
+			boolean dirty, LockModeType lock, Class expectedExceptionType) {
 		OpenJPAEntityManagerFactorySPI emf = (useDataCache)
 			? emfWithDataCache : emfWithoutDataCache;
 			
@@ -465,34 +466,59 @@
 		 *   
 		 */
 		em.getTransaction().begin();
-		if (lock != null)
-			em.getFetchPlan().setReadLockMode(lock);
+		em.getFetchPlan().setReadLockMode(lock);
+		if (dirty) 
+			pc.setName("Dirty Name");
 		try {
 			em.refresh(pc);
-			fail("expected EntityNotFoundException for PObject:" + oid);
-		} catch (EntityNotFoundException ex) {
-			// we are good
+			if (expectedExceptionType != null) {
+				fail("expected " + expectedExceptionType.getSimpleName() + 
+						" for PObject:" + oid);
+			}
 		} catch (Exception ex) {
-			ex.printStackTrace();
-			fail("expected EntityNotFoundException for PObject:" + oid);
+			boolean expectedException = expectedExceptionType != null &&
+			    expectedExceptionType.isAssignableFrom(ex.getClass());
+			if (!expectedException) {
+				ex.printStackTrace();
+				String error = (expectedExceptionType == null) 
+					? "no exception" : expectedExceptionType.getName();
+				fail("expected " + error + " for PObject:" + oid);
+			}
 		} finally {
 			em.getTransaction().rollback();
 		}
 	}
 
-	public void testDeleteIsDetectedOnRefreshWithLockWithActiveDataCache() {
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, LockModeType.READ);
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, LockModeType.WRITE);
+	public void testDeleteIsNotDetectedOnCleanRefreshWithoutLockWithDataCache() {
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, NOLOCK, NO_ERROR);
 	}
 	
-	public void testDeleteIsNotDetectedOnRefreshWithNoLockWithActiveDataCache() {
-		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, NOLOCK);
+	public void testDeleteIsDetectedOnCleanRefreshWithLockWithDataCache() {
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
+	}
+
+	public void testDeleteIsNotDetectedOnDirtyRefreshWithoutLockWithDataCache() {
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, NOLOCK, NO_ERROR);	
+	}
+	
+	public void testDeleteIsDetectedOnDirtyRefreshWithLockWithDataCache() {
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
+	}
+	
+	public void testDeleteIsDetectedOnDirtyRefreshWitDataCache() {
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
+		verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
+	}
+	
+	public void testDeleteIsDetectedOnCleanRefreshWithoutLockWithoutDataCache() {
+		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, NOLOCK, ENTITY_NOT_FOUND_ERROR);
 	}
 	
-	public void testDeleteIsDetectedOnRefreshAlwaysWithoutDataCache() {
-		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, NOLOCK);
-		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, LockModeType.READ);
-		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, LockModeType.WRITE);
+	public void testDeleteIsDetectedOnCleanRefreshWithLockWithoutDataCache() {
+		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR);
+		verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR);
 	}
 
 }