Native queries are clearing the 2nd level cache entries. An answer from the hibernate forum that is 7 years old says that HQL update queries also clear the 2nd level cache. But is this still true?
Since the HQL query has the exact fields to be updated, and in which entity, I think it shouldn't be that hard to behave as if a regular session.save(..)
is invoked.
This cache only works at a session level, meaning each session object caches data independently, so there is no sharing of cached data across sessions, and the cached data is deleted when the session closes. This makes the cache only useful for repeated queries in the same session.
Hibernate second level cache uses a common cache for all the session object of a session factory. It is useful if you have multiple session objects from a session factory. SessionFactory holds the second level cache data. It is global for all the session objects and not enabled by default.
You can extend this caching with an optional second-level cache. The first-level keeps being mandatory and is consulted first always. The second-level cache is used to cache object across sessions.
A second-level cache is a local store of entity data managed by the persistence provider to improve application performance. A second-level cache helps improve performance by avoiding expensive database calls, keeping the entity data local to the application.
Native queries are clearing the 2nd level cache entries.
There is though a possibility to specify what from 2nd level cache should be invalidated (or even specify that nothing is evicted from cache). Look at great blog post http://www.link-intersystems.com/bin/view/Blog/Hibernate%27s+second+level+cache+and+native+queries where this is explained thoroughly.
To prevent Hibernate from invalidating anything from cache:
SQLQuery sqlQuery = session.createSQLQuery("ALTER SESSION SET NLS_COMP = 'BINARY'");
sqlQuery.addSynchronizedQuerySpace("");
int updatedEntities = sqlQuery.executeUpdate();
To instruct Hibernate to invalidate only the Person entity cache:
SQLQuery sqlQuery = session.createSQLQuery("UPDATE PERSON SET ... WHERE ...");
sqlQuery.addSynchronizedEntityClass(Person.class);
int updatedEntities = sqlQuery.executeUpdate();
An answer from the hibernate forum that is 7 years old says that HQL update queries also clear the 2nd level cache. But is this still true?
Example:
entityManager.createQuery("delete from Person p where p.id = 1").executeUpdate();
This will invalidate "only" the Person entity cache.
I am not aware of any possibility to prevent Hibernate from invalidating 2nd level cache for specific entity when it comes to HQL.
We did see HQL update clearing the 2nd level cache when running with Hibernate 3.2.x
As a simple way to validate for your individual setup, implement something like:
http://narcanti.keyboardsamurais.de/hibernate-statistics-jsp-reloaded.html
Note details on that page before and after running the HQL update transaction ...
Or gather stats directly in your code and/or using JMX
http://docs.jboss.org/hibernate/core/3.5/reference/en/html/performance.html#performance-monitoring
As for improved behaviour, the Hibernate project might be open to implement a patch :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With