Skip to content

Commit 6db69c8

Browse files
authored
Merge pull request quarkusio#48783 from yrodiere/i43594
Use Arc features in Hibernate extensions for eager startup and active/inactive
2 parents 12292ec + e5cc8a6 commit 6db69c8

File tree

77 files changed

+5468
-644
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+5468
-644
lines changed

docs/src/main/asciidoc/datasource.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,11 +450,11 @@ If a datasource is not active:
450450
* The datasource does not attempt to connect to the database during application startup.
451451
* The datasource does not contribute a <<datasource-health-check,health check>>.
452452
* Static CDI injection points involving the datasource, such as `@Inject DataSource ds` or `@Inject Pool pool`, cause application startup to fail.
453-
* Dynamic retrieval of the datasource, such as through `CDI.getBeanContainer()`, `Arc.instance()`, or by injecting an `Instance<DataSource>`, causes an exception to be thrown.
453+
* Dynamic retrieval of the datasource, such as through `CDI.getBeanContainer()`, `Arc.instance()`, or an injected `Instance<DataSource>`, causes an exception to be thrown.
454454
* Other Quarkus extensions that consume the datasource may cause application startup to fail.
455455
+
456456
In this case, you must also deactivate those other extensions.
457-
To see an example of this scenario, refer to xref:hibernate-orm.adoc#persistence-unit-active[this section of the Hibernate ORM guide].
457+
To see an example of this scenario, refer to xref:hibernate-orm.adoc#persistence-unit-active[this section of the Hibernate ORM guide]. For Hibernate ORM, deactivation of the persistence unit is automatic when the datasource is inactive.
458458

459459
This feature is especially useful when the application must select one datasource from a predefined set at runtime.
460460

docs/src/main/asciidoc/hibernate-orm.adoc

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -543,15 +543,19 @@ CriteriaBuilder criteriaBuilder;
543543
[[persistence-unit-active]]
544544
=== Activate/deactivate persistence units
545545

546-
If a persistence unit is configured at build time,
547-
by default it is active at runtime,
548-
that is Quarkus will start the corresponding Hibernate ORM `SessionFactory` on application startup.
546+
When a persistence unit is configured at build time, the persistence unit is active by default.
547+
Quarkus starts the corresponding Hibernate ORM `SessionFactory` when the application starts.
549548

550549
To deactivate a persistence unit at runtime, set `quarkus.hibernate-orm[.optional name].active` to `false`.
550+
551551
If a persistence unit is not active:
552552

553-
* The `SessionFactory` will not start during application startup.
554-
* Accessing the `EntityManagerFactory`/`EntityManager` or `SessionFactory`/`Session` will cause an exception to be thrown.
553+
* The `SessionFactory` does not start during application startup.
554+
* Static CDI injection points involving the persistence unit, such as `@Inject SessionFactory sf` or `@Inject Session session`, cause application startup to fail.
555+
* Dynamic retrieval of the persistence unit, such as through `CDI.getBeanContainer()`, `Arc.instance()`, or an injected `Instance<Session>`, causes an exception to be thrown.
556+
* Other Quarkus extensions that consume the persistence unit may cause application startup to fail.
557+
+
558+
In this case, you must also deactivate those other extensions.
555559

556560
This is in particular useful when you want an application to be able
557561
to xref:datasource.adoc#datasource-active[use one of a pre-determined set of datasources at runtime].
@@ -598,41 +602,53 @@ xref:config-reference.adoc#multiple-profiles[setting `quarkus.profile`]:
598602
599603
%oracle.quarkus.hibernate-orm."oracle".active=true
600604
%oracle.quarkus.datasource."oracle".active=true
601-
# Add any pg-related runtime configuration here, prefixed with "%pg."
605+
# Add any oracle-related runtime configuration here, prefixed with "%oracle."
602606
----
603607
====
604608

