<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body link="#355491" alink="#4262a1" vlink="#355491" style="background: #e2e2e2; margin: 0; padding: 20px;">

<div>
        <table cellpadding="0" bgcolor="#FFFFFF" border="0" cellspacing="0" style="border: 1px solid #dadada; margin-bottom: 30px; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                <tbody>
                        <tr>

                                <td>

                                        <table border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border: solid 2px #ccc; background: #dadada; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                                                <tbody>
                                                        <tr>
                                                                <td bgcolor="#000000" valign="middle" height="58px" style="border-bottom: 1px solid #ccc; padding: 20px; -moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px;">
                                                                        <h1 style="color: #333333; font: bold 22px Arial, Helvetica, sans-serif; margin: 0; display: block !important;">
                                                                        <!-- To have a header image/logo replace the name below with your img tag -->
                                                                        <!-- Email clients will render the images when the message is read so any image -->
                                                                        <!-- must be made available on a public server, so that all recipients can load the image. -->
                                                                        <a href="http://community.jboss.org/index.jspa" style="text-decoration: none; color: #E1E1E1">JBoss Community</a></h1>
                                                                </td>

                                                        </tr>
                                                        <tr>
                                                                <td bgcolor="#FFFFFF" style="font: normal 12px Arial, Helvetica, sans-serif; color:#333333; padding: 20px;  -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 5px; -webkit-border-bottom-left-radius: 5px;"><h3 style="margin: 10px 0 5px; font-size: 17px; font-weight: normal;">
    CacheLoader store not recreating keys/values
</h3>
<span style="margin-bottom: 10px;">
    created by <a href="http://community.jboss.org/people/jaysmith">jaysmith</a> in <i>JBoss Cache</i> - <a href="http://community.jboss.org/message/599443#599443">View the full discussion</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">

