gpt4 book ai didi

java - Hibernate 在填充新持久的子集合时会复制父集合中的元素

转载 作者:行者123 更新时间:2023-11-30 07:26:42 26 4
gpt4 key购买 nike

有人可以解释我遇到的以下奇怪行为吗?我试图保留一些新的子对象并同时将它们添加到父集合中。最后,父集合中的元素数量是我预期的两倍。让我举个例子:

@Entity
public class A {

@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Integer id;

@OneToMany(mappedBy = "a")
private List<B> bs = new ArrayList<>();

public Integer getId() { return id; }

public void setId(Integer id) { this.id = id; }

public List<B> getBs() { return bs; }

public void setBs(List<B> bs) { this.bs = bs; }
}

@Entity
public class B {

@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Integer id;

@ManyToOne
private A a;

public Integer getId() { return id; }

public void setId(Integer id) { this.id = id; }

public A getA() { return a; }

public void setA(A a) { this.a = a; }
}

测试用例:

@Test
public void test() throws Exception {
entityManager.getTransaction().begin();

A a = new A();

entityManager.persist(a);
entityManager.flush();
entityManager.clear();

a = entityManager.find(A.class, a.getId());

for (int i = 0; i < 3; i++) {
B b = new B();
b.setA(a);
entityManager.persist(b);
a.getBs().add(b);
}

assertEquals(3, a.getBs().size());

entityManager.getTransaction().commit();
}

结果:

java.lang.AssertionError: 
Expected :3
Actual :6

我不问如何修改给定的代码以达到预期的结果。我想了解为什么给定的代码会这样。

<小时/>

更新:在 EclipseLink 和 DataNucleus 上工作正常,但在 Hibernate 上失败。

感谢@riskop的回答和我的进一步调查,我们可以总结:

  • EclipseLink 2.5.0 - 它按预期工作。
  • DataNucleus 4.1.9 - 它按预期工作。
  • Hibernate 5.1.0.Final、5.0.3.Final 4.3.11.Final、4.2.21.Final、... - 它就是不起作用。

最佳答案

不幸的是,我无法准确地告诉您如何发生这种情况

但我想说这是一个 Hibernate 错误。它应该返回 3。

我用 Hibernate 5.0.3.Final 检查了这一点,并遇到了同样的问题。然后我使用 DataNucleus 4.1.9 检查了完全相同的代码,它按预期工作(没有重复的集合大小)。

但是,即使使用 Hibernate,如果执行以下任一操作,问题也会消失:

  • 不使用@GenerateValue(strategy = GenerationType.IDENTITY)。 GenerationType.IDENTITY 是不鼓励的,并且可能是其他问题的根源(只需谷歌即可找到)。如果将其更改为自动,则 Hibernate 可以正常工作。
  • 更改为对实体 A 进行急切获取 (@OneToMany(mappedBy = "a", fetch=FetchType.EAGER)
  • 从数据库加载集合后初始化 A 上的集合(例如通过调用 a.getBs().size())。

关于java - Hibernate 在填充新持久的子集合时会复制父集合中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36728616/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com