Alexandre Hubert
Alexandre Hubert

Reputation: 27

How to call GORM methods on domain classes in a generic way?

I have written a list() method for retrieving a list of domain class instances matching a set of filters, and this method is used for different domain classes ; the code is exactly the same except the class on which the GORM methods are called :

Store => Store.createCriteria()
Client => Client.createCriteria()
and so on.

To avoid code duplication, I have tried to make a generic version of the list method, by creating a generic class :

class QueryUtils<T> {

    def list(params) {
        T.createCriteria()
        [...]
    }

}

This way, each of my services (StoreService, ClientService, etc) can extend QueryUtils :

class StoreService extends QueryUtils<Store>
class ClientService extends QueryUtils<ClientService>

and so on, and inherit the list() method corresponding to its domain class type.

The problem is that during the execution, it doesn't work since the effective type of T is java.lang.Object, instead of the domain class type I have specified :

groovy.lang.MissingMethodException: No signature of method: static java.lang.Object.createCriteria() is applicable for argument types: () values: []

Do you know how to solve this problem?

Upvotes: 1

Views: 2374

Answers (1)

Burt Beckwith
Burt Beckwith

Reputation: 75671

I did something like this a while back for Hibernate (outside of Grails) - https://burtbeckwith.com/blog/?p=21

But it doesn't work with Groovy since the compiler ignores generics. But you could change it to take the class in the constructor instead of as a generic type:

class QueryUtils {

   private final Class clazz

   QueryUtils(Class clazz) {
      this.clazz = clazz
   }

   def list(params) {
      clazz.createCriteria()
      [...]
   }
}

Upvotes: 6

Related Questions