1

我有一个只提供标识的基类:

    public abstract class Identifable<T> {
    @Id
    private T id = null;

    public T getId() {
        return id;
    }

    public void setId(T id) {
        this.id = id;
    }

    public boolean hasId() {
        return id != null;
    }
}

以及几个扩展它的子类,例如:

@Entity
@Cache
public class MyEntity extends Identifable<String> {
    /* some specific attributes and methods */
}

我得到一个java.lang.IllegalStateException: @Id field 'id' in com.mypkg.MyEntity must be of type Long, long, or String.

为什么?Objectify 看不到继承的@Id字段吗?谢谢

4

3 回答 3

3

原因:

Objectify 仅在运行时使用反射检查类型。由于类型擦除,所有无界类型参数都在编译期间转换为Object类型,这是 objectify 看到和抱怨的。

解决方案:

使用具体类型作为id字段。可能按照@Anthony 的建议将其移至子类。

于 2013-10-18T19:25:16.860 回答
2

让我们推理一下……您正在尝试构建一个 ID 类型不同的超类型。你确定这是你想要构建的对象(根实体具有未知 ID 类型的对象层次结构)吗?虽然我在几个 ORM 框架中看到过这种代码,但这就是我构建你想要的东西的方式。

接口(不是对象层次结构的一部分):

public interface Identifable<T> {
    public T getId();
    public void setId(T id);
    public boolean hasId(); 
}

您的层次结构的根使用 id 的具体类型实现 Identifable:

@Entity
public class MyBaseClass implements Identifable<String> {
    @Id
    private String id = null;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public boolean hasId() {
        return id != null;
    }
}

子类自然而然地从中产生:

@EntitySubclass(index=true)
public class MyEntity extends MyBaseClass {
   // fields, accessors and mutators
}
于 2013-10-18T15:12:01.420 回答
2

在 JPA 中,您必须使用标记@Id为以下类型之一的字段:任何 Java 原始类型;任何原始包装类型;java.lang.String; java.util.日期;java.sql.日期;java.math.BigDecimal; java.math.BigInteger

只需从基类中删除泛型并为您的 id 字段使用上述类型之一。

于 2013-10-18T14:48:56.327 回答