2012-03-26 29 views
1

我有兩個實體A和B:JPA2/EclipseLink的一對多級聯堅持問題 「參照完整性約束違規」

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 ... 有任何幫助嗎? 預先感謝您。

編輯: 解決只需更換這一點:這個一個

@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屬性 - 意味着必須先使用A的值設置此屬性,然後才能保留B。

如果您使用的是JPA 2.0,則可以使用@MapsId(「aIda」)標記@ManyToOne,它將允許您刪除@JoinColumn它。這將使JPA提供程序將b.bPK.aIda中的值設置爲保持爲A的值。

如果你不使用JPA 2.0,你可以自己設置它首先堅持A,然後改變你的ADDB方法也設置B的bPK.aIda,或者你可以改變字段,以便JoinColumn是可寫的並使bPK.aIda可插入= false,updatable = false。

+0

感謝克里斯你的答案幫助了我,只是一個小精度:netbeans生成這些實體它不是我創建的,我只創建SQL表....是的,我們必須熟悉註釋或者只是使用可以生成所有這些註釋的IDE?你有什麼建議嗎? – Stacker 2012-03-26 21:33:14

+0

我們絕對必須熟悉註釋。自動生成在大多數情況下運行良好,但它可能會出錯或者自動註釋沒有得到多個選項。因此,最好先使用自動註釋對事物進行逆向工程,然後查看註釋並確定您不需要的東西。 – Ben 2016-07-27 08:31:19

相關問題