在JPA中,将多对一作为主键会引发引用完整性约束冲突 [英] In JPA, having a many-to-one as primary key throws referential integrity constraint violation
问题描述
我定义了以下实体:
@Entity
public class Child implements Serializable
{
@Id
@ManyToOne(cascade = CascadeType.ALL)
public Parent parent;
@Id
public int id;
}
@Entity
public class Parent
{
@Id
public int id;
}
当我尝试使用以下代码保留Child时:
When I try to persist a Child with the following code:
Parent p = new Parent();
p.id = 1;
Child c1 = new Child();
c1.id = 1;
c1.parent = p;
em.persist(c1);
Hibernate引发违反参考完整性约束"错误:
Hibernate throws a 'Referential integrity constraint violation' error:
Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FK3E104FC802AAC0A: PUBLIC.CHILD FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.PARENT(ID) (1)"; SQL statement:
insert into Child (parent_id, id) values (?, ?) [23506-171]
我相信这是因为它先插入子级,然后再插入父级,而我希望它先插入父级.知道如何更改插入顺序,或如何以其他方式解决此问题吗?
I believe this is because it first inserts the Child and then the Parent, while I would expect it to insert the Parent first. Any idea how I can change the order of insertion, or how to to solve this in some other way?
更新:请注意,此方法不符合JPA,但使用的是Hibernate规范(请参见
Update: note that this approach is not JPA compliant, but uses Hibernate specifics (see section 5.1.2.1. Composite identifier in the hibernate docs)
更新:我只需要持久保留Child c1并自动将持久化层叠级联到Parent p(此更新是对下面@Alf的回答的反应).
Update: I would like to only have to persist the Child c1 and have the persist cascade to Parent p automatically (this update is in reaction to @Alf's answer below).
推荐答案
em.persist(p);
em.persist(c1);
更新
我认为问题在于您的代码不符合JPA.尝试使用EmbeddedId,它对我有用.
I think the problem is that your code is not JPA compliant. Try with embeddedId, it works for me.
@Embeddable
public class ChildPK implements Serializable {
private int parentId;
private int childId;
// getters and setters
}
@Entity
public class Child implements Serializable {
@EmbeddedId
public ChildPK id = new ChildPK();
@MapsId( "parentId" )
@ManyToOne
public Parent parent;
}
Parent p = new Parent();
p.id = 1;
Child c1 = new Child();
c1.id.setChildId( 1 );
c1.parent = p;
em.persist( c1 );
我认为它也可以与@IdClass
一起使用,但我从未使用过.
I think it works with @IdClass
too, but I never used it.
这篇关于在JPA中,将多对一作为主键会引发引用完整性约束冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!