我有一个经理类,其中包含一些可访问元素列表,我希望使用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可以调用的拷贝构造函数?
答案 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 {}