Wrong behavior for @PrePersist/@PreUpdate with entityManager.merge(...)

Description

I have an entity class like -

Code:
public class Item {
@Id
//mapping
private Long id;

@ElementCollection
//mapping
private Set<ItemWrapper> wrapperSet;

@Transient
private Map<Item, Boolean> itemPredecessor;

..........
..........

@PrePersist
@PreUpdate
private void populateSet() {
wrapperSet.clear(); //itemPredecessor is empty here
for(Map.Entry<Item, Boolean> entry : itemPredecessor.entrySet()) {
wrapperSet.add(...);
}

}
..............
}

Code:
@Embeddable
public class PredecessorWrapper {

@Column(...)
private Long dependingId;
@Column(...)
private Integer ignoreErrors;

.......
}

What happens is when I call entityManager.merge(...) with newly instantiated object [entityState -> TRANSIENT] with itemPredecessor map having some entries in it, hibernate invokes callback method populateSet() with copy of instance passed to merge() which doesn't contain itemPredecessor map with respective entries as itemPredecessor is marked @Transient. When I use entityManager.persist(), it works fine as with actual instance passed to persist() is used to invoke callback method.

Note-:
I've debugged in 4.3.5 code base and found that in DefaultMergeEventListener, it does not copy properties which are marked with @Transient.

Environment

None

Activity

Show:
Steve Ebersole
October 27, 2015, 7:16 PM

This bug report does not indicate that the reported issue affects version 5.x. Versions prior to 5.x are no longer maintained. It would be a great help to the Hibernate team and community for someone to verify that the reported issue still affects version 5.x. If so, please add the 5.x version that you verified with to the list of affected-versions and attach the (preferably SSCCE) test case you used to do the verification to the report; from there the issues will be looked at during our triage meetings.

For details, see http://in.relation.to/2015/10/27/great-jira-cleanup-2015/

Steve Ebersole
October 28, 2015, 3:26 AM

As part of verifying that this issue affects 5.0, please just set the "Affects version". Leave the "verify-affects-5.0" label and leave the issue in "Awaiting Response" status; these are critical for us to be able to track these verifications and triage them. Thanks.

Christian Beikov
October 30, 2015, 11:34 AM

I'd say this is as the JPA spec mandates it. See the JPA spec 3.5.3 for reference.

For entities to which the merge operation has been applied and causes the creation of newly managed instances, the
PrePersist callback methods will be invoked for the managed instance after the entity state has been copied to it.

The transient parts of an entity are definitvely not part of the entity state. So this is actually more a feature request than a bug.
@Steve Ebersole what do you think about this?

Apart from that a side note. JPA spec 3.5.2 says it's non portable to change the entity state in lifecycle methods. You have been warned

In general, the lifecycle method of a portable application should not invoke EntityManager
or query operations, access other entity instances, or modify relationships within the
same persistence context[46].[47] A lifecycle callback method may modify the non-relationship
state of the entity on which it is invoked.

Assignee

Unassigned

Reporter

Deepak Raut

Fix versions

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Major
Configure