我有三个类(A、B、C),它们具有OneToMany关系A <>-- B <>-- C代码:
@Getter @Setter
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "a")
private List<B> bList;
private String name;
}
@Getter @Setter
@Entity
public class B {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne(fetch = FetchType.EAGER)
private A a;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "b")
private List<C> cList;
private String name;
}
@Getter @Setter
@Entity
public class C {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@ManyToOne(fetch = FetchType.EAGER)
private B b;
}我应该如何正确地填充数据?当我尝试这样的事情时:
A a = new A();
a.setName("A-1");
aRepository.save(a);
B b1 = new B();
b1.setName("B-1");
b1.setA(a);
bRepository.save(b1);
B b2 = new B();
b2.setName("B-2");
b2.setA(a);
bRepository.save(b2);
for (int i = 1; i <= 9; i++ ) {
C c = new C();
c.setName("C-"+i);
c.setB(b1);
cRepository.save(c);
}我在数据库中得到了正确填充的数据:
+----+------+
| ID | NAME |
+----+------+
| 1 | A-1 |
+----+------+
+----+------+------+
| ID | NAME | A_ID |
+----+------+------+
| 1 | B-1 | 1 |
+----+------+------+
| 2 | B-2 | 1 |
+----+------+------+
+----+------+------+
| ID | NAME | B_ID |
+----+------+------+
| 1 | C-1 | 1 |
+----+------+------+
| 2 | C-2 | 1 |
+----+------+------+
| 3 | C-3 | 1 |
+----+------+------+
| 4 | C-4 | 1 |
+----+------+------+
| 5 | C-5 | 1 |
+----+------+------+
| 6 | C-6 | 1 |
+----+------+------+
| 7 | C-7 | 1 |
+----+------+------+
| 8 | C-8 | 1 |
+----+------+------+
| 9 | C-9 | 1 |
+----+------+------+但是,当我试图从存储库获取数据时,有些地方是错误的:
这些测试是可以的:
assertThat(cRepository.findOne(1l)).isNotNull();
assertThat(cRepository.findOne(1l).getB()).isNotNull();
assertThat(cRepository.findAll()).hasSize(9);
assertThat(bRepository.findAll()).hasSize(2);
assertThat(bRepository.findOne(1l).getCList().size()).isEqualTo(9);但这次失败了:
assertThat(aRepository.findOne(1l).getBList().size()).isEqualTo(2);它返回10条记录。QuerySELECT * FROM B WHERE A_ID = 1返回2条记录,所以请您说明一下我做错了什么?
发布于 2015-05-11 18:50:27
它的奇怪的hibernate行为,这是由于热切的类型使用外部联接。对于与B相关的每个C对象,您都会得到重复的B对象。我遇到了类似的问题,我找到的唯一解决方案是将fetchType更改为惰性,或者更改列表设置。
在这里您有更好的解释:Hibernate Criteria returns children multiple times with FetchType.EAGER或Duplicates in OneToMany annotated List
发布于 2015-05-11 15:57:41
您需要将其更改为以下内容:
B b1 = new B();
b1.setName("B-1");
b1.setA(a);
a.getBList().add(b1);
bRepository.save(b1);
B b2 = new B();
b2.setName("B-2");
b2.setA(a);
a.getBList().add(b2);
bRepository.save(b2);
aRepository.save(a);现在从我这边得到一点信息。理论上,它也不需要额外的三行代码,但前提是使hibernate缓存失效。我认为,如果您分离a,而dann得到a。一般的建议,如果可能的话,它可能会返回正确的结果,避免双向映射。如果需要的话,将折叠部分添加到
public void addB(B b) {
b.setA(this);
a.getBList().add(b);
}发布到ManyToOne。不需要添加急切的抓取,因为这是默认值。
https://stackoverflow.com/questions/30172100
复制相似问题