如何使用JPA 2.0保留子类型列表?

时间:2012-02-16 05:07:21

标签: java hibernate persistence jpa-2.0

我有一个经理类,其中包含一些可访问元素列表,我希望使用JPA / Hibernate将其保存在数据库中:

@Entity
class Elements {
  void accept(Visitor v) {...}
  @? List<Visitable> elements;  // or List<AbstractElement>
}

@? class AbstractElement implements Visitable {}

@Entity class Element1 extends AbstractElement {}
@Entity class Element2 extends AbstractElement {}

class ElementDAO {
  void saveElements(Elements e, EntityManager em) {
    em.persist(e);
  }
}

我尝试了多种方法。我试图将AbstractElement标记为@MappedSuperclass,但是Hibernate无法找出正确的Visitable类型,并且不允许我用@OneToMany(targetEntity = AbstractElement.class)标记它。我已经尝试更改List以包含AbstractElement,但Hibernate抱怨它无法实例化抽象类。我也尝试在AbstractElement类上使用TABLE_PER_CLASS继承策略,并获得相同的“无法实例化”错误。

我有什么办法可以解决这个问题吗?这可行吗?

我在这个网站上搜索了很多类似的问题,处理jpa和继承,但没有一个建议有效。

更新: 所以看起来问题不在于继承方法或抽象类本身,而是因为我试图使用EntityManager :: merge()而不是EntityManager :: persist()。我认为这与merge合并制作实体的副本有关。

因此,鉴于这些新知识,我是否必须承认合并不能与抽象类的集合一起使用?或者有没有办法添加一个hibernate可以调用的拷贝构造函数?

1 个答案:

答案 0 :(得分:3)

你需要告诉JPA / Hibernate List的内容类型是Entity(因此它不能是一个接口但需要是一个抽象类),List表示Elements和AbstractElement之间的关系(使用@OneToMany)并且您的超级元素需要被标记为类层次结构的顶级元素(@Inheritance)。继承策略独立于此,因此是任意的(默认为SINGLE_TABLE):

@Entity
class Elements {
  @OneToMany 
  List<AbstractElement>
}

@Entity
@Inheritance
class abstract AbstractElement implements Visitable {}