jpa多次合并导致重复记录

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

发行

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

细节

这是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”中的子类列表

更新

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

hc2pp10m

hc2pp10m1#

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

Entity e = new Entity();

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

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

相关问题