我想用Hibernate坚持我的小动物园:
@Entity
@Table(name = "zoo")
public class Zoo {
@OneToMany
private Set<Animal> animals = new HashSet<Animal>();
}
// 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]
我知道targetEntity
- @OneToMany
的属性,但这意味着只有狗或猫可以住在我的动物园。
有没有办法用Hibernate来持久化一个具有多个实现的接口集合?
答案 0 :(得分:27)
接口不支持JPA注释。来自 Java Persistence with Hibernate (p.210):
请注意JPA规范 不支持任何映射注释 在界面上!这将得到解决 在未来的版本中 规格;当你读到这个 书,它可能是可能的 使用Hibernate Annotations。
一种可能的解决方案是使用具有TABLE_PER_CLASS
继承策略的抽象实体(因为您不能在关联中使用映射的超类 - 它不是实体)。像这样:
@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<Animal> animals = new HashSet<Animal>();
...
}
但是保持IMO接口没有太大的优势(实际上,我认为持久化类应该是具体的)。
答案 1 :(得分:1)
我猜你想要的是继承树的映射。 @Inheritance注释是要走的路。 我不知道它是否适用于接口,但它肯定适用于抽象类。
答案 2 :(得分:0)
我认为你必须使用@Entity
注释界面,我们必须在所有getter和setter of interface上注释@Transient
。