Hibernate Secondary Level Cache - java

Scenario: Project consists of reference data which is updated once a week. Hence constantly querying this reference data for every transaction from the database is not efficient. Hence the motivation to cache this data.
Question: If secondary level caching and query caching in Hibernate is activated and the cache element in the hibernate configuration is set to read-only, how will hibernate know when to update the cache if a change is made to the database via another program. Is this automatically handled by Hibernate or do we have to clear the cache using some trigger?
If this is handled by Hibernate could someone shed light on how this is handled?
The JBoss documentation was not very clear about the management of the cache.
I am currently using Hibernate 3.6 with Spring 3.1 and do not wish to upgrade to Hibernate 4 if its not necessary.

It wont.
The second level cache expects all access to the data to happen via the ORM framework so if you have another actor in the db your cache will become stale.
You can clear the cache though - see this
code snippet
So you could expose a service that allows the 3rd party to clear the cache on your app when the database gets updated.

Related

Distributed Infinispan Cache as Hibernate L2 Cache Issue

I would like to create an application, where I would use Hibernate L2 Cache to reduce the unnecessity to always requesting database for data.
In my application, over 80% of the time would be READ operation, and less than 20% would be Create / Update / Delete Operation. Therefore I think using Hibernate L2 Cache would be beneficial. However, as we are going to horizontal scale the application, we would like to use Infinispan as the L2 Cache of Hibernate.
However there are several questions which we are uncertain of.
If I understand correctly, Hibernate L2 Cache should work by updating the cache, whenever there is a new create / update / delete operation, or when the query has not yet queried previously. Therefore on a multiple servers setup connecting to the same database, since there are network IO issue, how could multiple update operation works in such environment? As the 2 application server may update the database simultaneously, each update the same entity to different data, but due to network IO issue, how could Hibernate know this data should be cached and synced, and this data should not?
It depends what kind of cache you are using. An invalidation cache, which I would suggest you to use here, will just invalidate cache entries that are stale. A replicating cache would replicate the changes to each node in the cluster. Hibernate just asks the cache implementation for the cache entry and if the cache returns that, it will use that and avoid accessing the database. If the cache entry is stale or how much blocking is involved in that cache lookup depends on the transaction configuration of the cache.

Refresh Hibernate cache across the contexts

I have two context on single tomcat pointing to same database. I am using ehcache for 2nd level caching with Hibernate.
Now, when I do any create/update/delete operation on database, it reflect in contect1 cache but to update in contecxt2 cache, it took almost 15-20 min. I can't use refresh/clear function in context2 as I don't know when to refresh.
How Can I refresh context2's Hibernate cache when there is any update happened through context1?
Also to do clustering for Hibernate cache, I need to give IP address and port number, but in my case, both are same for two contexts. So I think I can't use Hibernate cache clustering.

What's difference between hibernate caching and Spring framework cache?

I have an application where I get the data from database (using hibernate).
I want to load the cache (per user) with database state once per day and use the cache instead.
I'm using Spring framework with Hibernate and I know that both of them have some caching possibilities.
What are the differences between them? What would be a better choice?
Starting with Hibernate cache is a more prudent decision in my view, especially because the two don't exclude each other. In terms of performance Spring cache can offer you more, its much higher in the stack, you can cache business results (basically more than you can with hibernate's second level cache).
However one outstanding distinction is clearing the cache. With Spring cache you need to clear explicitly, while the hibernate cache is maintained automatically if your inserts, updates and deletions go through hibernate's framework.
In the context of the projects that I'm involved, using hibernate's second level cache is assumed, a default almost. Spring cache we use for the data that are much more static in nature.
Hibernate has 2 levels of cache. 1. First level 2. Second level
Second level chache is for the whole application and first level cache is for the current hibernate session. There is no cache available per user basis.
Also if you are using spring managed beans + caching. There is a provision for you to cache the beans for entire application rather than for a user. (little uncertain on this)
It sounds to me that you want to store the data in the user's session. ie., as long as the user is having an active session. Spring has a session scoped beans you may want to use these to cache the data per user.

Spring Roo JPA - Why are manual DB updates automatically available in Persistence Context?

I have developed a web app using Spring Roo (Spring MVC 3), JPA 1, Hibernate, JSTL, JQUERY etc..Persistence Contexts are application managed via a JPA Transaction manager. DB used is MSSQL2005. The application is running on JBOSS 5.
Everything works fine. My question is something that has been on my mind, yet i have yet to come across a suitable answer.
Suppose the following:
I retrieve some row from Table T using entitymanager.find(), and present the data to a page
I manually change one of the field values in the row (via SQL an gui tool).
I immediately repeat step (1), and I have the manually updated value available.
Is this correct? My understanding was that values within the persistence context do not get updated unless:
calling em.refesh()
object is not available in PERSISTENCE CONTEXT (--> query DB instead)
My experience seems to contradict the link below, which actually makes logical sense to me.
Updated data (in Database) is not visible via JPA/Eclipselink
Many thanks
NaP
This is the correct behavior. The values within a persistence context won't be updated unless you call em.refresh() within a SESSION.
When you retrieve the web page again, the old session is closed and a new session is opened with new data reflected.

How I can disable the second-level cache of some certain entities in Hibernate without changing annotations

I'm using Hibernate second level cache in my application, for certain business reason I can't change the entity annotation any more.
In my project, apart from changing the Database from Hibernate, there exist also other native SQL that do not go through Hibernate. Therefore, the Hibernate second-level cache data could be stale after database being updated from native SQL. That's why I want to disable the second-level cache for certain entities (programmatically or other way than changing annotation).
Thanks in advance!
WARNING: As Jens Schauder noted, it is impossible to configure Ehcache to store 0 elements in memory by setting maxElementsInMemory="0" as it effectively causes opposite effect - sets unlimited size for the cache. This behaviour is not mentioned on the Hibernate Caching page but is documented on Cache Configuration page.
I have quickly reviewed the documentation and haven't found alternative approach yet. I am unable to delete this answer by myself. :-(
My original suggestion:
You can configure the implementation provider of second level cache to short TTL times and/or to store 0 entries of particular entity type.
E.g. if you are using the Ehcache, you can configure it in ehcache.xml:*
<cache
name="com.problematic.cache.EntityName"
maxElementsInMemory="0" <<== this should effectively disable caching for EntityName
overflowToDisk="false" <<== Do not overflow any entries to disk
/>
See Hibernate Caching in Ehcache documentation.
In Terracotta 3.1 and above, you can enable/disable Hibernate 2nd Level Caches on a per region basis, both in the configuration (statically) and at runtime, using the Terracotta Developer Console.
You can also monitor in realtime statistics about the cache and Hibernate, for individual nodes in a cluster or cluster-wide.
Terracotta is open source. For more details, check out Terracotta for Hibernate.

Categories