Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hibernate cached query not updated when new record inserted

We have a EHCache cluster, hibernate and Mysql.

Everything is working almost fine. Criteria searches are being cached and when records are modified on other members of the clusters the cached queries are updated instantly on the other servers.

however, my problem is when new records are inserted. The cached queries on that table do not know about it until the cached query are expired.

I probably have missed something on my EHcache.xml configuration, but I have no idea what could it be.

Any ideas?

EHCache.xml follows:

`

<!--<diskStore path="java.io.tmpdir"/>-->

<!-- means for cache replication -->

<cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
    properties="connect=
        TCP(bind_port=10700):
        S3_PING(...):
        MERGE2(max_interval=30000;min_interval=10000):
        FD_SOCK(start_port=0):
        FD(timeout=3000;max_tries=3):
        VERIFY_SUSPECT(timeout=1500):
        BARRIER():
        pbcast.NAKACK(use_mcast_xmit=false;gc_lag=0;retransmit_timeout=300,600,1200,2400,4800;discard_delivered_msgs=true):
        UNICAST(timeout=300,600,1200):
        pbcast.STABLE(stability_delay=1000;desired_avg_gossip=50000;max_bytes=400K):
        pbcast.GMS(print_local_addr=true;join_timeout=300;view_bundling=true):
        FC(max_credits=2M;min_threshold=0.10):
        FRAG2(frag_size=60K):
        pbcast.STREAMING_STATE_TRANSFER()"
    propertySeparator="::" />    

<!-- default query cache to be used for all queries without an explicit cache -->

<cache
    name="org.hibernate.cache.StandardQueryCache"
    maxElementsInMemory="100"
    eternal="false"
    timeToLiveSeconds="600"
    overflowToDisk="false"
    statistics="true">
    <cacheEventListenerFactory
        class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
        properties="replicateAsynchronously=true, replicatePuts=true,
        replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>    

<!-- timestamps of particular last update time to tables -->

<cache
    name="org.hibernate.cache.UpdateTimestampsCache"
    maxElementsInMemory="5000"
    eternal="true"
    overflowToDisk="false"
    statistics="true">
    <cacheEventListenerFactory
        class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
        properties="replicateAsynchronously=true, replicatePuts=true,
        replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>

<!-- default cache to use for all cacheable entities without an explicit cache -->

<defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="600"
        timeToLiveSeconds="600"
        overflowToDisk="false"
        maxElementsOnDisk="10000000"
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="600"
        memoryStoreEvictionPolicy="LRU"
        statistics="true">
        <cacheEventListenerFactory
            class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
            properties="replicateAsynchronously=true, replicatePuts=true,
            replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true" />
</defaultCache>

`

like image 673
Rafael Avatar asked Jul 21 '11 14:07

Rafael


People also ask

How Hibernate ensures second level cache is updated with latest data in database?

Hibernate manages the cache himself, so when you update some entity thru hibernate Session it will invalidate cache entry assocciated with this entity - so cache is always fresh.

Does Hibernate cache query results?

Query Cache: Hibernate can also cache result set of a query. Hibernate Query Cache doesn't cache the state of the actual entities in the cache; it caches only identifier values and results of value type. So it should always be used in conjunction with the second-level cache.

How query level cache is implemented in Hibernate?

To use the query cache, you must first activate it using the hibernate. cache. use_query_cache="true" property in the configuration file. By setting this property to true, you make Hibernate create the necessary caches in memory to hold the query and identifier sets.


1 Answers

I'm afraid it's a little too late for the author, but I thought my answer can be useful for anyone else with the same problem.

You should remember how the StandardQueryCache and the UpdateTimestampsCache work. When the query cache is checked for a query, the time the query was cached is compared to the timestamps of the last update of all tables in the query. If any tables were updated after the query was cached, the cached result gets discarded and the database is used instead. Timestamps of the last update for each table are stored in the UpdateTimestampsCache.

In the above configuration the values from the UpdateTimestampsCache are not copied to other members of the cluster, so Hibernate looks at the old timestamps and thinks that a cached query is up-to-date. As a result newly inserted records are neglected. To fix it simply set replicateUpdatesViaCopy for the UpdateTimestampsCache to true.

like image 191
John29 Avatar answered Oct 24 '22 08:10

John29