如果Cascade.persist和Cascade.remove在Hibernet中的父实体中一起使用,则级联删除不起作用

时间:2014-06-16 13:12:21

标签: hibernate jpa persist

我有一个表关系定义如下所示,我试图级联持久性并从Entity2中删除(表2)意味着从table2删除记录应删除table3中的条目并保存table2中的数据以及表3中的相关数据

                     oneToMany                       oneToMany 

表1(实体1)(父)-------->表2(实体2)(Child to Table1)--------->表3(Child to Table2)(Entity3)

             oneToMany                          oneToMany

表1(父母)-------->表4(实体4)(Child to Table1)--------->表5(Child to Table4)(Entity5)

Table1是table2和table4的共同父级

问题陈述:

1)如果我在Entity1中使用CascadeType.REMOVE并在其子节点(Entity2和Entity4)中使用{CascadeType.PERSIST,CascadeType.REMOVE},那么在table2中保存记录并从table2中删除记录将被级联到其子Entity3 (table3),但保存记录到table1没有从它的子级(Table2和table4)级联,因为我没有使用Entity1中的cascade.persist

2)如果我在Entity1中使用{CascadeType.PERSIST,CascadeType.REMOVE}并在其子节点(Entity2和Entity4)中使用{CascadeType.PERSIST,CascadeType.REMOVE},则保存table2中的记录将被级联到其子Entity3 (table3)但是试图从table2中删除记录时没有被删除,而且它没有被级联到它的子Entity3(table3)并且也没有异常......(从日志中没有删除查询正在执行,但在第一种情况下,我可以看到正在执行的删除查询)

你能帮我找出我错的地方....为什么将CascadeType.PERSIST添加到Entity1(Table1)会对从table2删除记录产生影响吗?

以下示例代码:

表1 {

....

@OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE,mappedBy=....})
public Set<Table2> getTable2() {
return table2;
}

}

表2 {

....

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(....)
public Table1 getTable1() {
return table1 
}


@OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE,mappedBy=....})
public Set<Table3> getTable3() {
    return table3;
}

}

表3 {

....

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(....)
public Table2 getTable2() {
    return table2;

}

}

2 个答案:

答案 0 :(得分:2)

This article似乎完全描述了你的问题。如果作者所说的仍然是真的(2010年的文章),问题是JPA和Hibernate在持久化时所期望的行为之间存在不匹配。如果您使用较旧的Hibernate实施,我首先尝试升级到较新版本,因为我在最近的版本中从未见过这个问题。如果您无法升级(例如,您受限于使用应用服务器提供的Hibernate版本),或者升级不起作用,请将HCAnate级联注释替换为JPA级联注释可以解决你的问题。使用Hibernate注释并不是一个很好的解决方案,因为现在你的代码不是与实现无关的,但如果它有效,它就可以工作。

您使用的是什么版本的Hibernate / JPA / app服务器?

答案 1 :(得分:1)

您可能在不清除引用的情况下手动尝试删除Table2的实例,因此Table1的实例将引用已删除的table2实例。映射上的级联持久选项将导致重新插入 - 取消删除功能。

您需要清理对要删除的对象的引用,因为JPA不会为您执行此操作,如果不这样做,缓存将与数据库不同步。当您尝试删除Table2的实例时,您还需要将其从Table1的列表中删除。