[hibernate-commits] Hibernate SVN: r14368 - in core/trunk/cache-jbosscache2/src: main/java/org/hibernate/cache/jbc2/access and 5 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Feb 27 12:47:36 EST 2008


Author: bstansberry at jboss.com
Date: 2008-02-27 12:47:36 -0500 (Wed, 27 Feb 2008)
New Revision: 14368

Modified:
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/ClusteredConcurrentTimestampsRegionImpl.java
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
   core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractGeneralDataRegionTestCase.java
   core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java
   core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java
Log:
Redo handling of invalidated region root nodes

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java	2008-02-27 15:31:40 UTC (rev 14367)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java	2008-02-27 17:47:36 UTC (rev 14368)
@@ -31,6 +31,10 @@
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
 
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.Region;
+import org.hibernate.cache.jbc2.util.CacheHelper;
+import org.hibernate.cache.jbc2.util.NonLockingDataVersion;
 import org.jboss.cache.Cache;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.Node;
@@ -39,20 +43,10 @@
 import org.jboss.cache.config.Option;
 import org.jboss.cache.config.Configuration.NodeLockingScheme;
 import org.jboss.cache.notifications.annotation.CacheListener;
-import org.jboss.cache.notifications.annotation.NodeCreated;
-import org.jboss.cache.notifications.annotation.NodeRemoved;
-import org.jboss.cache.notifications.event.NodeCreatedEvent;
-import org.jboss.cache.notifications.event.NodeRemovedEvent;
 import org.jboss.cache.optimistic.DataVersion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.Region;
