使用Hibernate持久收集界面

我想用Hibernate坚持我的小动物园:

@Entity @Table(name = "zoo") public class Zoo { @OneToMany private Set animals = new HashSet(); } // Just a marker interface public interface Animal { } @Entity @Table(name = "dog") public class Dog implements Animal { // ID and other properties } @Entity @Table(name = "cat") public class Cat implements Animal { // ID and other properties } 

当我试图坚持动物园时,Hibernate抱怨道:

 Use of @OneToMany or @ManyToMany targeting an unmapped class: blubb.Zoo.animals[blubb.Animal] 

我知道@OneToManytargetEntity -property,但这意味着,只有Dogs或Cats可以住在我的动物园里。

有没有办法用Hibernate来持久化一个具有多个实现的接口集合?

接口不支持JPA注释。 从Java Persistence with Hibernate (p.210):

请注意,JPA规范不支持接口上的任何映射注释! 这将在规范的未来版本中得到解决; 当您阅读本书时,可能会使用Hibernate Annotations。

一种可能的解决方案是使用带有TABLE_PER_CLASSinheritance策略的抽象实体(因为您不能在关联中使用映射的超类 – 它不是实体)。 像这样的东西:

 @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public abstract class AbstractAnimal { @Id @GeneratedValue(strategy = GenerationType.TABLE) private Long id; ... } @Entity public class Lion extends AbstractAnimal implements Animal { ... } @Entity public class Tiger extends AbstractAnimal implements Animal { ... } @Entity public class Zoo { @Id @GeneratedValue private Long id; @OneToMany(targetEntity = AbstractAnimal.class) private Set animals = new HashSet(); ... } 

但是保持接口IMO没有太大的优势(实际上,我认为持久化类应该是具体的)。

参考

  • 注释,inheritance和接口
  • 使用MappedSuperclass关系一对多
  • 与MappedSuperclass的多态关联会引发exception

我猜你想要的是inheritance树的映射。 @Inheritance注释是要走的路。 我不知道它是否适用于接口,但它肯定适用于抽象类。

我认为你必须使用@Entity来注释接口,我们必须在所有getter和setter接口上注释@Transient