grails framework

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.