首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >spring如何保持传递的双向关系

spring如何保持传递的双向关系
EN

Stack Overflow用户
提问于 2015-05-11 15:47:32
回答 2查看 1.5K关注 0票数 2

我有三个类(A、B、C),它们具有OneToMany关系A <>-- B <>-- C代码:

代码语言:javascript
复制
@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;
}

我应该如何正确地填充数据?当我尝试这样的事情时:

代码语言:javascript
复制
    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);
    }

我在数据库中得到了正确填充的数据:

代码语言:javascript
复制
+----+------+
| 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    |
+----+------+------+

但是,当我试图从存储库获取数据时,有些地方是错误的:

这些测试是可以的:

代码语言:javascript
复制
    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);

但这次失败了:

代码语言:javascript
复制
    assertThat(aRepository.findOne(1l).getBList().size()).isEqualTo(2);

它返回10条记录。QuerySELECT * FROM B WHERE A_ID = 1返回2条记录,所以请您说明一下我做错了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-11 18:50:27

它的奇怪的hibernate行为,这是由于热切的类型使用外部联接。对于与B相关的每个C对象,您都会得到重复的B对象。我遇到了类似的问题,我找到的唯一解决方案是将fetchType更改为惰性,或者更改列表设置。

在这里您有更好的解释:Hibernate Criteria returns children multiple times with FetchType.EAGERDuplicates in OneToMany annotated List

票数 2
EN

Stack Overflow用户

发布于 2015-05-11 15:57:41

您需要将其更改为以下内容:

代码语言:javascript
复制
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。一般的建议,如果可能的话,它可能会返回正确的结果,避免双向映射。如果需要的话,将折叠部分添加到

代码语言:javascript
复制
public void addB(B b) {
    b.setA(this);
    a.getBList().add(b);
}

发布到ManyToOne。不需要添加急切的抓取,因为这是默认值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30172100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档