views:

564

answers:

2

Each book can have many authors. And each author can author many books.

class Book {
   static belongsTo = Author
   static hasMany = [authors:Author]
}

class Author {
   static hasMany = [books:Book]
}

Now when can I do:

def book = Book.get(id)
def authors = book.authors

Now I am thinking I should be able to take each author and get the books he is associated with:

authors.each {
   it.books
}

You see now it would get recursive (leading to stackoverflow). Does anyone know how it exactly works, when it is doing eager fetch?

+1  A: 

Whether it's eagerly or lazily loaded, once a Hibernate-managed instance is loaded it's kept in the Hibernate Session, which is its 1st-level cache (if you've also configured a 2nd-level cache then instances will also be there and may have come from there if they were previously loaded).

So having loaded the book, and then having loaded its author collection (a Set by default), each author's book is already in the Session, so there's no need to go to the database.

Eagerly loading a mapped collection uses the initial ResultSet to grab the top-level instance plus the child instances in one database query. Lazily loading the collection just requires a 2nd database query to populate the collection but it has the benefit of only loading the collection if needed.

Burt Beckwith
So when I load Book1 eagerly, all the authors of Book1 eg Author1, Author2 etc. and hence all the books written by each of those authors too will be loaded into session. Is that right?
Langali
I'm not sure how Grails configures the "max fetch depth" that Hibernate supports, but certainly for two classes it should work ok. If you specify eager fetching for both the Book's Authors and the Author's books then it will load everything for you. This is potentially expensive - it wouldn't take much to load every element of both tables if you load a book written by an author who writes many books. Eager loading should be used rarely because you don't often need every instance of a child collection every time you load an instance, so lazy loading performs better overall.
Burt Beckwith
+1  A: 

For more clarity you can refer to the blog written by Burt Beckwith at http://burtbeckwith.com/blog/?p=169 and you can also go through the presentation link given in the blog.

Amit Jain