一尘不染

使用Hibernate持久保存接口集合

hibernate

我想和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来持久化具有多个实现的接口集合?


阅读 250

收藏
2020-06-20

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

参考文献

2020-06-20