Skip to content

Conversation

yrodiere
Copy link
Member

@yrodiere yrodiere commented Jul 4, 2025

Draft for now.

To do:

  • Implement basic functionality for Hibernate ORM/Reactive
  • Run basic tests locally for Hibernate ORM/Reactive
  • Handle FIXME in the code about initialization (one-by-one vs. parallel threads)
  • Handle FIXME in the code about Panache
  • Run the whole test suite and not just a few tests in the ORM extension
  • Handle Hibernate Envers
  • Handle Hibernate Search
  • Handle Hibernate Validator (remove JPATraversableResolver if ORM deactivated?) => Bad idea, this would be complex to implement, and also to use (if entity types are used outside of PUs, why should the PU active/inactive status matter?
  • Update documentation
  • Write migration guide entry

Migration guide entry:

== Hibernate ORM

[[hibernate-orm-inactive-fail-fast]]
=== Hibernate ORM usage fails fast if persistence unit is deactivated

In previous versions of Quarkus, when the persistence unit was deactivated (`quarkus.hibernate-orm.active=false`), the application would be allowed to start successfully, but could fail much later upon first access to a Hibernate bean (`EntityManager`, `Session`, `SessionFactory`, ...).

Starting with this version of Quarkus, persistence units that are deactivated will lead to a startup failure if Quarkus can detect they are used:

* Static CDI injection points involving the persistence unit (`@Inject Session session`, `@Inject SessionFactory sessionFactory`, ...) will cause application startup to fail with an explicit, actionable message.
* Dynamic retrieval of the persistence unit (e.g. through `CDI.getBeanContainer()`/`Arc.instance()`, or by injecting an `Instance<Session>`) will not be detected on startup, but will cause an exception to be thrown with an explicit, actionable message.

The <<hibernate-reactive-inactive-fail-fast,Hibernate Reactive>> and <<hibernate-search-inactive-fail-fast,Hibernate Search>> extensions implement a similar behavior for their `Mutiny.SessionFactory`/`SearchSession`/`SearchMapping` CDI beans.

If your application needs to inject a `EntityManager/`Session`/`EntityManagerFactory`/`SessionFactory` or related bean for a persistence unit that can potentially be deactivated or have no URL, you may encounter a startup failure similar to this:

```
io.quarkus.arc.InactiveBeanException: Bean is not active: SYNTHETIC bean [class=org.hibernate.Session, id=QdxvhYUzh5cgfepxgL43K9-OFvU]
Reason: Persistence unit '<default>' was deactivated through configuration properties. To activate the persistence unit, set configuration property 'quarkus.hibernate-orm.active' to 'true' and configure datasource '<default>'. Refer to https://quarkus.io/guides/datasource for guidance.
To avoid this exception while keeping the bean inactive:
	- Configure all extensions consuming this bean as inactive as well, if they allow it, e.g. 'quarkus.someextension.active=false'
	- Make sure that custom code only accesses this bean if it is active
	- Inject the bean with 'Instance<org.hibernate.Session>' instead of 'org.hibernate.Session'
This bean is injected into:
	- io.quarkus.hibernate.orm.config.ConfigActiveFalseStaticInjectionTest$MyBean#session
[...]
```

To avoid this failure, follow the instructions in the exception message.
In particular, consider injecting the problematic bean as an `InjectableInstance` (for example `@Inject InjectableInstance<Session> session`) instead.
You can check whether that bean is active using `.getHandle().getBean().isActive().result()` on the `InjectableInstance`, and retrieve the bean instance using `InjectableInstance#get()`.
See https://quarkus.io/guides/hibernate-orm#persistence-unit-active for an example of such a setup for `Session`.

== Hibernate Reactive

[[hibernate-reactive-inactive-fail-fast]]
=== Hibernate Reactive usage fails fast if persistence unit is deactivated

Starting with this version of Quarkus, Hibernate Reactive persistence units that are deactivated will lead to a startup failure if Quarkus can detect they are used.

See the <<hibernate-orm-inactive-fail-fast,datasources,similar migration guide entry for Hibernate ORM>> for more information.

== Hibernate Search

[[hibernate-search-inactive-fail-fast]]
=== Hibernate Search usage fails fast if persistence unit is deactivated

Starting with this version of Quarkus, Hibernate Search mappings that are deactivated will lead to a startup failure if Quarkus can detect they are used.

See the <<hibernate-orm-inactive-fail-fast,datasources,similar migration guide entry for Hibernate ORM>> for more information.

@quarkus-bot quarkus-bot bot added area/hibernate-orm Hibernate ORM area/hibernate-reactive Hibernate Reactive labels Jul 4, 2025
Copy link

quarkus-bot bot commented Jul 4, 2025

/cc @gsmet (hibernate-orm)

Copy link

github-actions bot commented Jul 4, 2025

🎊 PR Preview 28074c2 has been successfully built and deployed to https://quarkus-pr-main-48783-preview.surge.sh/version/main/guides/

  • Images of blog posts older than 3 months are not available.
  • Newsletters older than 3 months are not available.

@yrodiere yrodiere force-pushed the i43594 branch 4 times, most recently from 36159d4 to ee161f6 Compare July 28, 2025 11:55
@quarkus-bot quarkus-bot bot added area/docstyle issues related for manual docstyle review area/documentation labels Jul 28, 2025
@yrodiere yrodiere force-pushed the i43594 branch 2 times, most recently from 328bc46 to ef96914 Compare July 28, 2025 14:30
@yrodiere
Copy link
Member Author

Hey @Sanne I remember discussing this with you: silently deactivating the PU when the datasource has no URL and proceeding with startup if the PU beans (session, session factory, ...) are not injected anywhere. I remember you had some conceerns, probably because this would be a very breaking change and/or simply inconvenient behavior.

Well, if that was your opinion, I'm starting to think like you. For example in the Panache case, where the session might not even be injected anywhere, this would be pretty bad.

So, I'm rolling this back a bit: I'll only silently deactivate the PU if there are no entity types in the PU (which we intend to make possible through #48732). In that case it's likely that Hibernate ORM is being used as a simple wrapper of JDBC with more convenient querying capabilities (with projections, ...), so I think it makes more sense.

This means in the vast majority of cases we'll get pretty much the same behavior as today, so it's much safer, too.

This comment has been minimized.

@yrodiere
Copy link
Member Author

yrodiere commented Sep 11, 2025

Hey @marko-bekhta or @lucamolteni can I please ask one of you review this? If you skip the first commit it's almost a reasonable amount of code (and the vast majority is just tests that look very similar).

EDIT: No need for both of you to review of course :)

Copy link
Contributor

@marko-bekhta marko-bekhta left a comment

Choose a reason for hiding this comment

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

Thanks! Looks nice 😃 🎉

I had some questions, but feel free to ignore those 😄


if (isDefaultPersistenceUnit) {
if (PersistenceUnitUtil.isDefaultPersistenceUnit(persistenceUnitName)) {
configurator.addQualifier(Default.class);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

for Search we always add the named qualifiers (just below) and for ORM those seem to be conditional, I wonder if we should be consistent 🤔

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 would like to, and if so I'd change what we do in ORM, but that seems out of scope. Want to create an issue?

Copy link
Member Author

@yrodiere yrodiere left a comment

Choose a reason for hiding this comment

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

I addressed your comments @marko-bekhta , thank you!

* Dynamic retrieval of the persistence unit, such as through `CDI.getBeanContainer()`, `Arc.instance()`, or by injecting an `Instance<Session>`, causes an exception to be thrown.
* Other Quarkus extensions that consume the persistence unit may cause application startup to fail.
+
In this case, you must also deactivate those other extensions.
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 added a small bit of documentation. Should be enough for now?


if (isDefaultPersistenceUnit) {
if (PersistenceUnitUtil.isDefaultPersistenceUnit(persistenceUnitName)) {
configurator.addQualifier(Default.class);
}
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 would like to, and if so I'd change what we do in ORM, but that seems out of scope. Want to create an issue?

Copy link

quarkus-bot bot commented Sep 11, 2025

Status for workflow Quarkus Documentation CI

This is the status report for running Quarkus Documentation CI on commit e5cc8a6.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

Warning

There are other workflow runs running, you probably need to wait for their status before merging.

@yrodiere yrodiere removed the request for review from lucamolteni September 11, 2025 12:38
Copy link

quarkus-bot bot commented Sep 11, 2025

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit e5cc8a6.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

@yrodiere
Copy link
Member Author

We're good to go, I just need an approval from someone with push access... @Sanne would you please do that? @marko-bekhta reviewed already and (I think) is happy :)

@lucamolteni
Copy link
Contributor

Hey @marko-bekhta or @lucamolteni can I please ask one of you review this? If you skip the first commit it's almost a reasonable amount of code (and the vast majority is just tests that look very similar).

EDIT: No need for both of you to review of course :)

Impressive changes thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/docstyle issues related for manual docstyle review area/documentation area/hibernate-orm Hibernate ORM area/hibernate-reactive Hibernate Reactive area/hibernate-search Hibernate Search area/panache
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use Arc features in Hibernate extensions for eager startup and active/inactive
3 participants