davelt
davelt

Reputation: 69

Grails Cache Restart

I am using the grails cache plugin to cache a collection of gorm objects. This method is in a service

@Cacheable('allBooks')
List<Book> getAllFictionBooks() {
    log.info("Looking up all books and adding them to a cache")
    Book.findAllByIsFiction(true)
}

However on server restart I get this error and often have to restart my server a second time

failed to lazily initialize a collection of role: com.Book.applyTo, no session or session was closed

I added

grails.cache.clearAtStartup = true

to Config.groovy but that didn't seem to help. I am probably doing something stupid. Any help is much appreciated.

I am using Grails 2.2.1. Plugin: cache:1.1.1

Upvotes: 0

Views: 663

Answers (1)

Burt Beckwith
Burt Beckwith

Reputation: 75671

You don't want to cache GORM query results with the cache plugin - Hibernate already has support for this with the query cache. And it's a lot more robust, specifically with invalidation. For example If your query returns 4 books, but at some point in the future a new fiction book is added, you need to manually remove this result. But Hibernate does this already - any new, deleted, or even modified book will cause all cached results with books to be removed.

But the issue you're seeing is that apparently you have a lazy-loaded applyTo collection. Once the query runs and you store the values in the Spring-managed cache and then the web request ends, the Hibernate Session is closed and the instances become disconnected. Later accessing any uninitialized lazy properties will trigger the exception you're seeing unless you reattach the instance to the current session, e.g. with merge(). But Hibernate would have done that for you if you used the 2nd-level cache.

The 2nd-level cache is also easily clusterable. Once you add a 2nd web server, you need to ensure that you don't have 2 independent caches, but rather 2 caches that update each other to stay in sync. This is obviously doable with the Spring caching, but it's more straightforward with Hibernate/GORM.

Upvotes: 1

Related Questions