Native queries are clearing the 2nd level cache entries.
- 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?
- 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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…