In the previous post we saw the GET and IGNORE values for CacheMode. The other values are PUT and REFRESH. Consider the below code:
public static void testPutMode() { Statistics statistics = sessionFactory.getStatistics(); Session session1 = sessionFactory.openSession(); System.out.println("Cache Put Count : " + statistics.getSecondLevelCachePutCount()); session1.get(BookType.class, 1); System.out.println("Cache Put Count : " + statistics.getSecondLevelCachePutCount()); session1.close(); System.out.println("Running in PUT mode"); Session session2 = sessionFactory.openSession(); session2.setCacheMode(CacheMode.PUT); session2.get(BookType.class, 1); session2.get(BookType.class, 2); session2.get(BookType.class, 3); System.out.println("Cache Put Count : " + statistics.getSecondLevelCachePutCount()); System.out.println("Cache Hit Count : " + statistics.getSecondLevelCacheHitCount()); session2.close(); }In the PUT mode, the session will add records to the second level cache. However it will not read any records from the cache. As the second session uses the PUT CacheMode it does nor read the record with id 1 from the cache. It fires three select queries for all three records, adding two of them to the cache. The output from above method is :
Cache Put Count : 0 Hibernate: /* load com.object.cache.BookType */
select booktype0_.ID as ID0_0_, booktype0_.NAME as NAME0_0_ from BOOK_TYPE_MASTER booktype0_ where booktype0_.ID=? Cache Put Count : 1 Running in PUT mode Hibernate: /* load com.object.cache.BookType */ select booktype0_.ID as ID0_0_, booktype0_.NAME as NAME0_0_ from BOOK_TYPE_MASTER booktype0_ where booktype0_.ID=? Hibernate: /* load com.object.cache.BookType */ select booktype0_.ID as ID0_0_, booktype0_.NAME as NAME0_0_ from BOOK_TYPE_MASTER booktype0_ where booktype0_.ID=? Hibernate: /* load com.object.cache.BookType */ select booktype0_.ID as ID0_0_, booktype0_.NAME as NAME0_0_ from BOOK_TYPE_MASTER booktype0_ where booktype0_.ID=? Cache Put Count : 3 Cache Hit Count : 0The other CacheMode is REFRESH. This has the same behavior as PUT (Or does it ?) From the Hibernate docs:
CacheMode.PUT: will write items to the second-level cache. Do not read from the second-level cache CacheMode.REFRESH: will write items to the second-level cache. Do not read from the second-level cache. Bypass the effect of hibernate.cache.use_minimal_puts forcing a refresh of the second-level cache for all items read from the databaseI tested the above method for Refresh but did not find any difference in the result. I found one link that seemed to add something to this explanation.
What is the default value for CacheMode ?
public static void testDefaultCacheMode() { Session session = sessionFactory.openSession(); System.out.println(session.getCacheMode()); }The output is :
NORMAL
thanks for info.. :)
ReplyDeleteDifference between PUT and REFRESH, it might be this:
ReplyDelete- as you can see PUT adds only the last 2 new objects, it does not touch the first one, existing in the second level cache
- REFRESH would also add the last 2 new objects AND trigger a refresh the first one, existing in the second level cache
Thanks for the very useful examples. I learned it all from here about CachMode options and, at the end of your article, i made the connection above.
DeleteThere is also a bit in the Hibernate doc, about REFRESH (neglect the use of the region parameter and focus only on the REFRESH part):
20.4.2. Query cache regions
If you require fine-grained control over query cache expiration policies, you can specify a named cache region for a particular query by calling Query.setCacheRegion().
List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger")
.setEntity("blogger", blogger)
.setMaxResults(15)
.setCacheable(true)
.setCacheRegion("frontpages")
.list();
If you want to force the query cache to refresh one of its regions (disregard any cached results it finds there) you can use org.hibernate.Query.setCacheMode(CacheMode.REFRESH). In conjunction with the region you have defined for the given query, Hibernate will selectively force the results cached in that particular region to be refreshed. This is particularly useful in cases where underlying data may have been updated via a separate process and is a far more efficient alternative to bulk eviction of the region via org.hibernate.SessionFactory.evictQueries().
This comment has been removed by the author.
DeleteI admit the HIbernate doc extract i posted is about "querry cache" whereas you use "session.get" in your examples which does NOT use query caches, but the understanding of REFRESH is the same: If an object with the Id specified in the method call (in case on session.get) or with the id extracted from the DB (in the case of a querry, which always interogates the DB, unless query cash is used) is present in the second level cache, it will be refreshed (session.refresh(p))
DeleteInteresting thoughts Vlad, This is good. Let me try and verify the same. Ill get back on this. Thanks
DeleteLike!! I blog quite often and I genuinely thank you for your information. The article has truly peaked my interest. furniture auckland
ReplyDeleteInteresting thoughts Vlad, This is good. Let me try and verify the same. Ill get back on this. Thanks.how does a leo woman attract a capricorn man
ReplyDeletez8 สล็อต ผู้ให้บริการเกมพนันออนไลน์แบบครบวงจรสูงที่สุด pg slot และก็มาจากมาเก๊าเพิ่มความพิเศษได้อย่างยอดเยี่ยมทางเว็บไซต์แห่งนี้มีงานบริการที่ถูกใจนักการพนันโซนทวีปเอเชีย
ReplyDelete