时间:2011-08-04 09:53:35

标签: java generics jpa playframework

我在其当前版本中使用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:请使用@ javax.persistence.Entity批注注释您的JPA模型。

我调试了方法,在运行时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 个答案:

答案 0 :(得分:6)

在Play中,应该扩展play.db.jpa.Model并使用@Entity注释(类级别)。

对于你所说的我理解你正在扩展play.db.jpa.JPABase。

这可能是问题的原因,因为Play(正如您所指出的)动态地增强了类,并且它可能与您的继承冲突。

编辑:我测试了这个问题

问题是Play没有增强对象T.这意味着find方法调用了一个GenericModel(Model的父类),它的实现是用消息抛出异常。

增强器似乎只检测带有@Entity的类。

即使mericano1的解决方案不起作用,增强器也不会选择它。所以我觉得你将无法在Play中使用该方法。

答案 1 :(得分:2)

最好的方法是使用扩展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 {
....
}