PojoCache Map collection adds key to Map object when removin
tfila May 23, 2007 12:35 PMHello,
It appears that in JBossCache-1.4.1.SP3 (and earlier versions) that doing a Map.remove() on a Map object in the PojoCache for a key that does not exist will result in the key being created in the Map without an associated value. After the remove() doing a containsKey() for that key will return 'true'. From that point on the only way to remove the key from the Map is to first assign it a value and then doing another remove.
For example:
The cache with an empty Map added:
/myProperties
_lock_: LOCK
__jboss:internal:class__: class java.util.HashMap
AOPInstance: org.jboss.cache.aop.AOPInstance@1ce3fc5
The cache after doing a remove on the key 'MY_KEY'
/myProperties
_lock_: LOCK
__jboss:internal:class__: class java.util.HashMap
AOPInstance: org.jboss.cache.aop.AOPInstance@1ce3fc5
/MY_KEY
_lock_: LOCK
The following unit test demonstrates this problem. In this test a HashMap is added to the cache and a key/value pair is added. A remove is performed on the key and then verified that the key no longer exists in the Map. A second removal on the same key is then done with the same verification which fails.
package org.jboss.cache.aop.collection; import java.util.HashMap; import java.util.Map; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.cache.PropertyConfigurator; import org.jboss.cache.aop.PojoCache; public class MultiRemovalCacheMapAopTest extends TestCase { Log log=LogFactory.getLog(MultiRemovalCacheMapAopTest.class); PojoCache cache_; Map hobbies; public MultiRemovalCacheMapAopTest(String name) { super(name); } protected void setUp() throws Exception { super.setUp(); log.info("setUp() ...."); String configFile = "META-INF/local-service.xml"; cache_ = new PojoCache(); PropertyConfigurator config = new PropertyConfigurator(); config.configure(cache_, configFile); cache_.start(); } protected void tearDown() throws Exception { super.tearDown(); cache_.stop(); } public void testMultipleRemoves() throws Exception { final String key = "MY_KEY"; HashMap properties = new HashMap(); cache_.putObject( "/myProperties", properties ); properties = (HashMap)cache_.getObject( "/myProperties" ); properties.put( key, "value1"); log.info( cache_.printDetails() ); assertTrue( properties.containsKey( key ) ); assertNotNull( properties.get(key)); log.info( "removing Map key [" + key + "]" ); properties.remove( key ); log.info( cache_.printDetails() ); assertTrue( !properties.containsKey( key ) ); log.info( "Second removal of Map key [" + key + "]" ); properties.remove( key ); log.info( cache_.printDetails() ); assertTrue( !properties.containsKey( key ) ); } public static Test suite() throws Exception { return new TestSuite(MultiRemovalCacheMapAopTest.class); } public static void main(String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } }
Any work-arounds other than checking first if the key exists prior to the remove would be appreciated.
Thanks.