-import org.hibernate.cache.jbc2.builder.JndiMultiplexingCacheInstanceManager;
-import org.hibernate.cache.jbc2.util.CacheHelper;
-import org.hibernate.cache.jbc2.util.NonLockingDataVersion;
-
 /**
  * General support for writing {@link Region} implementations for JBoss Cache
  * 2.x.
@@ -74,7 +68,7 @@
     protected final Logger log;
     protected final Object regionRootMutex = new Object();
 
-    protected RegionRootListener listener;
+//    protected RegionRootListener listener;
     
     public BasicRegionAdapter(Cache jbcCache, String regionName, String regionPrefix) {
         this.jbcCache = jbcCache;
@@ -103,17 +97,31 @@
                 }
             }
             
-            // If we are using replication, we may remove the root node
-            // and then need to re-add it. In that case, the fact
-            // that it is resident will not replicate, so use a listener
-            // to set it as resident
-            if (CacheHelper.isClusteredReplication(cfg.getCacheMode()) 
-                  || CacheHelper.isClusteredInvalidation(cfg.getCacheMode())) {
-                listener = new RegionRootListener();
-                jbcCache.addCacheListener(listener);
+//            // If we are using replication, we may remove the root node
+//            // and then need to re-add it. In that case, the fact
+//            // that it is resident will not replicate, so use a listener
+//            // to set it as resident
+//            if (CacheHelper.isClusteredReplication(cfg.getCacheMode()) 
+//                  || CacheHelper.isClusteredInvalidation(cfg.getCacheMode())) {
+//                listener = new RegionRootListener();
+//                jbcCache.addCacheListener(listener);
+//            }
+            
+            regionRoot = jbcCache.getRoot().getChild( regionFqn );
+            if (regionRoot == null || !regionRoot.isValid()) {
+               // Establish the region root node with a non-locking data version
+               DataVersion version = optimistic ? NonLockingDataVersion.INSTANCE : null;
+               regionRoot = CacheHelper.addNode(jbcCache, regionFqn, true, true, version);
             }
-            
-            establishRegionRootNode();
+            else if (optimistic && regionRoot instanceof NodeSPI) {
+                // FIXME Hacky workaround to JBCACHE-1202
+                if ( !( ( ( NodeSPI ) regionRoot ).getVersion() instanceof NonLockingDataVersion ) ) {
+                    ((NodeSPI) regionRoot).setVersion(NonLockingDataVersion.INSTANCE);
+                }
+            }
+            if (!regionRoot.isResident()) {
+               regionRoot.setResident(true);
+            }
         }
         catch (Exception e) {
             throw new CacheException(e.getMessage(), e);
@@ -123,30 +131,48 @@
     private void establishRegionRootNode()
     {
         synchronized (regionRootMutex) {
-            if (regionRoot != null && regionRoot.isValid())
+            // If we've been blocking for the mutex, perhaps another
+            // thread has already reestablished the root.
+            // In case the node was reestablised via replication, confirm it's 
+            // marked "resident" (a status which doesn't replicate)
+            if (regionRoot != null && regionRoot.isValid()) {
                 return;
+            }
+            
+            // For pessimistic locking, we just want to toss out our ref
+            // to any old invalid root node and get the latest (may be null)            
+            if (!optimistic) {
+               regionRoot = jbcCache.getRoot().getChild( regionFqn );
+               return;
+            }
+            
+            // The rest only matters for optimistic locking, where we
+            // need to establish the proper data version on the region root
+            
             // Don't hold a transactional lock for this 
             Transaction tx = suspend();
+            Node newRoot = null;
             try {
                  // Make sure the root node for the region exists and 
                  // has a DataVersion that never complains
-                 regionRoot = jbcCache.getRoot().getChild( regionFqn );
-                 if (regionRoot == null) {                
+                 newRoot = jbcCache.getRoot().getChild( regionFqn );
+                 if (newRoot == null || !newRoot.isValid()) {                
                      // Establish the region root node with a non-locking data version
                      DataVersion version = optimistic ? NonLockingDataVersion.INSTANCE : null;
-                     regionRoot = CacheHelper.addNode(jbcCache, regionFqn, true, true, version);    
+                     newRoot = CacheHelper.addNode(jbcCache, regionFqn, true, true, version);    
                  }
-                 else if (optimistic && regionRoot instanceof NodeSPI) {
+                 else if (newRoot instanceof NodeSPI) {
                      // FIXME Hacky workaround to JBCACHE-1202
-                     if ( !( ( ( NodeSPI ) regionRoot ).getVersion() instanceof NonLockingDataVersion ) ) {
-                          ((NodeSPI) regionRoot).setVersion(NonLockingDataVersion.INSTANCE);
+                     if ( !( ( ( NodeSPI ) newRoot ).getVersion() instanceof NonLockingDataVersion ) ) {
+                          ((NodeSPI) newRoot).setVersion(NonLockingDataVersion.INSTANCE);
                      }
                  }
-                // Never evict this node
-                regionRoot.setResident(true);
+                 // Never evict this node
+                 newRoot.setResident(true);
             }
             finally {
                 resume(tx);
+                regionRoot = newRoot;
             }
         }
     }
@@ -164,20 +190,22 @@
     }
     
     /**
-     * If the cache is configured for optimistic locking, checks for the 
-     * validity of the root cache node for this region,
-     * creating a new one if it does not exist or is invalid.  Suspends any 
+     * Checks for the validity of the root cache node for this region,
+     * creating a new one if it does not exist or is invalid, and also
+     * ensuring that the root node is marked as resident.  Suspends any 
      * transaction while doing this to ensure no transactional locks are held 
      * on the region root.
      * 
-     * This is only needed for optimistic locking, as with optimistic the
-     * region root node has a special version that must be established.
-     * 
      * TODO remove this once JBCACHE-1250 is resolved.
      */
     public void ensureRegionRootExists() {
-       if (optimistic && (regionRoot == null || !regionRoot.isValid()))
+       
+       if (regionRoot == null || !regionRoot.isValid())
           establishRegionRootNode();
+       
+       // Fix up the resident flag
+       if (regionRoot != null && regionRoot.isValid() && !regionRoot.isResident())
+          regionRoot.setResident(true);
     }
 
     public void destroy() throws CacheException {
@@ -202,10 +230,10 @@
         } catch (Exception e) {
             throw new CacheException(e);
         }
