使用休眠持久化接口集合

2022-09-01 13:18:06

我想用Hibernate来维持我的litte zoo:

@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来持久化一个接口的集合,它有一个有几个实现?


答案 1

接口上不支持 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 并没有太大的优势(实际上,我认为持久类应该是具体的)。

引用


答案 2

我可以猜到你想要的是继承树的映射。@Inheritance注释是要走的路。我不知道它是否适用于接口,但它肯定会与抽象类一起使用。