Skip to content

Conversation

jbescos
Copy link
Member

@jbescos jbescos commented Aug 5, 2025

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Aug 5, 2025
@jbescos jbescos self-assigned this Aug 5, 2025
@jbescos jbescos requested review from Tomas-Kraus and ljnelson August 5, 2025 10:43
@jbescos jbescos force-pushed the issue10441 branch 4 times, most recently from 72419d5 to cef1fa2 Compare August 5, 2025 13:27
@ljnelson
Copy link
Member

ljnelson commented Aug 5, 2025

I want to be careful here; I think it should be possible to merge a detached entity according to the spec.

Specifically, the spec says:

If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same identity or a new managed copy X' of X is created.

Then, recently, Hibernate says:

Previously, merging a detached entity resulted in a SQL insert whenever there was no matching row in the database (for example, if the object had been deleted in another transaction). This behavior was unexpected and violated the rules of optimistic locking.

Indeed, merging a detached entity X when there is no "pre-existing managed entity instance X'" should result in an INSERT when everything is said and done since that's how the persistence context works in all other cases. I'm not sure why Hibernate asserts that this is unexpected.

@jbescos
Copy link
Member Author

jbescos commented Aug 6, 2025

I want to be careful here; I think it should be possible to merge a detached entity according to the spec.

Specifically, the spec says:

If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same identity or a new managed copy X' of X is created.

Then, recently, Hibernate says:

Previously, merging a detached entity resulted in a SQL insert whenever there was no matching row in the database (for example, if the object had been deleted in another transaction). This behavior was unexpected and violated the rules of optimistic locking.

Indeed, merging a detached entity X when there is no "pre-existing managed entity instance X'" should result in an INSERT when everything is said and done since that's how the persistence context works in all other cases. I'm not sure why Hibernate asserts that this is unexpected.

Thanks @ljnelson , does it make sense that you open them an issue to discuss this?.

@jbescos
Copy link
Member Author

jbescos commented Aug 7, 2025

Native image fails consistently:
tests/native-image-mp-2-windows

Caused by: org.apache.maven.plugin.MojoExecutionException: Execution of C:\hostedtoolcache\windows\graalvm-jdk-21.0.3_windows-x64_bin\21.0.3\x64\graalvm-jdk-21.0.3+7.1\bin\native-image.cmd @target\tmp\native-image-5266420025302078153.args io.helidon.tests.integration.packaging.mp2.Mp2Main returned non-zero result
    at org.graalvm.buildtools.maven.AbstractNativeImageMojo.buildImage (AbstractNativeImageMojo.java:429)
    at org.graalvm.buildtools.maven.NativeCompileNoForkMojo.execute (NativeCompileNoForkMojo.java:104)

@barchetta barchetta mentioned this pull request Jul 31, 2025
12 tasks
@jbescos jbescos force-pushed the issue10441 branch 2 times, most recently from 5a51266 to ad0497f Compare August 13, 2025 08:43
@jbescos jbescos force-pushed the issue10441 branch 5 times, most recently from e23022b to 0d6d1a7 Compare September 18, 2025 09:44
@barchetta barchetta modified the milestones: 4.3.0, 4.3.1 Sep 18, 2025
@jbescos jbescos force-pushed the issue10441 branch 6 times, most recently from a3670af to 1a03467 Compare September 25, 2025 06:38
@jbescos
Copy link
Member Author

jbescos commented Sep 25, 2025

It is passing now

]
},
{
"name": "org.hibernate.event.spi.PostUpsertEventListener[]",
Copy link

Choose a reason for hiding this comment

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

@jbescos such metadata should be unnecessary if you use the Hibernate provided GraalVM module?
-https://github.com/hibernate/hibernate-orm/blame/main/hibernate-graalvm/src/main/java/org/hibernate/graalvm/internal/StaticClassLists.java#L68

I created that module to simplify such integrations by other frameworks, please let us know if it's not useful.

Copy link
Member Author

Choose a reason for hiding this comment

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

In this file we tell GraalVM what classes should be available for reflection at runtime. I added that because GraalVM told me to do so.

We don't have org.hibernate.orm:hibernate-graalvm as dependency, but I have added it and the test fails, with and without this configuration. It compiles well, but in runtime I am having some ClassNotFoundExceptions.

Copy link

Choose a reason for hiding this comment

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

In this file we tell GraalVM what classes should be available for reflection at runtime. I added that because GraalVM told me to do so.

I understand, but it makes more sense to have the rules which are specific to a library to be maintained by the library - otherwise you'll need to make changes for each new Hibernate release.
So for that reason I had created the hibernate-graalvm module.

We don't have org.hibernate.orm:hibernate-graalvm as dependency, but I have added it and the test fails, with and without this configuration.

Such features need to be activated

Args=-H:ReflectionConfigurationResources=${.}/reflect-config-additional.json
Args=-H:ReflectionConfigurationResources=${.}/reflect-config-additional.json \
-H:ClassInitialization=org.hibernate.bytecode.enhance.internal.bytebuddy.ByteBuddyEnhancementContext:run_time \
-H:ClassInitialization=org.hibernate.proxy.pojo.bytebuddy.ByteBuddyProxyHelper:run_time
Copy link

Choose a reason for hiding this comment

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

My concern would be that this is going to fail at runtime. Just hiding / postponing problems.

Copy link
Member Author

Choose a reason for hiding this comment

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

We use static enhancement, so bytebuddy related things should not be executed. This args allows me to replace the static fields that are triggering reflection.

Copy link

Choose a reason for hiding this comment

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

I understand - but the compiler is usually right, it's running a formal proof. So if it's including it, this would suggest that there are some corner cases in which this code is necessary.

Copy link
Member Author

Choose a reason for hiding this comment

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

Adding --trace-class-initialization only shows the stack traces I printed here. It starts with ByteBuddyEnhancementContext and ByteBuddyProxyHelper. We cannot know more about why are that static fields loaded.

We already have a lot of GraalVM configuration related to Hibernate here and some other methods substitutions here. I was not part of this, but it seems this integration was not easy.

@barchetta barchetta modified the milestones: 4.3.1, 4.3.2 Oct 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4.x: Tests fail when upgrading to Hibernate 6.6.23.Final

4 participants