【问题标题】:Hibernate - How to cascade deletes using annotations where only unidirectional child relationship is specifiedHibernate - 如何使用仅指定单向子关系的注释级联删除
【发布时间】:2010-01-24 06:19:21
【问题描述】:

假设我有两个实体,一个父对象和一个子对象。我希望孩子具有与父实体和引用指定的关系,但我不希望父母必须知道它。这样做的原因是存在许多这样的关系,并且明确指定所有这些子对象的关系将意味着不断更新和污染父对象。但是我仍然希望删除父对象以级联到子对象。作为附加约束,子对象只能通过设置引用父 ID 的属性来设置对父实体的引用。假设我有类似的东西:

@Entity
class Child {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Column(nullable=false)
    private Long parentId;

    @ManyToOne(fetch=FetchType.LAZY, optional=false)
    @JoinColumn(name="parentId", insertable=false, updatable=false, nullable=false, unique=false)
    private Parent parentEntity;

    // etc...

}

@Entity
class Parent {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    // etc...   
}

那么有没有什么方法可以在不给父实体增加额外关系的情况下将父对象的删除级联到子对象?

最好使用仅使用 JPA 注释的解决方案,但我们将不胜感激。

【问题讨论】:

    标签: java hibernate jpa annotations


    【解决方案1】:

    不,这是不可能的。

    级联(任何类型的)遍历关系。如果你不告诉 JPA 从 A 到 B 的关系(即使有一个从 B 到 A),那么它就不能自动遍历它。

    附带说明:仅指定父 ID 而不是父实体会使其变得更加困难。 Hibernate/JPA 不是您正在做的事情的正确工具,或者您需要接受它的工作方式,这意味着指定和维护对象关系。

    【讨论】:

      【解决方案2】:

      直接添加 parentId 而不是 parent 会让您的生活更加艰难。 Hibernate 只是在数据库中保存一个 id。那么你自己做这件事有什么意义呢? 回到你的问题。您必须使关系双向并将 cascade=CascadeType.ALL 添加到您的 children 属性中,该属性本身是 mappedBy="parent"。它体积小、操作简单、速度快。

      【讨论】:

      • 在创建这个对象时,我只有父 ID(它是通过 RPC 调用来的),所以添加它而不是进行另一个查找很方便。
      • 您可以使用 session.load(Parent.class, parentId) 创建一个占位符,您可以在语句中使用而无需实际查询数据库。
      猜你喜欢
      • 2012-11-02
      • 1970-01-01
      • 2022-10-07
      • 1970-01-01
      • 2015-04-27
      • 2012-05-23
      • 2016-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多