JPA OneToMany 仅在第一次更新

JPA OneToMany Only Updates First Time

我正在使用 EclipseLink 并且我有两个基本的 类 比如

@Entity
public class Foo {
  @Id
  @Column(name="FOO_ID)
  private int id;
  
  @Column(name="FOO_NAME")
  private String name;
  
  @OneToMany(mappedBy = "foo")
  private List<Bar> bars;
}

@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 processBar(Foo foo) {
  Bar bar = new Bar();
  bar.setName("Test");
  bar.setFoo(foo);
  entityMgr.persist(bar);
  
  List<Bar> bars = foo.getBars();
  
  for (Bar b : bars) {
    System.out.println("Bar - id : " + b.getId());
    System.out.println("Bar - name : " + b.getName());
  }
}

当我进入 webapp 并调用代码(foo 设置良好)时,我可以看到一个 child Bar 的预期输出,其中包含我期望的 ID 和名称。

如果我随后进入一个新会话并 运行 相同的代码,那么我不会看到两个 Bar,我仍然看到第一个(而且只有第一个)但是Bar 记录已在数据库中创建并正确链接。

如果我在创建新的 Bar 之前添加相同的循环来打印出柱状图,那么在创建 bar

之前和之后我总是会看到一个空列表

oneToMany 上设置 fetch = FetchType.EAGER) 给我一个空集。 添加 bar 后合并 foo 没有任何区别。

我需要什么才能使它保持一致?

更新

我现在通过在 Foo

中实现一个 addBar 方法来完成这项工作
public void addBar(Bar b) {
  bars.add(b);
}

为关系添加级联

@OneToMany(mappedBy="foo", cascade = CascadeType.ALL)

然后我用 foo.addBar(bar)

替换了 bar 的 persist

最后添加了entityMgr.merge(foo)

现在可以正常工作了,但我仍然不明白为什么原始代码不起作用,所以关于该代码如何工作的问题仍然存在(或者是否必须像我所做的那样完成这里)

您正在使用双向 OneToMany 关系,因此,如果您在关系中添加或删除项目,例如通过提供特殊的 setter,您有责任更新 Java 模型。例如,see this blogpost.