Skip to content

HHH-19605 Session.isDirty might return true when batch fetching entity with CacheConcurrencyStrategy.READ_WRITE #10777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

mbellade
Copy link
Member

https://hibernate.atlassian.net/browse/HHH-19605


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.


Comment on lines 397 to 396
final LazyInitializer lazyInitializer = extractLazyInitializer( entity );
if ( lazyInitializer != null && lazyInitializer.isUninitialized() ) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why we weren't checking for non-enhanced proxies, but this seems more correct (and in line with isNonDirtyViaTracker).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget, but @mbellade look at the git history for this:

  • In commit eb1e19f I added this comment:

      		// TODO: why do we not check !lazinessInterceptor.hasWrittenFieldNames()
      		//       as we do below in isNonDirtyViaTracker() ?
    
  • In commit 5b4a6df I deliberately removed the TODO, which suggests that I figured out it's actually correct?

I don't remember any of this, and I stupidly didn't document my reasoning for removing the TODO in the commit message, but probably there's more here than meets the eye.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just checking !interceptor.isInitialized() though, not interceptor.hasWrittenFieldNames(): I get not relying on the internal written flags when using a custom dirtiness strategy, but how can a non-initialized proxy ever be considered "dirty"?

I was also wondering if there were reasons it was explicitly omitted, and we just considered any EnhancementAsProxyLazinessInterceptor to be non-initialized, but I couldn't come up with anything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you manage to come up with a test to demonstrate it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To demonstrate what? That an uninitialized proxy can be encountered here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I added one, and that revealed a NPE caused by holder.getEntityEntry() returning null. I've now switched the implementation in DefaultDirtyCheckEventListener to use PersistenceContext#reentrantSafeEntityEntries, which to me sounds more correct. This also removes the need to handle non-enhanced proxies, lmk what you think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah good.

PersistenceContext#reentrantSafeEntityEntries

This one instantiates a many instances of EntityEntryCrossRefImpl though. Is there no way to avoid that?

This also removes the need to handle non-enhanced proxies, lmk what you think.

Yeah, nice.

@mbellade mbellade force-pushed the HHH-19605 branch 2 times, most recently from 3650daa to 0fe6273 Compare August 19, 2025 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants