質問

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

役に立ちましたか?

解決

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.

他のヒント

I think you are right at your point.

You first need to persist the child then parent.

Barry

A ManyToOne relationship in Java is where the source object has an attribute that references another target object and (if) that target object had the inverse relationship back to the source object it would be a OneToMany relationship.

JPA also defines a OneToOne relationship, which is similar to a ManyToOne relationship except that the inverse relationship (if it were defined) is a OneToOne relationship

The main difference between a OneToOne and a ManyToOne relationship in JPA is that a ManyToOne always contains a foreign key from the source object's table to the target object's table, where as a OneToOne relationship the foreign key may either be in the source object's table or the target object's table.

you can see below example

@Entity
public class Student {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;

@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="DEPT_ID")
private Department department;

 //getter and setter
}

@Entity
public class Department {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
 //getter and setter

}


Student student = new Student();
student.setName("prateek");
em.persist(student);


Department dept = new Department();
dept.setName("MCA KIIT");
student.setDepartment(dept);
em.flush();

I come with what is, I guess, a simpler solution:

@Entity
public class Child implements Serializable {
    @Id
    @JoinColumn(name = "id")
    private String id;

    @ManyToOne
    @PrimaryKeyJoinColumn
    private Parent parent;

    private String otherMember;    
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top