-        finally {
-            if (listener != null)
-                jbcCache.removeCacheListener(listener);
-        }
+//        finally {
+//            if (listener != null)
+//                jbcCache.removeCacheListener(listener);
+//        }
     }
 
     protected void deactivateLocalNode() {
@@ -364,17 +392,17 @@
         return escaped;
     }
     
-    @CacheListener
-    public class RegionRootListener {
-        
-        @NodeCreated
-        public void nodeCreated(NodeCreatedEvent event) {
-            if (!event.isPre() && event.getFqn().equals(getRegionFqn())) {
-                log.debug("Node created for " + getRegionFqn());
-                Node regionRoot = jbcCache.getRoot().getChild(getRegionFqn());
-                regionRoot.setResident(true);
-            }
-        }
-        
-    }
+//    @CacheListener
+//    public class RegionRootListener {
+//        
+//        @NodeCreated
+//        public void nodeCreated(NodeCreatedEvent event) {
+//            if (!event.isPre() && event.getFqn().equals(getRegionFqn())) {
+//                log.debug("Node created for " + getRegionFqn());
+//                Node regionRoot = jbcCache.getRoot().getChild(getRegionFqn());
+//                regionRoot.setResident(true);
+//            }
+//        }
+//        
+//    }
 }

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java	2008-02-27 15:31:40 UTC (rev 14367)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java	2008-02-27 17:47:36 UTC (rev 14368)
@@ -169,9 +169,6 @@
        
         Option opt = NonLockingDataVersion.getInvocationOption();
         CacheHelper.removeAll(cache, regionFqn, opt);
-        
-        // Restablish the region root node with a non-locking data version
-        CacheHelper.addNode(cache, regionFqn, false, true, NonLockingDataVersion.INSTANCE);
     }
 
 }

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java	2008-02-27 15:31:40 UTC (rev 14367)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java	2008-02-27 17:47:36 UTC (rev 14368)
@@ -56,16 +56,23 @@
     }
 
     public Object get(Object key, long txTimestamp) throws CacheException {
+       
+        region.ensureRegionRootExists();
+        
         return CacheHelper.get(cache, regionFqn, key);
     }
 
     public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+       
+        region.ensureRegionRootExists();
 
         return CacheHelper.putForExternalRead(cache, regionFqn, key, value);
     }
 
     public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
             throws CacheException {
+       
+        region.ensureRegionRootExists();
 
         // We ignore minimalPutOverride. JBossCache putForExternalRead is
         // already about as minimal as we can get; it will promptly return
@@ -88,6 +95,8 @@
     }
 
     public boolean insert(Object key, Object value, Object version) throws CacheException {
+       
+        region.ensureRegionRootExists();
 
         CacheHelper.put(cache, regionFqn, key, value);
         return true;
@@ -99,6 +108,8 @@
 
     public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
             throws CacheException {
+       
+        region.ensureRegionRootExists();
 
         CacheHelper.put(cache, regionFqn, key, value);
         return true;
@@ -110,6 +121,8 @@
     }
 
     public void remove(Object key) throws CacheException {
+       
+        region.ensureRegionRootExists();
 
         CacheHelper.remove(cache, regionFqn, key);
     }
@@ -119,6 +132,9 @@
     }
 
     public void evict(Object key) throws CacheException {
+       
+        region.ensureRegionRootExists();
+        
         CacheHelper.remove(cache, regionFqn, key);
     }
 
@@ -127,8 +143,6 @@
     }
     
     private void evictOrRemoveAll() throws CacheException {
-        CacheHelper.removeAll(cache, regionFqn);
-        // Restore the region root node
-        CacheHelper.addNode(cache, regionFqn, false, true, null);        
+        CacheHelper.removeAll(cache, regionFqn);        
     }
 }

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java	2008-02-27 15:31:40 UTC (rev 14367)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java	2008-02-27 17:47:36 UTC (rev 14368)
@@ -89,8 +89,6 @@
         if (localOnly)
             opt.setCacheModeLocal(true);
         CacheHelper.removeAll(getCacheInstance(), getRegionFqn(), opt);
