Skip to content
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

Hibernate ORM update issue since 3.13.0 #42902

Closed
HerrDerb opened this issue Aug 30, 2024 · 11 comments
Closed

Hibernate ORM update issue since 3.13.0 #42902

HerrDerb opened this issue Aug 30, 2024 · 11 comments
Labels
area/hibernate-orm Hibernate ORM kind/bug Something isn't working

Comments

@HerrDerb
Copy link
Contributor

HerrDerb commented Aug 30, 2024

Describe the bug

Since 3.13.0 a panache update statement fails under certain conditions.

When detaching an entity, changing its primary key and persist it as duplicate without flushing , then updating the foreign key in another entity, the update statement fails as the session seems not to know the new id.

Calling an explicit flush after persists seems to workaround the problem.
This is a change of behavior from 3.12.3 to 3.13.0

This issue is related with the history of changes of #42400

Expected behavior

No change of behavior. All tests of the reproducer should pass using Quarkus 3.13.x

How to Reproduce?

https://github.com/HerrDerb/quarkus-issue/tree/panache-entitymanager-session-issue
Run tests with 3.13.x -> one will fail

Run tests with 3.12.3 -> all pass

@HerrDerb HerrDerb added the kind/bug Something isn't working label Aug 30, 2024
Copy link

quarkus-bot bot commented Aug 30, 2024

/cc @FroMage (panache), @loicmathieu (panache)

@FroMage
Copy link
Member

FroMage commented Aug 30, 2024

FYI @gsmet @yrodiere

@yrodiere
Copy link
Member

yrodiere commented Aug 30, 2024

Seems similar to #42322. I think this is related to https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.13#auto-flush-optimization

Previously Hibernate ORM in Quarkus was flushing indiscriminately before a query, leading to performance issues, especially compared to pretty much every other framework out there, where that sort of aggressive flushing is opt-in. We changed that to align on the rest of the ecosystem -- and on how Hibernate ORM expects to be used.

Your problem would hint at Hibernate ORM not auto-detecting that a flush is needed -- possibly a limitation of auto-flush, which you could try reporting upstream to get improved detection (with a reproducer based on https://github.com/hibernate/hibernate-test-case-templates/blob/main/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/QuarkusLikeORMUnitTestCase.java, ideally).

EDIT: In the meantime, the easiest workaround would be to add an explicit flush, of course.

EDIT2: Second workaround to revert to the old behavior in 3.12 (and accept the performance hit that was present then, throughout your entire application):

    // Put this in an `@ApplicationScoped` bean somewhere.
    void onBeginTransaction(@Observes @Initialized(TransactionScoped.class) Object event, Session session) {
        session.setHibernateFlushMode(FlushMode.ALWAYS);
    }

@yrodiere yrodiere changed the title Panache update issue since 3.13.0 Update issue since 3.13.0 Aug 30, 2024
@yrodiere yrodiere added area/hibernate-orm Hibernate ORM and removed area/panache labels Aug 30, 2024
@yrodiere yrodiere changed the title Update issue since 3.13.0 Hibernate ORM update issue since 3.13.0 Aug 30, 2024
@FroMage
Copy link
Member

FroMage commented Aug 30, 2024

Thanks a lot @yrodiere :)

@yrodiere
Copy link
Member

yrodiere commented Sep 3, 2024

Created https://hibernate.atlassian.net/browse/HHH-18559 upstream, let's see how that goes.

@HerrDerb
Copy link
Contributor Author

HerrDerb commented Sep 3, 2024

Thanks for you effort 👌😊

@yrodiere
Copy link
Member

yrodiere commented Sep 4, 2024

So. HHH-18559 was deemed "not a bug" as it seems in this particular case, auto-flush was not designed to help. Hence, this is unlikely to get fixed in Hibernate ORM 6.6 and Quarkus 3.13/3.14/3.15.

Now, there is still hope, since the Hibernate team is discussing HHH-18563 and may end up implementing it in a future version of Hibernate ORM, assuming there are no major downsides.

In the meantime, I will close this, as it's not -- technically -- a bug: the previous behavior was unintended.

Reminder of workarounds for anyone ending up here:

  1. add an explicit flush before your query
  2. OR set the flush mode on your query using .setHibernateFlushMode(FlushMode.ALWAYS) / .setHint(AvailableHints.HINT_FLUSH_MODE, FlushMode.ALWAYS) -- or with Panache, withHint(AvailableHints.HINT_FLUSH_MODE, FlushMode.ALWAYS)
  3. OR set the flush mode on your session using Session#setHibernateFlushMode
  4. OR revert to the old behavior in Quarkus 3.12 (and accept the performance hit that was present then, throughout your entire application):
    // Put this in an `@ApplicationScoped` bean somewhere.
    void onBeginTransaction(@Observes @Initialized(TransactionScoped.class) Object event, Session session) {
        session.setHibernateFlushMode(FlushMode.ALWAYS);
    }

@yrodiere yrodiere closed this as not planned Won't fix, can't repro, duplicate, stale Sep 4, 2024
@cthiebault
Copy link

Thanks for the hints @yrodiere !

I also have some issues with the new flush mode, so I tried to revert to the old behavior but I have exatly the same issues, so I imagine it didn't change the way the sessions are flushed.

Here is my code:

@ApplicationScoped
class HibernateFlushModeConfig {

  fun onBeginTransaction(@Observes @Initialized(TransactionScoped::class) event: Any, session: Session) {
    session.hibernateFlushMode = FlushMode.ALWAYS
  }

}

@yrodiere
Copy link
Member

yrodiere commented Sep 5, 2024

@cthiebault Right, I didn't test this, just provided the workaround to someone else a while ago and got no answer, so I assumed there was no problem... maybe there is.

My first suspicion would be Kotlin, but if you checked that the bean indeed gets executed... there's probably a timing issue.

Debugging session.setHibernateFlushMode() might help: you should be going through io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession#setHibernateFlushMode at some point, and in that method the acquireSession method should go through the isInTransaction() block. If not, then the event handler is probably getting executed too early, or something like this.

You can probably try something like this?

quarkus.hibernate-orm.unsupported-properties."org.hibernate.flushMode"=ALWAYS

@cthiebault
Copy link

Debugging  io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession#setHibernateFlushMode, I see that you are right with your 2 approaches @yrodiere:

  • your code snippet works... even mine in Kotlin ;-)
  • the setting in the application.properties also set the flush mode

But even with this, I get some org.hibernate.FetchNotFoundException with Quarkus 3.14.2 & FlushMode.ALWAYS  and it's working fine with Quarkus 3.12.3.

@yrodiere
Copy link
Member

yrodiere commented Sep 6, 2024

But even with this, I get some org.hibernate.FetchNotFoundException with Quarkus 3.14.2 & FlushMode.ALWAYS and it's working fine with Quarkus 3.12.3.

Then this is probably a different problem... possibly one in Hibernate ORM... and we'll need a reproducer and report. Ideally directly in Hibernate ORM 's Jira instance if you manage to write a reproducer based on https://github.com/hibernate/hibernate-test-case-templates/blob/main/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/QuarkusLikeORMUnitTestCase.java.

Thanks in advance :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/hibernate-orm Hibernate ORM kind/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants