在JPA中,将多对一作为主键会引发引用完整性约束冲突 [英] In JPA, having a many-to-one as primary key throws referential integrity constraint violation

查看:357
本文介绍了在JPA中,将多对一作为主键会引发引用完整性约束冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了以下实体:

@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规范(请参见5.1.2.1.复合标识符"部分/hibernate/core/3.6/reference/zh-CN/html_single/#mapping-declaration-id"rel =" nofollow>休眠文档)

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