17

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.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140

3 Answers3

12

Native queries are clearing the 2nd level cache entries.

  1. Native queries (actually this is only for native inserts/deletes/updates, not queries) are invalidating the 2nd level cache entries for all caches (WHOLE CACHE). I have verified this with the current stable version of Hibernate: 4.1.9. This is sensible because Hiberante can't possibly know what was changed in the DB, so the only option is to invalidate whole 2nd level cache. This can be a serious issue in some systems which relies heavily on the 2nd level cache.

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?

  1. HQL does invalidate only a the 2nd level cache region which is related to the entity you are doing some inserts/updates/deletes on. That makes sense because Hibernate knows which entities are affected by the HQL, it can clear only the 2nd level cache region for this entity.

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.

Marek Dominiak
  • 693
  • 1
  • 7
  • 9
1

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 :)

gliptak
  • 3,592
  • 2
  • 29
  • 61
0

The closest thing I could dig up was this: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-cache

I would imagine it has a lot to do with which provider you use.

Woot4Moo
  • 23,987
  • 16
  • 94
  • 151