2012-03-26 32 views
1

私は2つのエンティティAとBがあります。JPA2/EclipseLinkのOneToManyカスケード存続問題 "参照整合性制約違反"

A.java:

... 
public class A implements Serializable { 
private static final long serialVersionUID = 1L; 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Basic(optional = false) 
@Column(name = "IDA", nullable = false) 
private Integer ida; 
@Basic(optional = false) 
@Column(name = "NAME", nullable = false, length = 30) 
private String name; 
@OneToMany(cascade = CascadeType.ALL, mappedBy = "a") 
private List<B> bList=new ArrayList(); 

public void addB(B bp){ 
bp.setA(this); 
bList.add(bp); 
} 
... 

B.java:

... 
public class B implements Serializable { 
private static final long serialVersionUID = 1L; 
@EmbeddedId 
protected BPK bPK; 
@Basic(optional = false) 
@Column(name = "NAME", nullable = false, length = 30) 
private String name; 
@JoinColumn(name = "A_IDA", referencedColumnName = "IDA", nullable = false, insertable = false, updatable = false) 
@ManyToOne(optional = false) 
private A a; 
... 

bPKフィールドは複合主キーです。

@Embeddable 
public class BPK implements Serializable { 
@Basic(optional = false) 
@Column(name = "IDB", nullable = false, length = 20) 
private String idb; 
@Basic(optional = false) 
@Column(name = "A_IDA", nullable = false) 
private int aIda; 

public BPK() { 
} 

public BPK(String idb, int aIda) { 
    this.idb = idb; 
    this.aIda = aIda; 
} 
... 

SQLコード:

CREATE TABLE A (
idA INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 
name VARCHAR(30) NOT NULL, 
PRIMARY KEY(idA) 
); 

CREATE TABLE B (
idB VARCHAR(20) NOT NULL, 
A_idA INTEGER UNSIGNED NOT NULL, 
name VARCHAR(30) NOT NULL, 
PRIMARY KEY(idB, A_idA), 
FOREIGN KEY(A_idA) 
REFERENCES A(idA) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION 
); 

メインコード:

A a=new A(null,"A1"); 
    BPK bpk=new BPK(); 
    bpk.setIdb("b1"); 
    a.addB(new B(bpk,"B1")); 

    EntityManager em=getEntityManager(); 
    em.getTransaction().begin(); 
    em.persist(a); 
    em.getTransaction().commit(); 

私はこのエラーを取得する:

Exception in thread "main" javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException 
[EL Warning]: 2012-03-26 01:29:16.724--UnitOfWork(1902320872)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "CONSTRAINT_42_1: PUBLIC.B FOREIGN KEY(A_IDA) REFERENCES PUBLIC.A(IDA)"; SQL statement: 
Internal Exception: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "CONSTRAINT_42_1: PUBLIC.B FOREIGN KEY(A_IDA) REFERENCES PUBLIC.A(IDA)";... 

エラーが整合性制約の違反を示しますが、なぜですか? エンティティBの挿入がAより先に行われるかどうかを1つの可能性... 助けてください? ありがとうございます。

EDIT:この1により

@JoinColumn(name = "A_IDA", referencedColumnName = "IDA", nullable = false, insertable = false, updatable = false) 

:ちょうどこれを置き換える解決

ついに
@MapsId("aIda") 

B.java:

@NamedQuery(name = "B.findByName", query = "SELECT b FROM B b WHERE b.name = :name")}) 
public class B implements Serializable { 
private static final long serialVersionUID = 1L; 
@EmbeddedId 
protected BPK bPK; 
@Basic(optional = false) 
@Column(name = "NAME", nullable = false, length = 30) 
private String name; 
@MapsId("aIda") 
@ManyToOne(optional = false) 
private A a; 

答えて

1

あなたが制御A_AIDフィールドを持っていますEmbeddableのaIda属性によって

JPA 2.0を使用している場合は、@ManyToOneに@MapsId( "aIda")を付けて、削除できるようにすることができますそのための@JoinColumn。これにより、JPAプロバイダはb.bPK.aIdaの値をAの値をpersistに設定します。

JPA 2,0を使用していない場合は、最初にAを保持し、次にBのbPK.aIdaを設定するようにaddBメソッドを変更するか、JoinColumnが書き込み可能になるようにフィールドを変更できますbPK.aIda insertable = false、updatable = falseにします。

+0

おかげで答えが助けられました。ちょっとした精度:netbeansはこれらのエンティティを生成しました。これは私が作成した人ではなく、SQLテーブルのみを作成します。私たちはアノテーションに精通している必要がありますか、それをすべて生成するIDEを使用するだけですか?あなたは私のための提案をお持ちですか? – Stacker

+0

私たちは間違いなくアノテーションに精通していなければなりません。自動生成はほとんどの場合うまく機能しますが、何か間違ったり、自動注釈で得られない複数のオプションがあります。そのため、自動アノテーションを使用して、まずリバースエンジニアリングを行い、アノテーションを見て必要のないカリングを修正するのが最善です。 – Ben

関連する問題