【问题标题】:How do I persist a list of subtypes with JPA 2.0?如何使用 JPA 2.0 保留子类型列表?
【发布时间】:2012-03-07 12:44:54
【问题描述】:

我有一个包含可访问元素列表的管理器类,我想使用 JPA/Hibernate 将其保存在数据库中:

@Entity
class Elements {
  void accept(Visitor v) {...}
  @? List<Visitable> elements;  // or List<AbstractElement>
}

@? class AbstractElement implements Visitable {}

@Entity class Element1 extends AbstractElement {}
@Entity class Element2 extends AbstractElement {}

class ElementDAO {
  void saveElements(Elements e, EntityManager em) {
    em.persist(e);
  }
}

我尝试了多种方法。我试图将 AbstractElement 标记为 @MappedSuperclass,但是 Hibernate 无法找出正确的 Visitable 类型,并且不会让我用 @OneToMany(targetEntity=AbstractElement.class) 标记它。我尝试将 List 更改为包含 AbstractElement 但 Hibernate 抱怨它无法实例化抽象类。我还尝试在 AbstractElement 类上使用 TABLE_PER_CLASS 继承策略并得到相同的“无法实例化”错误。

有什么办法可以解决这个问题吗?这完全可行吗?

我在这个网站上搜索了许多关于 jpa 和继承的类似问题,但没有一个建议奏效。

更新: 所以看起来问题不在于继承方法或抽象类本身,而在于我试图使用 EntityManager::merge() 而不是 EntityManager::persist()。我认为这与合并复制实体的事实有关。

因此,鉴于这些新知识,我是否只需要承认合并不能与抽象类的集合一起使用?或者有没有办法添加一个hibernate可以调用的复制构造函数?

【问题讨论】:

    标签: java hibernate persistence jpa-2.0


    【解决方案1】:

    您需要告诉 JPA/Hibernate List 的内容类型是 Entity(因此它不能是接口但必须是抽象类),List 表示 Elements 和 AbstractElement 之间的关系(使用@OneToMany) 并且您的超级元素需要标记为类层次结构的顶部元素 (@Inheritance)。继承策略与此无关,因此是任意的(默认为 SINGLE_TABLE):

    @Entity
    class Elements {
      @OneToMany 
      List<AbstractElement>
    }
    
    @Entity
    @Inheritance
    class abstract AbstractElement implements Visitable {}
    

    【讨论】:

    • 所以我之前试过这个(如上所述),但我想我应该再试一次。当我这样做时,我得到一个 InstantiationException:线程“main”中的异常 javax.persistence.PersistenceException:org.hibernate.InstantiationException:无法实例化抽象类或接口:org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:第1215章)
    • 请参阅原始问题中的新更新说明,因为是的,如果使用persist(),您的答案是正确的,但merge() 存在问题。
    • 显然这是依赖于休眠的,但考虑到我现在正在使用它,我通过代码找出了它无法创建抽象类的确切原因。我发现这个特殊的异常来自 org.hibernate.tuple.PojoInstantiator::instantiate()。如果它试图创建的实体是一个抽象类除非映射的类是具有非空 id 的 Serializable,它总是会抛出这个异常。因此,我在具体的 Element 类中添加了 Serializable 和一个 id,瞧,merge 现在可以工作了。
    猜你喜欢
    • 1970-01-01
    • 2014-11-09
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多