Difference between findAll, getAll and list in Grails

GrailsGrails Orm

Grails Problem Overview


With Grails there are several ways to do the same thing.

Finds all of domain class instances:

Book.findAll()
Book.getAll()
Book.list()

Retrieves an instance of the domain class for the specified id:

Book.findById(1)
Book.get(1)

When do you use each one? Are there significant differences in performance?

Grails Solutions


Solution 1 - Grails

getAll is an enhanced version of get that takes multiple ids and returns a List of instances. The list size will be the same as the number of provided ids; any misses will result in a null at that slot. See http://grails.org/doc/latest/ref/Domain%20Classes/getAll.html

findAll lets you use HQL queries and supports pagination, but they're not limited to instances of the calling class so I use executeQuery instead. See http://grails.org/doc/latest/ref/Domain%20Classes/findAll.html

list finds all instances and supports pagination. See http://grails.org/doc/latest/ref/Domain%20Classes/list.html

get retrieves a single instance by id. It uses the instance cache, so multiple calls within the same Hibernate session will result in at most one database call (e.g. if the instance is in the 2nd-level cache and you've enabled it).

findById is a dynamic finder, like findByName, findByFoo, etc. As such it does not use the instance cache, but can be cached if you have query caching enabled (typically not a good idea). get should be preferred since its caching is a lot smarter; cached query results (even for a single instance like this) are pessimistically cleared more often than you would expect, but the instance cache doesn't need to be so pessimistic.

The one use case I would have for findById is as a security-related check, combined with another property. For example instead of retrieving a CreditCard instance using CreditCard.get(cardId), I'd find the currently logged-in user and use CreditCard.findByIdAndUser(cardId, user). This assumes that CreditCard has a User user property. That way both properties have to match, and this would block a hacker from accessing the card instance since the card id might match, but the user wouldn't.

Solution 2 - Grails

Another difference between Domain.findByID(id) and Domain.get(id) is that if you're using a hibernate filter, you need to use Domain.findById(id). Domain.get(id) bypasses the filter.

Solution 3 - Grails

AFAIK, these are all identical

Book.findAll()
Book.getAll()
Book.list()

These will return the same results

Book.findById(1)
Book.get(1)

but get(id) will use the cache (if enabled), so should be preferred to findById(1)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArturo HerreroView Question on Stackoverflow
Solution 1 - GrailsBurt BeckwithView Answer on Stackoverflow
Solution 2 - GrailsBrad RhoadsView Answer on Stackoverflow
Solution 3 - GrailsDónalView Answer on Stackoverflow