Eclipselink与连接对象合并/持久化 [英] Eclipselink merge/persist with joined objects
本文介绍了Eclipselink与连接对象合并/持久化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有两个实体,A和B。合并A时,我也希望合并B-所以我从不对B进行操作,而总是对A进行操作。可以通过A对象访问B对象。 ,反之亦然(如果可能),反之亦然。 A和B共享相同的主键字段,也就是说,B的主键字段是A的主键的外键。但是,我终于知道了 INSERT
查询的顺序正确,但是由于未在查询参数中绑定ID,因此会抛出 InsertNullViolation
,因为未设置主键。有谁知道如何使EclipseLink绑定诸如B之类的已连接对象的主键?
公共类A {
...
@Id
@Column(name = A_ID)
@SequenceGenerator(...)
@GeneratedValue(...)
公共长getA_ID();
@OneToOne(mappedBy = a,targetEntity = B.class)
public B getB();
...
}
公共类B {
...
@Id
public Long getA_ID();
MapsId
@ OneToOne(targetEntity = A.class)
@ JoinColumn(name = A_ID)
public A getA();
...
}
以上设置未设置主键
公共类A {
...
@Id
@Column(name = A_ID)
@SequenceGenerator(...)
@GeneratedValue(...)
public Long getA_ID();
@OneToOne(mappedBy = a,targetEntity = B.class)
public B getB();
...
}
公共类B {
...
@Id
@OneToOne(targetEntity = A.class)
@JoinColumn(name = A_ID)
public A getA();
...
}
此设置也有相同的问题。例外是:
内部异常:java.sql.SQLIntegrityConstraintViolationException:ORA-01400:无法将NULL插入( SOME_USER。 B。 A_ID)
错误代码:1400
调用:INSERT INTO B(SOME_FIELD1,SOME_FIELD2,...,A_ID)值(?,?,..., ?)
bind => [null,SOME_VALUE,...,null]
查询:InsertObjectQuery(packagename.B@ObjectId)
EclipseLink需要使用绑定线填充绑定行上的最后一个 null
,它使用先前插入对象A时从序列中检索到的实际ID。 $ b我要进行的合并基本上可以归结为:
public void merge(A objectA,B objectB){
objectA.setB(objectB);
entitymanager.merge(objectA);
}
解决方案
问题似乎是您没有在B上设置A。
您必须保持双向关系,没有魔术为您做到这一点。
在创建A并分配B时,还必须将A分配给B,否则它为null,并将插入null。因此,您应该这样做而是:
public void merge(A objectA,B objectB){
A.setB(objectB); //因此,当您合并A时,它将知道B个对象
B.setA(objectA); //因此B知道要查看A对象的键
Entitymanager.merge(objectA);
}
此外,在第一个示例中,B中也有重复的A_ID字段,因此在设置A的B时,还必须设置此值。确保首先保持A的持久性,否则其Id为null,可以通过删除A_ID并将@Id放在OneToOne上来避免这种情况,就像在你的第二个例子。您还可以在A_ID中插入insert / updateable = false,在OneToOne中输入true,然后外键值将来自OneToOne。
您将获得多个可写映射。错误,因为A_ID和OneToOne都映射同一列,因此您需要将其中之一标记为insert / updateable = false。
查看全文