605-
With such a setup, you will need to take care to only ever access the _active_ persistence unit.
606-
To do so, you may define a xref:cdi.adoc#ok-you-said-that-there-are-several-kinds-of-beans[CDI bean producer] for the default `Session` redirecting to the currently active named `Session`, so that it can be injected directly, like this:
609+
With this setup, ensure that only the _active_ persistence unit is accessed.
610+
To achieve this, inject an `InjectableInstance<SessionFactory>` or `InjectableInstance<Session>` with an `@Any` qualifier and call xref:cdi-integration.adoc#inactive-synthetic-beans[`getActive()`].
607611

608-
[source,java,indent=0]
612+
[source,java]
609613
----
610-
public class MyProducer {
614+
import io.quarkus.arc.InjectableInstance;
615+
@ApplicationScoped
616+
public class MyConsumer {
611617
@Inject
612-
@DataSource("pg")
613-
InjectableInstance<AgroalDataSource> pgDataSourceBean; // <1>
618+
@Any
619+
InjectableInstance<Session> session;
614620
615-
@Inject
616-
@DataSource("oracle")
617-
InjectableInstance<AgroalDataSource> oracleDataSourceBean;
621+
public void doSomething() {
622+
Session sessionForActivePersistenceUnit = session.getActive();
623+
// ...
624+
}
625+
}
626+
----
618627

628+
Alternatively, you can define a xref:cdi.adoc#ok-you-said-that-there-are-several-kinds-of-beans[CDI bean producer] for the beans of the default persistence unit.
629+
This bean producer redirects to the currently active named persistence unit.
630+
This allows beans to be injected directly, as shown below:
631+
632+
[source,java,indent=0]
633+
----
634+
public class MyProducer {
619635
@Inject
620636
@PersistenceUnit("pg")
621-
Session pgSessionBean;
637+
InjectableInstance<Session> pgSessionBean; // <1>
622638
623639
@Inject
624640
@PersistenceUnit("oracle")
625-
Session oracleSessionBean;
641+
InjectableInstance<Session> oracleSessionBean;
626642
627643
@Produces // <2>
628644
@ApplicationScoped
629645
public Session session() {
630-
if (pgDataSourceBean.getHandle().getBean().isActive()) { // <3>
631-
return pgSessionBean;
632-
} else if (oracleDataSourceBean.getHandle().getBean().isActive()) { // <3>
633-
return oracleSessionBean;
646+
if (pgSessionBean.getHandle().getBean().isActive()) { // <3>
647+
return pgSessionBean.get();
648+
} else if (oracleSessionBean.getHandle().getBean().isActive()) { // <3>
649+
return oracleSessionBean.get();
634650
} else {
635-
throw new RuntimeException("No active datasource!");
651+
throw new RuntimeException("No active persistence unit!");
636652
}
637653
}
638654
}
@@ -647,13 +663,13 @@ public class MyConsumer {
647663
}
648664
}
649665
----
650-
<1> Don't inject a `DataSource` or `AgroalDatasource` directly,
651-
because that would lead to a failure on startup (can't inject inactive beans).
652-
Instead, inject `InjectableInstance<DataSource>` or `InjectableInstance<AgroalDataSource>`.
653-
<2> Declare a CDI producer method that will define the default session
654-
as either PostgreSQL or Oracle, depending on what is active.
655-
<3> Check whether datasource beans are active before retrieving the corresponding session.
656-
<4> This will get injected with the (only) active session.
666+
<1> Do not inject a `Session` directly.
667+
Injecting inactive beans causes a startup failure.
668+
Instead, inject `InjectableInstance<Session>`.
669+
<2> Declare a CDI producer method to define the default session.
670+
It selects either PostgreSQL or Oracle, depending on which persistence unit is active.
671+
<3> Check if a bean is active before retrieving it.
672+
<4> Injects the only active persistence unit.
657673

658674
[[persistence-xml]]
659675
== Setting up and configuring Hibernate ORM with a `persistence.xml`

0 commit comments

Comments
 (0)