【发布时间】:2012-02-29 11:11:40
【问题描述】:
我正在编写允许将对象图从一个数据库迁移到另一个数据库的代码。对象图表示配置,我们实质上是将配置从暂存环境转移到生产环境。
从源数据库中获取图形,分离,序列化,然后合并到目标数据库中。
到目前为止,这一直运作良好,但我有一个泡菜。
我有一个看起来像这样的图表:
@Entity
class UoObject
{
@Id
private int uoObject;
@OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
private Set<UoAttribute> uoAttribute;
// Other irrelevant fields
}
@Entity
class UoAttribute
{
@Id
private int uoAttribute;
@OneToOne(optional=true, fetch=FetchType.EAGER, cascade=CascadeType.ALL)
private UoAttributeObject uoAttributeObject;
}
@Entity
class UoAttributeObject
{
@Id
private UoAttribute uoAttribute;
@ManyToOne
private UoObject uoObject;
}
所以这里 UoObject 有一个 UoAttributes 的集合,而这些 UoAttributes 可能有一个 UoAttributeObject 引用另一个 UoObject。
UoAttributeObjects 引用的 UoObjects 应该已经在目标数据库中。如果不是,我想提出一个错误。为清楚起见,我从不希望目标 UoObject 更新其状态...本质上我只想建立关系。
当我实现这个时,我预计如果关系上没有 cascade=MERGE,JPA 会引发错误,指出对象不存在。或者,甚至,数据库层最终会抱怨外键。相反,我发现 JPA 尝试插入一个大部分为空的 UoObject 实例(仅设置了键)。我在 JPA 2.0 规范中发现了这一点:
如果 X 是合并到 X' 的实体,并引用另一个实体 Y,其中未指定 cascade=MERGE 或 cascade=ALL,则从 X' 导航相同关联会产生对托管对象 Y 的引用' 具有与 Y 相同的持久标识。
似乎源数据库发现目标 UoObject 不存在,安排一个实例进行插入(坏),但没有合并源 UoObject 的状态(好!)。
在源数据库端,有没有办法可以检测到实体不在数据库中并引发错误?我怀疑生命周期回调 @PrePersist 和 @PreUpdate 可能会有所帮助,但我不知道如何。
【问题讨论】:
-
我怀疑我被这个错误击中了:bugs.eclipse.org/bugs/show_bug.cgi?id=247662
标签: jpa merge eclipselink