首页 > 解决方案 > 休眠 OneToMany 子级和级联

问题描述

我有一个非常复杂的实体设置:

A -> (一对一,共享相同的主键) B -> (一对多) C

@Entity
public class A {
    @Id
    @Column(unique = true, nullable = false)
    private Long id;

    @MapsId
    @OneToOne
    @JoinColumn(name = "id")
    private B b;
}

@Entity
public class B {
    @Id
    @Column(unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne(fetch = FetchType.LAZY, optional = true)
    @PrimaryKeyJoinColumn
    private A a;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "id")
    private Set<C> c;
}  

@Entity
public class C {
    @Id
    @Column(unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long cId;

    @MapsId
    @ManyToOne
    @JoinColumn("id")
    private B b;
} 

我想同时创建 A、B 和 C。首先,这可能吗?真正的快速单元测试:

A a = new A();
B b = new B();

C c1 = new C();
c1.setB(b);
C c2 = new C();
c2.setB(b);

Set<C> set = new HashSet<C>(2);
set.add(c1);
set.add(c2); // works if this is commented out

b.setA(a);
b.setC(set);

a.setB(b);

crudRepo.save(a);

DataIntegrityViolationException: A different object with the same identifier value was already associated with the session

我已经尝试了一系列具有不同级联类型、不同“ownedBys”的组合,或者最终尝试生成具有相同 ID/主键的多个“C”,或者出现错误说 C 需要首先持久化。如果我错误地复制了一些代码,我深表歉意 - 试图将不相关的东西排除在外。

标签: hibernatespring-data-jpa

解决方案


尝试以这种方式更正您的映射:

@Entity
public class A {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(unique = true, nullable = false)
    private Long id;

    @MapsId
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "id")
    private B b;
}

@Entity
public class B {
    // ...
    @OneToOne(mappedBy = "b")
    private A a;
}  

然后以这种方式保存您的实体:

A a = new A();
B b = new B();
C c1 = new C();
C c2 = new C();

Set<C> set = new HashSet<C>(2);
set.add(c1);
set.add(c2);

b.setC(set);

// sync both side of bi-directional @OneToOne association
a.setB(b);
b.setA(a)

crudRepo.save(a);

推荐阅读