我有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.id在保存“c”之前为空,但此值将转到CompositeKey实例。
我想保存“c”并自动保存ClassWithCompositeKey的集合。但是现在我首先必须保存“c”,然后将ClassWithCompositeKey实例附加到它并保存它。 有可能(可能通过使用其他类型的映射)在一个“持久”调用中通过级联保存C和ClassWithCompositeKey?
答案 0 :(得分:0)
只有在持续存在的时候,你才会在C处获得生成的值,这就是你得到例外的原因。
Beacuse hibernate只会在插入操作后更新生成的值。它将首先插入然后更新连接列。
在上面的场景中,你有C类的C_ID,它是主键,映射到ClassWithCompositeKey的C_ID,它又是主键,而且对象的主键不能为空。
因此,尝试使用外键列重新设置ClassWithCompositeKey。
答案 1 :(得分:0)
您可能必须在复合键字段中设置级联选项,以至少级联持久操作。
答案 2 :(得分:0)
我认为问题是你在ClassWithCompositeKey类中同时将某些列标记为“insertable = false”和“optional = false”。
@JoinColumn(name = "A_ID", insertable = false, updatable = false)
@ManyToOne(optional = false)
private A a;
您甚至不需要此列!! 删除此课程中的a,b和c列,如果您需要,您已在嵌入式ID中使用它们:
ClassWithCompositeKey yourClass = ...;
//any initialization code
yourClass.getCompositeKey().getA();
yourClass.getCompositeKey().getB();
yourClass.getCompositeKey().getC();