3

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

4

4 に答える 4

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

アップデート

問題は、コードが JPA に準拠していないことだと思います。embeddedId を試してみてください。うまくいきます。

@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が、使用したことはありません。

于 2013-07-11T12:39:04.653 に答える
1

私はあなたが正しいと思います。

最初に子を永続化し、次に親を永続化する必要があります。

于 2013-07-11T11:50:19.147 に答える
1

バリー

Java の ManyToOne 関係は、ソース オブジェクトに別のターゲット オブジェクトを参照する属性があり、(もし) そのターゲット オブジェクトがソース オブジェクトに逆の関係を持っていた場合、それは OneToMany 関係になります。

JPA は、逆の関係 (定義されている場合) が OneToOne の関係であることを除いて、ManyToOne の関係と同様の OneToOne の関係も定義します。

JPA における OneToOne 関係と ManyToOne 関係の主な違いは、ManyToOne にはソース オブジェクトのテーブルからターゲット オブジェクトのテーブルへの外部キーが常に含まれていることです。一方、OneToOne 関係では、外部キーはソース オブジェクトのテーブルまたは対象オブジェクトのテーブル。

以下の例を見ることができます

@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();
于 2013-07-12T05:35:23.570 に答える