-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Second level cache is cleared automatically after commit
PostPosted: Sun Nov 09, 2008 5:51 pm 
Newbie

Joined: Sun Nov 09, 2008 5:22 pm
Posts: 2
I've been looking for the answer for few days now, wasting my weekend on this, and the fact that deep digging in google didn't find any answers means that this is probably something stupid on my part.

I have secend level cache enabled in Hibernate but it always goes to the database to load the object.

Cache debug shows entries as follows, for any transaction, not just the ones that involve the objects marked for caching:

Code:
16:28:33,767 DEBUG SessionImpl:422 - after transaction completion
16:28:33,845 DEBUG SessionFactoryImpl:830 - evicting second-level cache: com.dummy.data.Network
16:28:33,845 DEBUG SessionFactoryImpl:830 - evicting second-level cache: com.dummy.data.CardStatus
16:28:33,845 DEBUG SessionImpl:273 - closing session

When loading the object (via session.load()) EhCache shows:

Code:
16:32:42,931 DEBUG EhCache:68 - key: com.dummy.data.Network#3
16:32:42,931 DEBUG EhCache:77 - Element for com.dummy.data.Network#3 is null

--> loads data from DB here
Code:
16:32:42,931 DEBUG ReadOnlyCache:58 - Caching: com.dummy.data.Network#3


This happens every time, ie it looks like the object is always put to the cache but never found in the cache.

My theory is that Hibernate evicts my objects from second level cache after each session is closed, basically clearing the cache. But then what's the point of the second level cache? It then just works like first level cache. I've grepped all the source code I have and didn't find any calls to Evict anywhere.

I've changed the EhCache to HashTable provider and I've got the same results.

The Network object is very simple, I am using it as a test case. I've also cut down all the code to the minimum usable and still get this behavior.

Here is the relevant Hibernate config:

Code:
<hibernate-configuration>
    <session-factory>
        <property name="show_sql">true</property>
        <property name="format_sql">false</property>
        <property name="use_sql_comments">true</property>
        <property name="generate_statistics">false</property>
        <property name="max_fetch_depth">2</property>
        <property name="default_batch_fetch_size">16</property>
        <property name="use_streams_for_binary">true</property>
        <property name="connection.isolation">2</property>

        <property name="hibernate.c3p0.min_size">3</property>
        <property name="hibernate.c3p0.max_size">20</property>
        <property name="hibernate.c3p0.timeout">300</property>
        <property name="hibernate.c3p0.max_statements">300</property>
        <property name="hibernate.c3p0.idle_test_period">3000</property>

        <property name="hibernate.c3p0.idle_test_period">3000</property>

        <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
        <property name="hibernate.cache.use_structured_entries">true</property>
        <property name="hibernate.cache.use_second_level_cache">true</property>
<mapping resource="com/dummy/data/Network.hbm.xml" />
       
   <class-cache class="com.dummy.data.Network" usage="read-only"/>
    </session-factory>
</hibernate-configuration>


Network:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.dummy.data.Network" table="network" mutable="false">
        <id name="networkId" type="int">
            <generator class="assigned" />
        </id>
        <property name="timeZoneName" type="string" length="50" not-null="true" />
        <property name="cutoffHour" type="int" not-null="true" />
        <property name="cutoffMinute" type="int" not-null="true" />
        <property name="name" type="string" not-null="true" unique="true" />
    </class>
</hibernate-mapping>


And finally the test code I am using:
Code:
Transaction tx=session.beginTransaction();

Network net = (Network)session.load(Network.class, 3);
info("net loaded"+net.getName());
tx.commit();
session.close();


And finally the ehcache config:
Code:
<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="false"
        />
    <cache name="com.dummy.data.Network"
        maxElementsInMemory="100"
        eternal="true"
        timeToIdleSeconds="600"
        timeToLiveSeconds="1200"
        overflowToDisk="false"
    />
</ehcache>


Any help would be welcome, I am going crazy in here :-)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 10, 2008 11:55 am 
Newbie

Joined: Sun Nov 09, 2008 5:22 pm
Posts: 2
That was a stupid mistake on my part after all.

I had a db logger setup that was putting messages to the db while my test code run and that code was using a sql query to insert data to log table. Every time that sql query would run it would invalidate the second level cache:

Code:
SQLQuery query = s.createSQLQuery("INSERT INTO message_log (dateCreated,realm, tag, messageType, transmissionDate, message) VALUES(getutcdate(),?,?,?,?,?,?)");
      query.setParameter(0, getRealm());
      query.setParameter(1, getTag());
      query.setParameter(2, getMessageType());
      query.setParameter(3, getTransmissionDate());
      query.setParameter(54 getMessage());
      query.executeUpdate();


I've changed it to have a message class with proper hibernate mapping and just do session.persist(message). The reason I was using a query to insert was because i didn't need or want messageId on that table, these are not really entities and I only insert them

well, live and learn


Top
 Profile  
 
 Post subject: Re: Second level cache is cleared automatically after commit
PostPosted: Wed Jan 06, 2010 11:41 am 
Newbie

Joined: Fri Dec 26, 2008 1:13 am
Posts: 8
Hi,

I am also having the problem that my caches are being evicted (looking at the logging output somehow the SessionFactoryImpl evicts the caches), but I do not understand why!! Under what condition does it get evicted? I am stuck on this for two days now and my problem seems very close to yours, but I do not understand your solution in the second post. I am new to Hibernate, could you please explain why your caches got evicted?

Thank you,
Andrej


Top
 Profile  
 
 Post subject: Re: Second level cache is cleared automatically after commit
PostPosted: Wed Jan 06, 2010 7:39 pm 
Newbie

Joined: Fri Dec 26, 2008 1:13 am
Posts: 8
Hi,

Now I found that my second-level caches are being cleared whenever I write to another database table than the one that I am actually caching: I am read-only caching table Client and whenever writing to the table User, the Client-cache gets cleared!! Now I also understand your second post. But, it is not clear to me under what conditions the Client-cache is being cleared. The User-table has a foreign key to Client, but because I am using a read-only cache for Client, it should not be cleared, I guess?

So under what conditions will a read-only cache be cleared?

Thank you,
Andrej


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.