Generics и Play Framework - PullRequest
       5

Generics и Play Framework

4 голосов
/ 04 августа 2011

Я использую Play Framework в его текущей версии, и мои классы моделей расширяют play.db.jpa.JPABase.

Сегодня я попытался сделать часто используемый тип запроса универсальным и определить статический вспомогательный метод для его создания.

Я написал следующее:

import play.db.jpa.Model;
import play.libs.F;

public class GenericQueries {

  public static <T extends Model> F.Option<T> firstOption(
          Class<T> clazz,
          String query,
          Object... parameters){

    final T queryResult = T.find(query,parameters).first();

    return (queryResult == null) ?
            F.Option.<T>None() :
            F.Option.Some(queryResult);
  }
}

Однако я получаю следующую ошибку:

Исключение при исполнении

Произошло UnsupportedOperationException: пожалуйста, аннотируйте вашу модель JPA аннотацией @ javax.persistence.Entity.

Я отлаживал в методе, во время выполнения T, кажется, правильно настроен на соответствующий класс Model. Я даже вижу аннотацию.

Я подозреваю, что ответственные за это ребята из игры улучшают класс вуду, но я не совсем уверен.

Есть идеи?

Обновление: добавлен класс модели по запросу

Вот сокращенная версия одного из классов Model, которые я использую.

package models;

import org.apache.commons.lang.builder.ToStringBuilder;
import play.data.validation.Required;
import play.db.jpa.Model;
import play.modules.search.Field;
import play.modules.search.Indexed;

import javax.persistence.Column;
import javax.persistence.Entity;
import java.util.Date;

@Entity @Indexed
public class FooUser extends Model {

  @Required
  public Date firstLogin;

  @Field
  @Required(message = "needs a username")
  @Column(unique = false,updatable = true)
  public String name;

  @Field
  public String description;

  @Required
  public boolean isAdmin;

  @Override
  public String toString(){
    return new ToStringBuilder(this)
            .append("name", name)
            .append("admin", isAdmin)
            .toString();
  }
}

Ответы [ 2 ]

6 голосов
/ 04 августа 2011

В играх участники должны расширять play.db.jpa.Model и использовать аннотацию @Entity (уровень класса).

Из того, что вы говорите, я понимаю, что вы расширяете play.db.jpa.JPABase.

Это может быть причиной проблемы, поскольку Play (как вы указали) динамически улучшает классы и может конфликтовать с вашим наследством.

EDIT: я проверял проблему

Проблема в том, что Play не расширяет объект T. Это означает, что метод find вызвал id как метод GenericModel (родительский объект для Model), реализация которого заключается в создании исключения с сообщением.

Похоже, что энхансер обнаруживает только классы с @ Entity.

Даже решение mericano1 не работает, энхансер его не выбирает.Поэтому я чувствую, что вы не сможете использовать этот метод в Play.

2 голосов
/ 04 августа 2011

Лучший способ сделать это - использовать базовый класс, расширяющий play.db.jpa.Model только статическими методами, которые будут использоваться подклассами.

Добавьте аннотацию @Entity кБазовый класс и без полей класса.

import play.db.jpa.Model;
import play.libs.F;

public class BaseModel extends Model {

  public static <T extends Model> F.Option<T> firstOption(
          Class<T> clazz,
          String query,
          Object... parameters){

    final T queryResult = T.find(query,parameters).first();

    return (queryResult == null) ?
            F.Option.<T>None() :
            F.Option.Some(queryResult);
  }
}

А затем

@Entity 
public class FooUser extends BaseModel {
....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...