Part I

In a Grails app, I understand that you enable the 2nd level cache per domain class by adding

static mapping {
  cache true
}

By default the 2nd level cache is only used when get() is called, but it can also be used for criteria queries and dynamic finders by adding cache true to the query.

However, I'm still not sure I understand how the query cache works. My best guess is that:

  • there are separate query caches for each domain class, e.g. one for Book and another for Author
  • before a query like Author.findByName('bob', [cache: true]) is executed, a cache key is computed, which is based on the domain class (Author), the query (findByName) and the query parameters ('bob'). If that key is found in the Author query cache, the cached results are returned instead of executing the query
  • any time an Author is saved, deleted, or updated, the Author query cache is flushed

This seems reasonable until we consider that a query that returns Book instances may join to the Author table. In that case, it would be necessary to flush both the Book and Author query caches when an Author is saved, deleted, or updated. This leads me to suspect that perhaps there is just one single query cache and it is cleared whenever any cached domain class is saved?

Part II

In the Grails docs it mentions that

As well as the ability to use Hibernate's second level cache to cache instances you can also cache collections (associations) of objects.

For example:

class Author {    

  static hasMany = [books: Book]

  static mapping = { 
    cache true        // Author uses the 2nd level cache
    books cache: true // associated books use the 2nd level cache
  } 
}

class Book {
  static belongsTo = [author: Author]

  static mapping = {
    cache true // Book uses the 2nd level cache
Edit
Report