jpa多次合并导致重复记录

xmd2e60i  于 2021-09-13  发布在  Java
关注(0)|答案(1)|浏览(481)

发行

我有一对多父子关系,但当我合并父对象时,它会创建一组重复的子记录。

细节

这是jpa onetomany的后续版本,我第一次使用eclipse链接时只更新了它,接下来我有两个类

  1. @Entity
  2. public class Foo {
  3. @Id
  4. @Column(name="FOO_ID)
  5. private int id;
  6. @Column(name="FOO_NAME")
  7. private String name;
  8. @OneToMany(mappedBy="foo", cascade = CascadeType.ALL)
  9. private List<Bar> bars;
  10. public void addBar(Bar b) {
  11. b.setFoo(this);
  12. bars.add(b);
  13. }
  14. }
  15. @Entity
  16. public class Bar {
  17. @Id
  18. @Column(name="BAR_ID")
  19. private it id;
  20. @Column(name="BAR_NAME")
  21. private String name;
  22. @ManyToOne
  23. @JoinColumn(name="FOO_ID")
  24. private Foo foo;
  25. }

然后我有

  1. public void processBars(Foo foo) {
  2. for (MyListItem i : myList) {
  3. Bar bar = new Bar();
  4. bar.setName("Test");
  5. foo.addBar(bar);
  6. }
  7. entityMgr.merge(foo);
  8. }

最后

  1. processBars(foo);
  2. if(someCodition) {
  3. foo.setStatus("xxx");
  4. entityMgr.merge(foo);
  5. }

然后,第二次合并将创建第二组条形图

序列、id和equalsandhashcode

我猜这是因为id字段使用了数据库序列。什么时候 Bar 创建时,id显然为空,然后出于某种原因,在插入记录并确定它是另一个对象后,它再次检查。我正在使用 Lombok 并补充说, @EqualsAndHashCode 两个类的注解,不包括“foo”中的子类列表

更新

当我发现是第二次合并导致问题时,对问题进行了修改

hc2pp10m

hc2pp10m1#

jpa的合并api接收传入的对象并将其合并到上下文中。这与persist不同,persist接受传入的示例并使其成为托管示例-merge将返回托管示例。

  1. Entity e = new Entity();
  2. Entity e1 = em.merge(e);
  3. assertTrue(e1!=e);// they are different instances

当事务被刷新/提交时,e1将设置其id,因为它是由持久性单元管理的,但“e”不会。因此,当您调用em.merge(e)时,您将给它一个空白示例,强制输入重复的示例。
简单的解决方案是从processbars方法返回结果foo,并将其用于后续更改和合并调用。

相关问题