Using Grails console-plugin to Interactively Evict Hibernate’s Second Level Cache
It can be very handy to use Grails console-plugin to investigate database-cache-related issues. For instance in a case where everything works as expected but still a certain value is not displayed on a view – the reason can be that an old value is provided due to a configured database-caching. In the following case it’s a Hibernate’s second-level cache configured in conjunction with Grails and the following simple domain-model:
[groovy title="Company.groovy" highlight="6"]
class Company {
static hasMany = [isins: ISIN]
Set<ISIN> isins
static mapping = {
isins lazy: false, cache: true
}
}
[/groovy]
[groovy title="ISIN.groovy"]
class ISIN {
String name
static constraints = {
name blank: false, unique: true
}
}
[/groovy]
The Company domain is using Hibernate’s second level cache to cache a collection (association) of ISIN domain-objects. As an addition the collection is fetched non-lazy (eager) which avoids GORM firing N+1 queries when iterating over the ISINs.
—
But back to the original problem – to ensure that a value is not fetched out of a cache it is best to just empty that cache. Luckily, we can use the SessionFactory of Hibernate to do that. Having a Grails-setup and using the Grails console-plugin it’s easy as a one-liner on the interactive prompt to say that we want to evict the second level cache for a given collection:
[groovy title="interactive grails-console" highlight="9"]
// Groovy Code here
// Implicit variables include:
// ctx: the Spring application context
// grailsApplication: the Grails application
// config: the Grails configuration
// request: the HTTP request
// session: the HTTP session
ctx.sessionFactory.evictCollection('Company.isins')
[/groovy]
The groovy-script gets the Hibernate SessionFactory from Spring’s application-context and calls evictCollection which according to the source-code of evictCollection delegates to a CollectionPersister that defines a contract between the persistence strategy and the actual persistent collection. Hibernate then takes the underlying CollectionRegionAccessStrategy for the ISIN-collection and forcibly evicts all items from the cache immediately without regard for transaction-isolation.



