Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In JPA, having a many-to-one as primary key throws referential integrity constraint violation

I have defined the following entities:

@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;
}

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 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?

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)

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).

like image 610
Barry NL Avatar asked Sep 03 '25 06:09

Barry NL


1 Answers

em.persist(p);
em.persist(c1);

UPDATE

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 );

I think it works with @IdClass too, but I never used it.

like image 158
Alf Avatar answered Sep 04 '25 23:09

Alf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!