JPA和泛型

我想知道一个带泛型的抽象类如何处理JPA? 我的意思是我需要什么类型的注释?

考虑这些:

@MappedSuperclass
public abstract class AbstractMyClass<T> {
  // What about Strings and Integers? Do I need some kind of @LOB?
  private T field;

  public T getField() {
    return field;
  }

  public void setField(T field) {
    this.field = field;
  }
}

然后这些

@Entity
@Table(name = "String")
public class MyStringClass extends AbstractMyClass<String> {
}

@Entity
@Table(name = "Integer")
public class MyIntegerClass extends AbstractMyClass<Integer> {
}

JPA完全能够处理你提出的问题,因为泛型出现在抽象类层次上,对于具体类别,它每个类别只有一个值。 实际上,根据您选择的@InheritanceStrategy,JPA会将您的子类存储在一个或多个表中,并为此使用不同的机制。

你可以弄清楚为什么你的情况不是问题,推理一下ORM如何在DB上保存这两个类:

  • 您可以将MyStringClass和MyIntegerClass存储在同一个表中,添加Discriminator列,以便ORM在从DB加载时知道应调用哪个构造函数。
  • 您可以将每个子类存储在更多表中。
  • 另一方面,不可能的是定义一个通用的

    @Entity
    @Table(name = "MyGenericClass")
    public class MyGenericClass<T> {
        private T t;
        public MyGenericClass(T t) {
           this.t=t;
        }
    }
    

    其原因在于,在编译时,T由于类型擦除而被“擦除”。 它在编译时用于验证签名和类型的正确性,但是随后它会在JVM中变成java.lang.Object。 如果你直到现在,你应该能够理解以下内容:

  • 在你的情况下,AbstractMyClass的每个具体子类都有一个类型T,它是为类的所有实例定义的。 虽然T信息未保留到AbstractMyClass中,但它在子类中保留且唯一。
  • 在我发布的第二种情况下,MyGenericClass的每个可能的具体实例都可能具有T的不同值,并且由于类型擦除,此信息不会被保留。
  • *注意:第二种情况不能由JPA处理的事实是绝对合理的,如果您属于这种情况,您应该问自己关于您的设计的问题。 泛型是设计灵活类的好工具,它可以类型安全的方式处理其他类,但类型安全是一种编程语言概念,与持久性无关。


    额外:你可以使用javap来查看真正的擦除。 从MyGenericClass中取出注释并编译它。

    G:>javac MyGenericClass.java
    
    G:>javap -p MyGenericClass
    Compiled from "MyGenericClass.java"
    public class MyGenericClass extends java.lang.Object{
        private java.lang.Object t;
        public MyGenericClass(java.lang.Object);
    }
    

    我们可以。 如果T实现Serializable

    @Entity
    public class IgsSubject extends BasicObject implements Serializable{
    
        private static final long serialVersionUID = -5387429446192609471L;
    
    @MappedSuperclass
    public class IgsBasicLog<T> extends BasicObject {
    
        @ManyToOne
        @JoinColumn(name = "ITEM_ID")
        private T item;
    
    @Entity
    public class IgsLogA extends IgsBasicLog<IgsSubject> implements Serializable {
        private static final long serialVersionUID = -8207430344929724212L;
    }
    
    链接地址: http://www.djcxy.com/p/10927.html

    上一篇: JPA and generics

    下一篇: ScrollView doesn't scrolls if soft keyboard is visible