发行
我有一对多父子关系,但当我合并父对象时,它会创建一组重复的子记录。
细节
这是jpa onetomany的后续版本,我第一次使用eclipse链接时只更新了它,接下来我有两个类
@Entity
public class Foo {
@Id
@Column(name="FOO_ID)
private int id;
@Column(name="FOO_NAME")
private String name;
@OneToMany(mappedBy="foo", cascade = CascadeType.ALL)
private List<Bar> bars;
public void addBar(Bar b) {
b.setFoo(this);
bars.add(b);
}
}
@Entity
public class Bar {
@Id
@Column(name="BAR_ID")
private it id;
@Column(name="BAR_NAME")
private String name;
@ManyToOne
@JoinColumn(name="FOO_ID")
private Foo foo;
}
然后我有
public void processBars(Foo foo) {
for (MyListItem i : myList) {
Bar bar = new Bar();
bar.setName("Test");
foo.addBar(bar);
}
entityMgr.merge(foo);
}
最后
processBars(foo);
if(someCodition) {
foo.setStatus("xxx");
entityMgr.merge(foo);
}
然后,第二次合并将创建第二组条形图
序列、id和equalsandhashcode
我猜这是因为id字段使用了数据库序列。什么时候 Bar
创建时,id显然为空,然后出于某种原因,在插入记录并确定它是另一个对象后,它再次检查。我正在使用 Lombok
并补充说, @EqualsAndHashCode
两个类的注解,不包括“foo”中的子类列表
更新
当我发现是第二次合并导致问题时,对问题进行了修改
1条答案
按热度按时间hc2pp10m1#
jpa的合并api接收传入的对象并将其合并到上下文中。这与persist不同,persist接受传入的示例并使其成为托管示例-merge将返回托管示例。
当事务被刷新/提交时,e1将设置其id,因为它是由持久性单元管理的,但“e”不会。因此,当您调用em.merge(e)时,您将给它一个空白示例,强制输入重复的示例。
简单的解决方案是从processbars方法返回结果foo,并将其用于后续更改和合并调用。