gpt4 book ai didi

java - Eclipselink 合并/保留连接的对象

转载 作者:行者123 更新时间:2023-12-02 07:59:07 24 4
gpt4 key购买 nike

我有两个实体,A 和 B。当我合并 A 时,我希望 B 也被合并 - 所以我从不对 B 进行操作,而总是对 A 进行操作。B 对象可以通过 A 对象访问,但反之则不然(如果可能的话)。 A 和 B 共享相同的主键字段,即 B 的主键字段是 A 的主键的外键。但是,我终于得到了 INSERT 查询的顺序正确,但由于它没有绑定(bind)查询参数中的 ID,因此它会抛出 InsertNullViolation,因为未设置主键。有谁知道如何让 EclipseLink 为 B 这样的连接对象绑定(bind)主键?

public class A {
...
@Id
@Column(name = "A_ID")
@SequenceGenerator(...)
@GeneratedValue(...)
public Long getA_ID();

@OneToOne(mappedBy = "a", targetEntity = B.class)
public B getB();
...
}

public class B {
...
@Id
public Long getA_ID();

@MapsId
@OneToOne(targetEntity = A.class)
@JoinColumn(name="A_ID")
public A getA();
...
}

上述设置未在 B 上设置主键,因此会在尝试插入 B 时引发 InsertNullViolation。

public class A {
...
@Id
@Column(name = "A_ID")
@SequenceGenerator(...)
@GeneratedValue(...)
public Long getA_ID();

@OneToOne(mappedBy = "a", targetEntity = B.class)
public B getB();
...
}

public class B {
...
@Id
@OneToOne(targetEntity = A.class)
@JoinColumn(name="A_ID")
public A getA();
...
}

这个设置也有同样的问题。异常(exception)是:

Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("SOME_USER"."B"."A_ID")

Error Code: 1400
Call: INSERT INTO B (SOME_FIELD1, SOME_FIELD2, ..., A_ID) VALUES (?, ?, ..., ?)
bind => [null, SOME_VALUE, ..., null]
Query: InsertObjectQuery(packagename.B@ObjectId)

绑定(bind)行上的最后一个 null 需要由 EclipseLink 使用之前在插入对象 A 时从序列中检索到的实际 ID 进行填充。我为合并所做的事情基本上可以归结为:

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); //so when you merge A it knows about the B objects
B.setA(objectA); //so B knows to look at the A object for it's key
entitymanager.merge(objectA);
}

此外,在第一个示例中,B 中也有重复的 A_ID 字段,因此在设置 B 的 A 时也必须设置该值。确保先持久化了 A,否则其 Id 将为空,您可以通过删除 A_ID 并将 @Id 放在 OneToOne 上来避免这种情况,就像您在第二个示例中所做的那样。您还可以将 insert/updateable=false 放在 A_ID 中,将 true 放在 OneToOne 中,那么外键值将来自 OneToOne。

您收到多个可写映射错误,因为 A_ID 和 OneToOne 都映射同一列,您需要标记其中之一 insert/updateable=false。

看, http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Primary_Keys_through_OneToOne_and_ManyToOne_Relationships

并且, http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Object_corruption.2C_one_side_of_the_relationship_is_not_updated_after_updating_the_other_side

关于java - Eclipselink 合并/保留连接的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9165747/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com