【问题标题】:Persist collection of interface using Hibernate使用 Hibernate 持久化接口集合
【发布时间】:2010-05-26 12:39:07
【问题描述】:

我想用 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]

我知道@OneToManytargetEntity 属性,但这意味着只有狗或猫可以住在我的动物园里。

有什么方法可以用 Hibernate 持久化具有多个实现的接口集合?

【问题讨论】:

    标签: java hibernate interface


    【解决方案1】:

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

    请注意,JPA 规范 不支持任何映射注解 在界面上!这将得到解决 在未来的版本中 规格;当你读到这个 书,应该是可以的 带有休眠注释。

    一种可能的解决方案是使用具有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 并没有太多优势(实际上,我认为持久类应该是具体的)。

    参考文献

    【讨论】:

    • 真相是,我真正的问题比上面的问题要复杂一些,所以你的答案在我的情况下不起作用。但这看起来像是对我的问题的正确答案,所以我会接受。谢谢!
    • 知道为什么抽象类AbstractAnimal没有实现接口Animal吗?
    【解决方案2】:

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

    【讨论】:

    • 我会尝试,如果它不起作用,我会去抽象类。
    • 是的,抽象类是更好的解决方案。正如 Péter Török 已经说过的,您可以将 id 和其他常见属性放到 Animal 类中。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-24
      • 1970-01-01
      • 1970-01-01
      • 2020-03-30
      • 2018-12-10
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      相关资源
      最近更新 更多