19.3. Managing the caches
Whenever you pass an object to
save()
, update()
or saveOrUpdate()
, and whenever you retrieve an object using load()
, get()
, list()
, iterate()
or scroll()
, that object is added to the internal cache of the Session
.
When
flush()
is subsequently called, the state of that object will be synchronized with the database. If you do not want this synchronization to occur, or if you are processing a huge number of objects and need to manage memory efficiently, the evict()
method can be used to remove the object and its collections from the first-level cache.
ScrollableResults cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set while ( cats.next() ) { Cat cat = (Cat) cats.get(0); doSomethingWithACat(cat); sess.evict(cat); }
The
Session
also provides a contains()
method to determine if an instance belongs to the session cache.
To evict all objects from the session cache, call
Session.clear()
For the second-level cache, there are methods defined on
SessionFactory
for evicting the cached state of an instance, entire class, collection instance or entire collection role.
sessionFactory.evict(Cat.class, catId); //evict a particular Cat sessionFactory.evict(Cat.class); //evict all Cats sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections
Note
This method is invoked as a result of the application using the SessionFactory.evictXXX(..., Serializable id) API. Applications using this API should recognize that calls to it may block waiting for other transactions to complete with a JBoss Cache based Second Level Cache.
Further, such calls that occur in the middle of a transaction will hold locks until the transaction commits and will not update other nodes until the transaction commits. If this is a problem, it may be helpful to do the eviction before the transaction begins or after it commits.
The
CacheMode
controls how a particular session interacts with the second-level cache:
CacheMode.NORMAL
: will read items from and write items to the second-level cacheCacheMode.GET
: will read items from the second-level cache. Do not write to the second-level cache except when updating dataCacheMode.PUT
: will write items to the second-level cache. Do not read from the second-level cacheCacheMode.REFRESH
: will write items to the second-level cache. Do not read from the second-level cache. Bypass the effect ofhibernate.cache.use_minimal_puts
forcing a refresh of the second-level cache for all items read from the database
To browse the contents of a second-level or query cache region, use the
Statistics
API:
Map cacheEntries = sessionFactory.getStatistics() .getSecondLevelCacheStatistics(regionName) .getEntries();
You will need to enable statistics and, optionally, force Hibernate to keep the cache entries in a more readable format:
hibernate.generate_statistics true hibernate.cache.use_structured_entries true