【问题标题】:JPA2/EclipseLink OneToMany cascade persist issue "Referential integrity constraint violation"JPA2/EclipseLink OneToMany 级联持续问题“参照完整性约束违规”
【发布时间】:2012-03-26 00:22:34
【问题描述】:

我有两个实体 A 和 B:

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;

【问题讨论】:

    标签: jpa eclipselink


    【解决方案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,可更新=false。

    【讨论】:

    • 谢谢克里斯,你的回答帮助了我,只是一个小小的精度:netbeans 生成这些实体不是我创建的,我只创建 SQL 表....;是我们必须熟悉注释还是只使用生成所有这些的 IDE?你有什么建议吗?
    • 注解大家一定要熟悉。自动生成在大多数情况下运行良好,但它可能会出错,或者自动注释无法获得多个选项。因此最好先使用自动注解对事物进行逆向工程,然后查看注解并修复您不需要的剔除事物。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    • 2019-10-25
    • 1970-01-01
    • 2011-12-13
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多