1

If I indicate that the results of a query are to be cached, e.g.

// This example shows the execution of a Hibernate query in a Grails app,
// but the question isn't really about Grails
Author author = new Author(name: 'Charles Dickens')
def results = Book.findByAuthor(author, [cache: true])

Is it necessary for Author to implement equals() and hashCode() in order for the caching to be effective?

If I don't implement these methods, it appears that if I execute the code above twice, the second author object will have a different hash code to the first, and therefore the cached results will not be returned the second time the query is executed.

Update

For those unfamiliar with GORM, the query above is equivalent to the HQL

executeQuery("from Book b where b.author = ?", author)
Dónal
  • 185,044
  • 174
  • 569
  • 824
  • I don't know how gorm works and what the actual query is behind `findByAuthor`, but AFAIK, Hibernate doesn't care about the hashCode of your entities. It uses the query, and its actually bound parameters, to compute the cache key. How do you diagnose that the cached results are not returned? – JB Nizet Feb 24 '12 at 12:14
  • are you executing with the same session? – Oleg Mikheev Feb 24 '12 at 12:18
  • @Qwe I'm talking about a case where the two queries are executed with different sessions. If they were executed in the same session, I don't think the 2nd level cache would be used. – Dónal Feb 24 '12 at 12:30
  • 1
    @JBNizet I've updated my question with what I think is an equivalent HQL query. I think what you're saying is that in the SQL generated by Hibernate, the bound query parameter will be `author.id`, so `author.id.hashCode()` will be used when when computing the hash key, rather than `author.hashCode()`. Am I understanding you correctly? – Dónal Feb 24 '12 at 12:38
  • You are understanding me correctly. You can make your test in a unique session: Hibernate will execute the query twice if you tell it to execute it twice. The session doesn't cache query results. It only caches entities. – JB Nizet Feb 24 '12 at 12:43
  • @JBNizet So what you're saying is that there's no need to implement equals and hashCode for the purpose of ensuring that query caching workds correctly? If you can make an answer out of your comments, I'll accept it – Dónal Feb 24 '12 at 12:56
  • I'm not 100% sure about the internal behavior, but that's what I understood from the documentation. Please test it to confirm that I'm right. – JB Nizet Feb 24 '12 at 12:58
  • related: http://stackoverflow.com/questions/1998326/hibernate-query-cache-for-objects-not-in-the-2nd-level-cache-risky-usefull – Oleg Mikheev Feb 24 '12 at 13:21
  • @JBNizet _It uses the query, and its actually bound parameters_ - but isn't it important whether query parameters are equal with `equals()` ? – Oleg Mikheev Feb 24 '12 at 13:30
  • As I said, AFAIK, what is remembered in the cache is not the parameter that you pass (the instance of the entity), but the parameter that is bound by Hibernate (the ID of the entity). And the ID has equals and hashCode. – JB Nizet Feb 24 '12 at 13:32

0 Answers0