我们有一个问题,听起来像Hibernate中处理oneToMany列表(带索引)的orphanRemovation=true的bug。
以下是简化的映射:
public class ParentClass {
[...]
@OneToMany(cascade = ALL, mappedBy = "parent", orphanRemoval = true)
@OnDelete(action = OnDeleteAction.CASCADE)
@Fetch(FetchMode.JOIN)
@OrderColumn(name = "pos", nullable = false)
public List<ChildClass> getChildren() {
return children;
}
}
儿童班:
public class ChildClass {
[...]
@ManyToOne
@JoinColumn(nullable = false, name = "parent_id")
public ParentClass getParent() {
return parent;
}
}
鉴于此映射,以下场景将失败:
这是密码
@Transactional
public void test() {
// 1)
ParentClass parent = entityManager.find(ParentClass.class, "some-id");
// 2)
ChildClass child = new ChildClass(parent);
parent.getChildren().add(child);
// 3)
entityManager.find(SomethingElse.class, "2");
// 4)
parent.getChildren().remove(child);
}
在这种情况下,子分配被插入到DB中,并且在事务结束时不被删除。
但是,如果不执行步骤3),则子分配不会正确地持久化到数据库中
那是虫子吗?错误的映射?有解决办法吗?
有一个JPA注释@PreRemove
可能对您的特定情况有所帮助。尝试将其添加到子实体,以便它可以从父实体中删除自己:
@PreRemove
protected void beforeRemove(){
parent.getChildren().remove(this);
}
删除子项时,需要设置关联的双方:
child.setParent(null);
parent.getChildren().remove(child);
在你的情况下,孤儿转移是不够的。如果一对多是单向关联,那么您可以简单地从列表中删除孩子,删除将传播到孩子实体。
当你有双向关联时,你需要双方同步。这就是为什么在删除时需要将子实体与父实体解除关联。
是的,那是一只虫子。我打赌您没有使用Hibernate的最新版本(4.3.8),并且它与此问题相关(如果不是同一问题):[HHH-9330]orphanRemove=true在双向关系中不起作用(没有级联),即使使用最新版本,此错误也可能存在。如果是这样,请报告它,然后在这里的某个地方向bug报告URL。解决方法:仅当确定必须持久化子项时,才尝试添加该子项,或者尝试将子项中的父项设置为null:
child.setParent(空)
另外,作为另一种解决方法,您可以尝试使用Hibernate会话,而不是EntityManager(正如Hibernate论坛中所写)。
问题内容: 我正在尝试清理有很多孤立物品的桌子。 我正在通过查找空值来检查是否与另一个表有关系,从而达到这一目的。 我收到一个错误,左外部联接无效。 我正在寻找其他方法的建议,可以从这种破裂的关系中删除这些孤儿 问题答案: 试试这个:
问题内容: 阅读了 JPA 2.0 / Hibernate和“orphanRemoval”:仅替换一个实体并不会删除旧的实体和相关票据https://hibernate.atlassian.net/browse/HHH-6484,我推断这已经(最终是)已在4.2.7和4.3.0.CR1版中修复。 但是,尝试 哪里 仍然不会使Hibernate 为目标实体发出SQL语句。 那么,此问题是否已解决?如
当单击按钮时,我试图删除表中的数据行。我当前的代码在1-3次按下后删除行内容,但我希望它能清除内容,然后在一次按下中添加新内容。 这是我正在使用的代码。。。 5行数据显示在jTable中。再次按下按钮后,将删除两行数据。如果我按下按钮,第二次留下一行数据。第三次按下按钮,所有行都被删除,下一次按下按钮将插入5行数据。理想情况下,我希望这个按钮总是清除行字段,然后添加插入的数据。使每个按钮按下显示新
问题内容: 从列表中删除项目时遇到麻烦。该列表是在超类中定义的,但是Hibernate批注将应用于子类中的属性访问器。超类中有两种方法可以操作列表。“添加”方法可以正常工作,但“删除”不能持久保存更改。我检查了我的Cascade设置,似乎一切正确。我在做一些不可能的事情吗?如果不是,我做错了什么吗? 这是我的课程: 我按如下方式使用TemporalAsset类的实例(请注意,我仅使用“refres
我刚加入弹性搜索公司。我正在想办法从ElasticSearch中删除数据。我已经删除了我的索引。然而,这似乎并没有真正删除数据本身。我看到的其他内容指向Delete by Query特性。然而,我甚至不确定该查询什么。我知道我的索引。从本质上说,我想弄清楚如何做一个 来自Chrome版邮递员。但是,我没有什么运气。好像不管我做什么,数据都挂在那里。到目前为止,我已经通过使用PostMan中的DEL
在mysql工作台中,我试图执行 这是一个查询,但是我收到了这个消息 错误代码:1175。您使用的是安全更新模式,并且您试图更新一个没有使用键列禁用安全模式的表,请在“首选项”中切换该选项-