Как вызывать методы GORM в классах домена в общем виде? - PullRequest
1 голос
/ 02 декабря 2011

Я написал метод list () для получения списка экземпляров классов домена, соответствующих набору фильтров, и этот метод используется для разных классов домена; код точно такой же, за исключением класса, в котором вызываются методы GORM:

Store => Store.createCriteria ()
Client => Client.createCriteria ()
и т. д.

Чтобы избежать дублирования кода, я попытался создать универсальную версию метода list, создав универсальный класс:

class QueryUtils<T> {

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

}

Таким образом, каждый из моих сервисов (StoreService, ClientService и т. Д.) Может расширять QueryUtils:

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

и т. Д. И наследование метода list (), соответствующего его типу класса домена.

Проблема заключается в том, что во время выполнения он не работает, поскольку эффективным типом T является java.lang.Object, а не тип класса домена, который я указал:

groovy.lang.MissingMethodException: Нет сигнатуры метода: статический java.lang.Object.createCriteria () применим для типов аргументов: () значения: []

Знаете ли вы, как решить эту проблему?

1 Ответ

6 голосов
/ 02 декабря 2011

Некоторое время назад я делал что-то подобное для Hibernate (за пределами Grails) - https://burtbeckwith.com/blog/?p=21

Но это не работает с Groovy, так как компилятор игнорирует обобщенные типы. Но вы можете изменить его так, чтобы он принимал класс в конструкторе, а не как универсальный тип:

class QueryUtils {

   private final Class clazz

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

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