Eclipse Link strange behavior after re attaching e

2019-08-06 04:12发布

问题:

I have a standard JEE7 application using Eclipse Link as JPA engine and an Entity tree will all entities annotated with CascadeType.ALL in their OneToMany relationships. All Entities have @GeneratedValue ids from database sequences.

During a transaction I have fetched a managed instance of an Entity tree, then I detach the root then set null to all @Id fields and @Version fields of the tree and merge the root Entity.

As I expect all managed Entities in the tree, except from two, have new Ids. The problem is that 2 entities of different type retain the null in their id fields and when committing I'm getting the following Exception:

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]

I tried several changes in equals and hashCode methods in that EntityA mainly to avoid regarding two entities equals if their ids are null in both of them, but nothing happened. The behavior is not deterministic, during debugging sometimes the id was generated but usually is null.

Could anyone give a hint for the problem.

--EDIT

When we used FetchType.EAGER instead of FetchType.LAZY in problematic relationship, the merge created the ids as expected. Could anyone explain why this happens?

回答1:

Unless you are serializing your entity, it is not really detached. EclipseLink has functionality that allows fetching lazy relationships as long as the context is still available, which pretty much means until the EntityManagerFactory is closed or the entity is serialized. So if you 'detach' your entity and traverse a lazy, unfetched relationship, the referenced entities will be read in from the EntityManager that performed the initial read, and be managed.

Regardless of that, since change tracking an other artifacts get woven into your entities, you are better off copying your entity if you wish to persist the data with a new identity.