我有一个标准的JEE7应用程序,使用Eclipse Link
作为JPA
引擎,实体树将在其OneToMany
关系中用CascadeType.ALL
注释所有实体。所有实体都具有来自数据库序列的@GeneratedValue
ID。
在事务处理过程中,我获取了实体树的托管实例,然后分离根,然后将树的所有@Id
字段和@Version
字段设置为null,并合并根实体。
正如我所期望的,树中的所有托管实体(除了两个)都有新的Id。问题是,两个不同类型的实体在它们的id字段中保留了null,当提交时,我会得到以下异常:
org.eclipse.persistence.exceptions.ValidationException
Exception Description: Null or zero primary key encountered in unit of work clone [EntityA [id=null, businessId=17EN000000000083]], primary key [null]
我在EntityA中尝试了对equals和hashCode方法的几次更改,主要是为了避免在两个实体的id都为null的情况下将两个实体视为equals,但都没有发生。这种行为是不确定的,在调试过程中,有时会生成id,但通常为null。
有人能给这个问题一个提示吗。
--编辑
当我们在有问题的关系中使用FetchType.EAGER
而不是FetchType.LAZY
时,merge
按预期创建了ID。有人能解释为什么会发生这种情况吗?
除非您正在序列化实体,否则它并不是真正分离的。EclipseLink的功能允许在上下文仍然可用的情况下获取惰性关系,这几乎意味着直到EntityManagerFactory关闭或实体序列化。因此,如果您"分离"实体并遍历惰性、不匹配的关系,则引用的实体将从执行初始读取的EntityManager中读取并进行管理。
不管怎样,由于更改跟踪和其他工件被编织到您的实体中,如果您希望用新身份持久化数据,那么最好复制您的实体。