-        // Restore the region root node
-        CacheHelper.addNode(getCacheInstance(), getRegionFqn(), false, true, null);    
     }
 
     public Object get(Object key) throws CacheException {

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/ClusteredConcurrentTimestampsRegionImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/ClusteredConcurrentTimestampsRegionImpl.java	2008-02-27 15:31:40 UTC (rev 14367)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/ClusteredConcurrentTimestampsRegionImpl.java	2008-02-27 17:47:36 UTC (rev 14368)
@@ -93,8 +93,6 @@
     public void evictAll() throws CacheException {
         Option opt = getNonLockingDataVersionOption(true);
         CacheHelper.removeAll(getCacheInstance(), getRegionFqn(), opt);
-        // Restore the region root node
-        CacheHelper.addNode(getCacheInstance(), getRegionFqn(), false, true, null);   
     }
 
     public Object get(Object key) throws CacheException {

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java	2008-02-27 15:31:40 UTC (rev 14367)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java	2008-02-27 17:47:36 UTC (rev 14368)
@@ -97,8 +97,6 @@
         // TODO Is this a valid operation on a timestamps cache?
         Option opt = getNonLockingDataVersionOption(true);
         CacheHelper.removeAll(getCacheInstance(), getRegionFqn(), opt);
-        // Restore the region root node
-        CacheHelper.addNode(getCacheInstance(), getRegionFqn(), false, true, null);   
     }
 
     public Object get(Object key) throws CacheException {

Modified: core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractGeneralDataRegionTestCase.java
===================================================================
--- core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractGeneralDataRegionTestCase.java	2008-02-27 15:31:40 UTC (rev 14367)
+++ core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractGeneralDataRegionTestCase.java	2008-02-27 17:47:36 UTC (rev 14368)
@@ -212,42 +212,35 @@
         
         localRegion.evictAll();
         
+        // This should re-establish the region root node in the optimistic case
+        assertNull(localRegion.get(KEY));
+        
         regionRoot = localCache.getRoot().getChild(regionFqn);
-        assertFalse(regionRoot == null);
-        assertEquals(0, regionRoot.getChildrenNames().size());
-        assertTrue(regionRoot.isResident());
-
-        if (CacheHelper.isClusteredInvalidation(remoteCache)) {
-           // With invalidation, a node that removes the region root cannot reestablish
-           // it on remote nodes, since the only message the propagates is "invalidate".
-           // So, we have to reestablish it ourselves
-           
-           // First, do a get to help test whether a get messes up the optimistic version
-           String msg = "Known issue JBCACHE-1251 -- problem reestablishing invalidated region root";
-           try {
-              assertEquals(null, remoteRegion.get(KEY));
-           }
-           catch (CacheException ce) {
-              log.error(msg, ce);
-              fail(msg + " -- cause: " + ce);
-           }
-           remoteRegion.put(KEY, VALUE1);
-           assertEquals(msg, VALUE1, remoteRegion.get(KEY));
+        if (optimistic) {
+           assertFalse(regionRoot == null);
+           assertEquals(0, regionRoot.getChildrenNames().size());
+           assertTrue(regionRoot.isValid());
+           assertTrue(regionRoot.isResident());
         }
-    
+        else {
+            assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
+        }
+
+        // Re-establishing the region root on the local node doesn't 
+        // propagate it to other nodes. Do a get on the remote node to re-establish
+        // This only adds a node in the case of optimistic locking
+        assertEquals(null, remoteRegion.get(KEY));
+        
         regionRoot = remoteCache.getRoot().getChild(regionFqn);
-        assertFalse(regionRoot == null);
-        if (invalidation) {
-            // JBC seems broken: see http://www.jboss.com/index.html?module=bb&op=viewtopic&t=121408
-            // FIXME   replace with the following when JBCACHE-1199 and JBCACHE-1200 are done:
-            //assertFalse(regionRoot.isValid());
-            checkNodeIsEmpty(regionRoot);
+        if (optimistic) {
+            assertFalse(regionRoot == null);
+            assertEquals(0, regionRoot.getChildrenNames().size());
+            assertTrue(regionRoot.isValid());
+            assertTrue(regionRoot.isResident());
         }
         else {
-            // Same assertion, just different assertion msg
-            assertEquals(0, regionRoot.getChildrenNames().size());
-        }        
-        assertTrue(regionRoot.isResident());
+            assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
+        }
         
         assertEquals("local is clean", null, localRegion.get(KEY));
         assertEquals("remote is clean", null, remoteRegion.get(KEY));

Modified: core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java
===================================================================
--- core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java	2008-02-27 15:31:40 UTC (rev 14367)
+++ core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java	2008-02-27 17:47:36 UTC (rev 14368)
@@ -460,8 +460,6 @@
         // Wait for async propagation
         sleep(250);
         
-
-        
         if (isUsingOptimisticLocking()) {
             regionRoot = localCache.getRoot().getChild(regionFqn);
             assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass());
@@ -474,43 +472,54 @@
         else
             localAccessStrategy.removeAll();
         
+        // This should re-establish the region root node in the optimistic case
+        assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis()));
+        
         regionRoot = localCache.getRoot().getChild(regionFqn);
-        assertFalse(regionRoot == null);
-        assertEquals(0, getValidChildrenCount(regionRoot));
-        assertTrue(regionRoot.isResident());
-
-        if (isUsingInvalidation()) {
-           // With invalidation, a node that removes the region root cannot reestablish
-           // it on remote nodes, since the only message the propagates is "invalidate".
-           // So, we have to reestablish it ourselves
-           
-           // First, do a get to help test whether a get messes up the optimistic version
-           String msg = "Known issue JBCACHE-1251 -- problem reestablishing invalidated region root";
-           try {
-              assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
-           }
-           catch (CacheException ce) {
-              log.error(msg, ce);
-              fail(msg + " -- cause: " + ce);
-           }
-           remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
-           assertEquals(msg, VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
+        if (isUsingOptimisticLocking()) {
+            assertFalse(regionRoot == null);
+            assertEquals(0, getValidChildrenCount(regionRoot));
+            assertTrue(regionRoot.isValid());
+            assertTrue(regionRoot.isResident());
         }
+        else {
+            assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
+        }
 
+        // Re-establishing the region root on the local node doesn't 
+        // propagate it to other nodes. Do a get on the remote node to re-establish
+        // This only adds a node in the case of optimistic locking
+        assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
+
         regionRoot = remoteCache.getRoot().getChild(regionFqn);
+        if (isUsingOptimisticLocking()) {
+           assertFalse(regionRoot == null);
+           assertTrue(regionRoot.isValid());
+           assertTrue(regionRoot.isResident());
+           // Not invalidation, so we didn't insert a child above
+           assertEquals(0, getValidChildrenCount(regionRoot));
+        }        
+        else {
+            assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
+        }
+        
+        // Test whether the get above messes up the optimistic version
+        remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
+        assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
+        
+        // Revalidate the region root
+        regionRoot = remoteCache.getRoot().getChild(regionFqn);
         assertFalse(regionRoot == null);
-        if (isUsingInvalidation()) {
-            // Region root should have 1 child -- the one we added above
-            assertEquals(1, getValidChildrenCount(regionRoot));
-        }
-        else {
-            // Same assertion, just different assertion msg
-            assertEquals(0, getValidChildrenCount(regionRoot));
-        }        
+        assertTrue(regionRoot.isValid());
         assertTrue(regionRoot.isResident());
+        // Region root should have 1 child -- the one we added above
+        assertEquals(1, getValidChildrenCount(regionRoot));
         
-        assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis()));
-        assertEquals("remote is correct", (isUsingInvalidation() ? VALUE1 : null), remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
+        // Wait for async propagation of the putFromLoad
+        sleep(250);
+        
+        assertEquals("local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get(KEY, System.currentTimeMillis()));
+        assertEquals("remote is correct", VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
     }
     
     private int getValidChildrenCount(Node node) {

Modified: core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java
===================================================================
--- core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java	2008-02-27 15:31:40 UTC (rev 14367)
+++ core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java	2008-02-27 17:47:36 UTC (rev 14368)
@@ -24,7 +24,6 @@
 package org.hibernate.test.cache.jbc2.entity;
 
 import java.util.Iterator;
-import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -34,7 +33,6 @@
 import junit.framework.TestSuite;
 
 import org.hibernate.cache.CacheDataDescription;
-import org.hibernate.cache.CacheException;
 import org.hibernate.cache.EntityRegion;
 import org.hibernate.cache.access.AccessType;
 import org.hibernate.cache.access.EntityRegionAccessStrategy;
@@ -684,43 +682,53 @@
         else
             localAccessStrategy.removeAll();
         
+        // This should re-establish the region root node in the optimistic case
+        assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis()));
+        
         regionRoot = localCache.getRoot().getChild(regionFqn);
-        assertFalse(regionRoot == null);
-        assertEquals(0, getValidChildrenCount(regionRoot));
-        assertTrue(regionRoot.isResident());
+        if (isUsingOptimisticLocking()) {
+            assertFalse(regionRoot == null);
+            assertEquals(0, getValidChildrenCount(regionRoot));
+            assertTrue(regionRoot.isValid());
+            assertTrue(regionRoot.isResident());
+        }
+        else {
+            assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
+        }
 
-        if (isUsingInvalidation()) {
-           // With invalidation, a node that removes the region root cannot reestablish
-           // it on remote nodes, since the only message the propagates is "invalidate".
-           // So, we have to reestablish it ourselves
-           
-           // First, do a get to help test whether a get messes up the optimistic version
-           String msg = "Known issue JBCACHE-1251 -- problem reestablishing invalidated region root";
-           try {
-              assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
-           }
-           catch (CacheException ce) {
-              log.error(msg, ce);
-              fail(msg + " -- cause: " + ce);
-           }
-           remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
-           assertEquals(msg, VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
-        }
+        // Re-establishing the region root on the local node doesn't 
+        // propagate it to other nodes. Do a get on the remote node to re-establish
+        assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
+
+        regionRoot = remoteCache.getRoot().getChild(regionFqn);
+        if (isUsingOptimisticLocking()) {
+           assertFalse(regionRoot == null);
+           assertTrue(regionRoot.isValid());
+           assertTrue(regionRoot.isResident());
+           // Not invalidation, so we didn't insert a child above
+           assertEquals(0, getValidChildrenCount(regionRoot));
+       }        
+       else {
+          assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid());
+       }
         
+        // Test whether the get above messes up the optimistic version
+        remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
+        assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
+        
+        // Revalidate the region root
         regionRoot = remoteCache.getRoot().getChild(regionFqn);
         assertFalse(regionRoot == null);
-        if (isUsingInvalidation()) {
-            // Region root should have 1 child -- the one we added above
-            assertEquals(1, getValidChildrenCount(regionRoot));
-        }
-        else {
-            // Same assertion, just different assertion msg
-            assertEquals(0, getValidChildrenCount(regionRoot));
-        }        
+        assertTrue(regionRoot.isValid());
         assertTrue(regionRoot.isResident());
+        // Region root should have 1 child -- the one we added above
+        assertEquals(1, getValidChildrenCount(regionRoot));
         
-        assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis()));
-        assertEquals("remote is correct", (isUsingInvalidation() ? VALUE1 : null), remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
+        // Wait for async propagation
+        sleep(250);
+        
+        assertEquals("local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get(KEY, System.currentTimeMillis()));
+        assertEquals("remote is correct", VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis()));
     }
     
     private int getValidChildrenCount(Node node) {




More information about the hibernate-commits mailing list