Updates can be lost with CustomEntityDirtynessStrategy
Description
follows up on
Activity

Christian Beikov January 14, 2025 at 7:07 PM
I reproduced the mentioned problems based on the PR. The first issue is a bug in the user code. ChildThing#setNullableFKReference
forgot to call changedValues.put( "nullableFKReference", this.nullableFKReference );
before changing the value.
The second issue is IMO simply a wrong expectation. Changing the state array in an interceptor will cause the entity object to be updated, but since you're using field access, the setter method is never called, so your custom dirtyness strategy never gets notified of this change. Hence the changedValues
of DynamicallyUpdatedThing
does not contain mutableProperty
. To fix this, you will simply have to use property access by e.g. moving the @Id
annotation to the getter method.
Attached you can find a patch that shows the test that I used to verify this.
Steve Ebersole October 28, 2015 at 3:25 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.
Steve Ebersole October 27, 2015 at 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/

Brett Meyer December 23, 2013 at 5:32 PM
, for scenario #1, what are your thoughts? Is it a good idea to automatically handle the secondPass updates' dirtiness in EntityEntry#isUnequivocallyNonDirty (maybe by checking the loadedState, etc)? Or, simply add javadocs and enforce that conditions causing secondPass updates (circular references, cascading, etc.) need to be explicitly handled in CustomEntityDirtinessStrategy impls? Other alternatives?

Shawn Clowater April 11, 2013 at 11:35 PM
Steve,
I noticed your recent blog post on the dirtiness check and it reminded me of this issue, not sure if you ever saw it but it contains 2 scenarios that I hit when I tried to implement the functionality last year.
I've found 2 different scenarios where updates can slip through the cracks when using the CustomEntityDirtynessStrategy functionality.
Scenario 1-
When saving an entity that references another, Hibernate will temporarily null out the properties and then update it in a secondary pass if it's not saved yet (to satisfy FK constraints). If the custom strategy returns that the entity isn't modified (it doesn't know that the Nullifier modified the loaded state)
This getValues() method of the DefaultFlushEntityEventListener determines that the loadedState != null and mightBeDirty is false so it then updates the entity based on the current loaded state and nulls out the property. The subsequent update never happens.
Scenario 2-
Interceptor modifies value during flush, the handleInterception() method in DefaultFlushEntityEventListener doesn't update the dirty values since the event is marked as handled by interceptor.
I worked around #2 locally by calling back into the custom dirty checker findDirty functionality but I have added a unit test that shows the scenario.
I have no idea what to do with Scenario #1, unit test will be provided to cover that scenario as well.