<div class="jive-rendered-content"><p>Hi there,</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>I have a simple proof of concept JUnit that creates a cache, creates a node, creates a test object and adds this object to the node.&#160; The cache is configured with a FileCacheLoader, passivation disabled and eviction happens after 2 seconds.</p><p>What I would expect to see is that when the object is added to the node, both RAM and disk are written to, after 2 seconds then memory should be cleared. After that time, a read should load the node and the object that the node contains back into memory.</p><p>However, what I'm actually seeing is different. After 2 seconds has elapsed and the node has been evicted from RAM, a read recreates the node from the persistent store but it is empty i.e. the object that the node orginally stored is no longer there.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>My configuration:</p><p>&lt;?xml version="1.0" encoding="UTF-8"?&gt;</p><p>&lt;jbosscache xmlns:xsi="<a class="jive-link-external-small" href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" xmlns="urn:jboss:jbosscache-core:config:3.2"&gt;</p><p><br/>&#160;&#160; &lt;!--<br/>&#160;&#160;&#160;&#160;&#160; isolation levels supported: READ_COMMITTED and REPEATABLE_READ<br/>&#160;&#160;&#160;&#160;&#160; nodeLockingSchemes: mvcc, pessimistic (deprecated), optimistic (deprecated)<br/>&#160;&#160; --&gt;<br/>&#160;&#160; &lt;locking<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; isolationLevel="REPEATABLE_READ"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; lockParentForChildInsertRemove="false"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; lockAcquisitionTimeout="20000"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; nodeLockingScheme="mvcc"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; writeSkewCheck="false"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; useLockStriping="true"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; concurrencyLevel="500"/&gt;</p><p>&#160;&#160; &lt;!--<br/>&#160;&#160;&#160;&#160;&#160; Used to register a transaction manager and participate in ongoing transactions.<br/>&#160;&#160;&#160;&#160;&#160; --&gt;<br/>&#160;&#160; &lt;transaction<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; transactionManagerLookupClass="org.jboss.cache.transaction.GenericTransactionManagerLookup"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; syncRollbackPhase="false"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; syncCommitPhase="false"/&gt;</p><p>&#160;&#160; &lt;!--<br/>&#160;&#160;&#160;&#160;&#160; Used to register JMX statistics in any available MBean server<br/>&#160;&#160;&#160;&#160;&#160; --&gt;<br/>&#160;&#160; &lt;jmxStatistics enabled="false"/&gt;</p><p>&#160;&#160; &lt;!--<br/>&#160;&#160;&#160;&#160;&#160; If region based marshalling is used, defines whether new regions are inactive on startup.<br/>&#160;&#160; --&gt;<br/>&#160;&#160; &lt;startup regionsInactiveOnStartup="true"/&gt;</p><p>&#160;&#160; &lt;!--<br/>&#160;&#160;&#160;&#160;&#160; Used to register JVM shutdown hooks.<br/>&#160;&#160;&#160;&#160;&#160; hookBehavior: DEFAULT, REGISTER, DONT_REGISTER<br/>&#160;&#160; --&gt;<br/>&#160;&#160; &lt;shutdown hookBehavior="DEFAULT"/&gt;</p><p>&#160;&#160; &lt;!--<br/>&#160;&#160;&#160;&#160;&#160; Used to define async listener notification thread pool size<br/>&#160;&#160; --&gt;<br/>&#160;&#160; &lt;listeners asyncPoolSize="1" asyncQueueSize="100000"/&gt;</p><p>&#160;&#160; &lt;!--<br/>&#160;&#160;&#160;&#160;&#160; Used to enable invocation batching and allow the use of Cache.startBatch()/endBatch() methods.<br/>&#160;&#160; --&gt;<br/>&#160;&#160; &lt;invocationBatching enabled="false"/&gt;</p><p>&#160;&#160; &lt;!--<br/>&#160;&#160;&#160;&#160;&#160; serialization related configuration, used for replication and cache loading<br/>&#160;&#160; --&gt;<br/>&#160;&#160; &lt;serialization objectInputStreamPoolSize="12" objectOutputStreamPoolSize="14" version="3.0.0"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; marshallerClass="org.jboss.cache.marshall.VersionAwareMarshaller" useLazyDeserialization="false"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; useRegionBasedMarshalling="false"/&gt;</p><p>&#160;&#160; &lt;!--<br/>&#160;&#160;&#160;&#160;&#160; Eviction configuration.&#160; WakeupInterval defines how often the eviction thread runs, in milliseconds.&#160; 0 means<br/>&#160;&#160;&#160;&#160;&#160; the eviction thread will never run.<br/>&#160;&#160; --&gt;<br/>&#160;&#160; &lt;eviction wakeUpInterval="500"&gt;<br/>&#160;&#160;&#160;&#160;&#160; &lt;default algorithmClass="org.jboss.cache.eviction.LRUAlgorithm" eventQueueSize="200000"&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;property name="maxNodes" value="5000" /&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;property name="timeToLive" value="1000" /&gt;<br/>&#160;&#160;&#160;&#160;&#160; &lt;/default&gt;<br/>&#160;&#160;&#160;&#160;&#160; &lt;region name="/griffin_peter"&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;property name="timeToLive" value="2000" /&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;!--&lt;property name="maxAge" value="10000" /&gt;--&gt;<br/>&#160;&#160;&#160;&#160;&#160; &lt;/region&gt;<br/>&#160;&#160;&#160;&#160;&#160; &lt;region name="/org/jboss/data2" algorithmClass="org.jboss.cache.eviction.FIFOAlgorithm" eventQueueSize="100000"&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;property name="maxNodes" value="3000" /&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;property name="minTimeToLive" value="4000" /&gt;<br/>&#160;&#160;&#160;&#160;&#160; &lt;/region&gt;<br/>&#160;&#160; &lt;/eviction&gt;</p><p>&#160;&#160; &lt;!--<br/>&#160;&#160;&#160;&#160;&#160; Cache loaders.</p><p>&#160;&#160;&#160;&#160;&#160; If passivation is enabled, state is offloaded to the cache loaders ONLY when evicted.&#160; Similarly, when the state<br/>&#160;&#160;&#160;&#160;&#160; is accessed again, it is removed from the cache loader and loaded into memory.</p><p>&#160;&#160;&#160;&#160;&#160; Otherwise, state is always maintained in the cache loader as well as in memory.</p><p>&#160;&#160;&#160;&#160;&#160; Set 'shared' to true if all instances in the cluster use the same cache loader instance, e.g., are talking to the<br/>&#160;&#160;&#160;&#160;&#160; same database.<br/>&#160;&#160; --&gt;<br/>&#160;&#160; &lt;loaders passivation="false" shared="false"&gt;<br/>&#160;&#160;&#160;&#160;&#160; &lt;preload&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;node fqn="/griffin_peter"/&gt;<br/>&#160;&#160;&#160;&#160;&#160; &lt;/preload&gt;</p><p>&#160;&#160;&#160;&#160;&#160; &lt;loader class="org.jboss.cache.loader.FileCacheLoader" async="true" fetchPersistentState="true"<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ignoreModifications="false" purgeOnStartup="true"&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;properties&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; check.character.portability=false<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; location=/web/dev/jboss-cache<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/properties&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;singletonStore enabled="false" class="org.jboss.cache.loader.SingletonStoreCacheLoader"&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;properties&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pushStateWhenCoordinator=true<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; pushStateWhenCoordinatorTimeout=20000<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/properties&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/singletonStore&gt;<br/>&#160;&#160;&#160;&#160;&#160; &lt;/loader&gt;<br/>&#160;&#160; &lt;/loaders&gt;<br/>&lt;/jbosscache&gt;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>Here is the code I have (based on code in JBoss Cache User Guide 3.x.x)</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>package tests.cache.loader;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>import org.jboss.cache.Cache;<br/>import org.jboss.cache.CacheFactory;<br/>import org.jboss.cache.DefaultCacheFactory;<br/>import org.jboss.cache.Fqn;<br/>import org.jboss.cache.Node;</p><p>import org.junit.AfterClass;<br/>import org.junit.BeforeClass;<br/>import org.junit.Test;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>public class CustomCacheLoaderTest {<br/>&#160;&#160;&#160; /** cache. */<br/>&#160;&#160;&#160; private static Cache&lt;String, Object&gt; cache = null;</p><p>&#160;&#160;&#160; class TestTO {<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; private String field1;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public String toString() {<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return this.getClass().getSimpleName() + ": field1=" + field1;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br/>&#160;&#160;&#160; }</p><p>&#160;&#160;&#160; @AfterClass<br/>&#160;&#160;&#160; public final static void afterClass() throws Exception {<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; cache.stop();<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; cache.destroy();<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; cache = null;<br/>&#160;&#160;&#160; }</p><p>&#160;&#160;&#160; @BeforeClass<br/>&#160;&#160;&#160; public final static void beforeClass() throws Exception {<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; CacheFactory cacheFactory = new DefaultCacheFactory();<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; cache = cacheFactory.createCache("jboss-cache-configuration.xml");<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; cache.create();<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; cache.start();<br/>&#160;&#160;&#160; }</p><p>&#160;&#160;&#160; @Test<br/>&#160;&#160;&#160; public final void put() throws Exception {<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Object listener = new CustomCacheListener();<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; cache.addCacheListener(listener);<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Node rootNode = cache.getRoot();<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Fqn peterGriffinFqn = Fqn.fromString("/griffin_peter");<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Node peterGriffinNode = rootNode.addChild(peterGriffinFqn);</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; TestTO testTO = new TestTO();<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; testTO.field1 = "This is a test string!";<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; peterGriffinNode.put("testTO", testTO);<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println("Fqn: /griffin_peter: Key=testTO; Value="<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; + cache.get("/griffin_peter", "testTO"));</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println("\nWaiting for 4000 milliseconds ...");<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Thread.sleep(4000);<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; java.util.Map data = cache.getData(Fqn.fromString("/griffin_peter"));<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println("data.size()=" + data.size());<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println("Fqn: /griffin_peter: Key=testTO; Value="<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; + cache.get("/griffin_peter", "testTO"));<br/>&#160;&#160;&#160; }</p><p>}</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>this outputs:</p><p><span style="font-size: 10pt;"><p align="left">Fqn: /griffin_peter: Key=testTO; Value=TestTO: field1=This is a test string!</p><p align="left" style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p align="left">Waiting for 4000 milliseconds ...</p><p align="left">data.size()=0</p></span></p><p>Fqn: /griffin_peter: Key=testTO; Value=null</p><p><span style="font-size: 10pt;"></span></p><p><span style="font-size: 10pt;"></span>When I plug a Cache Listener in, the output is:</p><p><span style="font-size: 10pt;"></span><span style="font-size: 10pt;">09:04:07.678 [CustomCacheListener] Created node: /griffin_peter<p><p align="left">09:04:07.803 [CustomCacheListener] Created node: /griffin_peter</p><p align="left">09:04:07.819 [CustomCacheListener] Visited node: /griffin_peter</p><p align="left">09:04:07.819 [CustomCacheListener] Visited node: /griffin_peter</p><p align="left">Fqn: /griffin_peter: Key=testTO; Value=TestTO: field1=This is a test string!</p><p align="left" style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p align="left">Waiting for 4000 milliseconds ...</p><p align="left">09:04:09.866 [CustomCacheListener] Evicted node: /griffin_peter</p><p align="left">09:04:09.866 [CustomCacheListener] Evicted node: /griffin_peter</p><p align="left">09:04:11.819 [CustomCacheListener] Created node: /griffin_peter</p><p align="left">09:04:11.819 [CustomCacheListener] Created node: /griffin_peter</p><p align="left">data.size()=0</p><p align="left">09:04:11.819 [CustomCacheListener] Visited node: /griffin_peter</p><p align="left">09:04:11.819 [CustomCacheListener] Visited node: /griffin_peter</p></p><p align="left">Fqn: /griffin_peter: Key=testTO; Value=null</p><p align="left"><span style="font-size: 10pt;"></span></p></span></p><p align="left"><span style="font-size: 10pt;"></span>So, the RAM is evicted at 09:04:09.866, node is recreated from backend store at 09:04:11.819 but the value for key testTO is null when it should be a TestTO object with field1 populated.</p><p align="left"><span style="font-size: 10pt;"></span></p><p align="left"><span style="font-size: 10pt;"></span>Any ideas why the backend store isn't storing keys and values?</p></div>

<div style="background-color: #f4f4f4; padding: 10px; margin-top: 20px;">
    <p style="margin: 0;">Reply to this message by <a href="http://community.jboss.org/message/599443#599443">going to Community</a></p>
        <p style="margin: 0;">Start a new discussion in JBoss Cache at <a href="http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2052">Community</a></p>
</div></td>
                        </tr>
                    </tbody>
                </table>


                </td>
            </tr>
        </tbody>
    </table>

</div>

</body>
</html>