By default GORM injects whole set of dynamic finders into domain entities. However what should one do if he needs to implement more complex queries that require use of Criteria Builder or HQL?
Simplest option is just to do this in the layer on top of domain model. So our controllers or services would call something like Customer.executeQuery or Customer.createCriteria. Although this is the simplest option it is also the worst. First, this will expose queries to client code and second we cannot reuse these queries anywhere else.
Second option is to implement these queries as methods in entities. The problem here is that now we are actually not just mixing business and persistence APIs (look my previous post about this) but also the implementation.
Third option is to use the same injection employed by Grails framework also in case of custom queries. For example if we need to implement complex query to find all customers who should to be notified about completed orders we can implement following finder:
class CustomerRepositoryPlugin {
def findAllCustomersWhoNeedToBeNotifiedAboutCompletedOrder() {
...
def result = Customer.executeQuery(...)
...
}
def install() {
Customer.metaClass.static.findAllCustomersWhoNeedToBeNotifiedAboutCompletedOrder = {
findAllCustomersWhoNeedToBeNotifiedAboutCompletedOrder()
}
}
}
Of course this could be made more generic and compact so that all suitable repository plugins are found and injected automatically.