Search code examples
hibernatecachinggrailsehcachesecond-level-cache

Cached association not get updated upon child item created


Say, I have domain object

class Parent {
  static hasMany = [children:Child]
  static mapping = {
   cache true
   children cache: true // !!!
  }
}

I have admin page that shows Parent with list of children. Also there is an ability to add new child. What happens to me is when I add new child with line (!!!) enabled - child not appears on Parent page. Though it's added to DB, because server restart makes it show. Without line (!!!) it works as expected.

Is this how it should work by design? Should I manually invalidate the association cache? Also something similar is described in this question cache setting in grails

Grails documentation is not very informative on this http://grails.org/doc/latest/guide/GORM.html#caching .

Btw. I'm using Grails 2.2.1.


Solution

  • Ok, found the reason. Seems Hibernate works this way by design. It's described here http://planet.jboss.org/post/collection_caching_in_the_hibernate_second_level_cache

    This part:

    What happens when a new Member is created and associated with a Group whose members collection is cached? As I stated above, Hibernate doesn’t update the collection in the cache, it just removes it. So, we’d expect the collection to be removed. And it should be, but there is an important subtlety that application developers need to be aware of:

    Collections are only invalidated from the cache as a result of an operation on the Java object that represents the collection! Performing some Java operation that results in a change in the database whereby a fresh read of the database would add the member to the collection isn’t sufficient.

    So the fix was to inject in Controller

    def sessionFactory
    

    and manually invalidate collections cache in save() method

    sessionFactory.cache.evictCollectionRegions()