4

我有 3 个实体。以免将其称为 A、B、C 和第 4 个具有组合键的 ID 组合。

@Entity
public class A {
    @Id
    @GeneratedValue(generator = "generator")
    private String id;
}

@Entity
public class B {
    @Id
    @GeneratedValue(generator = "generator")
    private String id;
}


@Entity
public class C {
    @Id
    @GeneratedValue(generator = "generator")
    private String id;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "c", fetch = FetchType.LAZY)
    private List<ClassWithCompositeKey> relations = new ArrayList<ClassWithCompositeKey>();

}

@Entity
public class ClassWithCompositeKey {

    @EmbeddedId
    protected CompositeKey compositeKey;

    @JoinColumn(name = "A_ID", insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private A a;

    @JoinColumn(name = "B_ID", insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private B b;

    @JoinColumn(name = "C_ID", insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private C c;

    public ClassWithCompositeKey(A a, B b, C c) {
       this.a = a;
       this.b = b;
       this.c = c;
       this.compositeKey = new CompositeKey(a.getId(),b.getId(),c.getId());
    }

}

@Embeddable
public class CompositeKey {

    @Basic(optional = false)
    @Column(name = "A_ID", columnDefinition = "raw")
    private String aId;
    @Basic(optional = false)
    @Column(name = "B_ID", columnDefinition = "raw")
    private String bId;
    @Basic(optional = false)
    @Column(name = "C_ID", columnDefinition = "raw")
    private String cId;

    public CompositeKey(String aId, String bId, String cId) {
        this.aId = aId;
        this.bId = bId;
        this.cId = cId;
    }
}

然后当我试图保存时:

A a = new A();
B b = new B();
C c = new C();
entityManager.persist(a);
entityManager.persist(b);
//I'm not saving C
ClassWithCompositeKey classWithCompositeKey = new ClassWithCompositeKey(a, b, c);
c.getRelations().add(classWithCompositeKey);
entityManager.persist(c);

我得到了例外 "ConstraintViolationException: Column 'C_ID' cannot be null"

这是因为在“c”将被保存之前 c.id 为空,但此值会转到 CompositeKey 实例。

我想保存“c”并自动保存 ClassWithCompositeKey 的集合。但是现在我首先必须保存“c”,然后将 ClassWithCompositeKey 实例附加到它并保存它。有可能(也许通过使用其他类型的映射)在一个“持久”调用中通过级联保存 C 和 ClassWithCompositeKey 吗?

4

3 回答 3

0

我认为问题在于您在 ClassWithCompositeKey 类中同时将某些列标记为“insertable = false”和“optional = false”。

@JoinColumn(name = "A_ID", insertable = false, updatable = false)
@ManyToOne(optional = false)
private A a;

你甚至不需要这个专栏!!删除此类中的 a、b 和 c 列,如果您需要它们,您已经在您的 Embedded Id 中拥有它们:

ClassWithCompositeKey yourClass = ...;
//any initialization code
yourClass.getCompositeKey().getA();
yourClass.getCompositeKey().getB();
yourClass.getCompositeKey().getC();
于 2012-08-16T21:11:15.317 回答
0

只有在持久化时,您才会在 C 处获得生成的值,这就是您获得异常的原因。

因为休眠只会在插入操作后更新生成的值。它将首先插入然后更新连接列。

在上面的场景中,你有 c 类的 C_ID,它是主键映射到 ClassWithCompositeKey 的 C_ID,它又是主键,并且明显的主键不能为空。

因此,请尝试使用外键列重新设计您的 ClassWithCompositeKey。

于 2012-08-16T12:42:04.760 回答
0

您可能必须在复合键字段中设置您的级联选项,以至少级联持久操作。

于 2012-08-16T13:00:54.703 回答