Showing posts with label searchable. Show all posts
Showing posts with label searchable. Show all posts

Tuesday, April 7, 2009

Eager fetching and searchable plugin in Grails

What came as surprise to me is that eager fetching even when specified on the level of the domain class does not work with the searchable plugin. I hit this problem while working on the software books reviews and statement and description why I found on one blog post. Unfortunately I cannot find the mentioned post again so I am not able to give a credit to the original author by linking to his/her post.

So for example lets have Book domain class that among other properties has publisher property specified like this:

class Book {
static searchable = true
Publisher publisher

static fetchMode = [publisher:"eager"]
}

Using searchable plugin you can search for the books like this:

 Map<String,String> options = new HashMap<String, String>()
if (params.offset) {
options.put('offset',new Long(params.offset))
}
options.put('escape', true)
options.put('max',10)
def searchResult = Book.search(params.searchTerm, options)

After executing given query searchResult.result will be populated with the list of found Book instances. And in this moment you hope that everything is fine. You send the found list of books to the view but to your surprise you see that publisher is not displayed for each of the book. You check if the book has publisher and it is in the database. The reason for the missing publisher is that the domain classes are created differently when loaded from the lucene index file.

To resolve this problem I have actually reloaded all the found books from the database. This way all the books are of course loaded as specified in the domain object. So code for searching looks like this:

Map<String,String> options = new HashMap<String, String>()
if (params.offset) {
options.put('offset',new Long(params.offset))
}
options.put('escape', true)
options.put('max',10)
def searchResult = Book.search(params.searchTerm, options)

// create new results because those current one are actually not loaded eagery
def newResults = new ArrayList()
searchResult.results.each {book ->
def bookToAdd = Book.get(book.id)
newResults.add(bookToAdd)
}

searchResult.results = newResults

So if you have integrated searching into your grails application and expects that some parts of the domain object are loaded eagerly you should probably use approach similar to this one.

P.S. Don't forget to write some review or post summary on the software books reviews.