Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2332,6 +2332,11 @@
<artifactId>quarkus-reactive-datasource-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-datasource-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-db2-client</artifactId>
Expand Down
4 changes: 4 additions & 0 deletions extensions/hibernate-orm/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator-spi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-datasource-spi</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.quarkus.hibernate.orm.deployment;

import java.util.List;
import java.util.Optional;
import java.util.function.Function;

import io.quarkus.hibernate.orm.runtime.PersistenceUnitUtil;

public class HibernateDataSourceUtil {
public static <T> Optional<T> findDataSourceWithNameDefault(String persistenceUnitName,
List<T> datasSources,
Function<T, String> nameExtractor,
Function<T, Boolean> defaultExtractor,
Optional<String> datasource) {
if (datasource.isPresent()) {
String dataSourceName = datasource.get();
return datasSources.stream()
.filter(i -> dataSourceName.equals(nameExtractor.apply(i)))
.findFirst();
} else if (PersistenceUnitUtil.isDefaultPersistenceUnit(persistenceUnitName)) {
return datasSources.stream()
.filter(i -> defaultExtractor.apply(i))
.findFirst();
} else {
// if it's not the default persistence unit, we mandate an explicit datasource to prevent common errors
return Optional.empty();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static io.quarkus.hibernate.orm.deployment.util.HibernateProcessorUtil.jsonMapperKind;
import static io.quarkus.hibernate.orm.deployment.util.HibernateProcessorUtil.setDialectAndStorageEngine;
import static io.quarkus.hibernate.orm.deployment.util.HibernateProcessorUtil.xmlMapperKind;
import static io.quarkus.hibernate.orm.runtime.PersistenceUnitUtil.DEFAULT_PERSISTENCE_UNIT_NAME;

import java.io.IOException;
import java.net.URL;
Expand Down Expand Up @@ -144,6 +145,7 @@
import io.quarkus.hibernate.validator.spi.BeanValidationTraversableResolverBuildItem;
import io.quarkus.panache.hibernate.common.deployment.HibernateEnhancersRegisteredBuildItem;
import io.quarkus.panache.hibernate.common.deployment.HibernateModelClassCandidatesForFieldAccessBuildItem;
import io.quarkus.reactive.datasource.spi.ReactiveDataSourceBuildItem;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.configuration.ConfigurationException;
import net.bytebuddy.description.type.TypeDescription;
Expand Down Expand Up @@ -327,6 +329,7 @@ public void configurationDescriptorBuilding(
ImpliedBlockingPersistenceUnitTypeBuildItem impliedPU,
List<PersistenceXmlDescriptorBuildItem> persistenceXmlDescriptors,
List<JdbcDataSourceBuildItem> jdbcDataSources,
List<ReactiveDataSourceBuildItem> reactiveDataSources,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
LaunchModeBuildItem launchMode,
List<AdditionalJpaModelBuildItem> additionalJpaModelBuildItems,
Expand Down Expand Up @@ -380,7 +383,8 @@ public void configurationDescriptorBuilding(

if (impliedPU.shouldGenerateImpliedBlockingPersistenceUnit()) {
handleHibernateORMWithNoPersistenceXml(hibernateOrmConfig, index, persistenceXmlDescriptors,
jdbcDataSources, applicationArchivesBuildItem, launchMode.getLaunchMode(), additionalJpaModelBuildItems,
jdbcDataSources, reactiveDataSources, applicationArchivesBuildItem, launchMode.getLaunchMode(),
additionalJpaModelBuildItems,
jpaModel, capabilities,
systemProperties, nativeImageResources, hotDeploymentWatchedFiles, persistenceUnitDescriptors,
reflectiveMethods, unremovableBeans, dbKindMetadataBuildItems);
Expand Down Expand Up @@ -842,6 +846,7 @@ private void handleHibernateORMWithNoPersistenceXml(
CombinedIndexBuildItem index,
List<PersistenceXmlDescriptorBuildItem> descriptors,
List<JdbcDataSourceBuildItem> jdbcDataSources,
List<ReactiveDataSourceBuildItem> reactiveDataSources,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
LaunchMode launchMode,
List<AdditionalJpaModelBuildItem> additionalJpaModelBuildItems,
Expand Down Expand Up @@ -907,7 +912,7 @@ private void handleHibernateORMWithNoPersistenceXml(
hibernateOrmConfig.defaultPersistenceUnit(),
modelForDefaultPersistenceUnit.allModelClassAndPackageNames(),
jpaModel.getXmlMappings(PersistenceUnitUtil.DEFAULT_PERSISTENCE_UNIT_NAME),
jdbcDataSources, applicationArchivesBuildItem, launchMode, capabilities,
jdbcDataSources, reactiveDataSources, applicationArchivesBuildItem, launchMode, capabilities,
systemProperties, nativeImageResources, hotDeploymentWatchedFiles, persistenceUnitDescriptors,
reflectiveMethods, unremovableBeans, storageEngineCollector, dbKindMetadataBuildItems);
} else if (!modelForDefaultPersistenceUnit.entityClassNames().isEmpty()
Expand Down Expand Up @@ -939,7 +944,7 @@ private void handleHibernateORMWithNoPersistenceXml(
hibernateOrmConfig, jpaModel, persistenceUnitName, persistenceUnitEntry.getValue(),
model == null ? Collections.emptySet() : model.allModelClassAndPackageNames(),
jpaModel.getXmlMappings(persistenceUnitName),
jdbcDataSources, applicationArchivesBuildItem, launchMode, capabilities,
jdbcDataSources, reactiveDataSources, applicationArchivesBuildItem, launchMode, capabilities,
systemProperties, nativeImageResources, hotDeploymentWatchedFiles, persistenceUnitDescriptors,
reflectiveMethods, unremovableBeans, storageEngineCollector, dbKindMetadataBuildItems);
}
Expand All @@ -957,6 +962,7 @@ private static void producePersistenceUnitDescriptorFromConfig(
Set<String> modelClassesAndPackages,
List<RecordableXmlMapping> xmlMappings,
List<JdbcDataSourceBuildItem> jdbcDataSources,
List<ReactiveDataSourceBuildItem> reactiveDataSources,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
LaunchMode launchMode,
Capabilities capabilities,
Expand All @@ -968,8 +974,32 @@ private static void producePersistenceUnitDescriptorFromConfig(
BuildProducer<UnremovableBeanBuildItem> unremovableBeans,
Set<String> storageEngineCollector,
List<DatabaseKindDialectBuildItem> dbKindMetadataBuildItems) {
Optional<JdbcDataSourceBuildItem> jdbcDataSource = findJdbcDataSource(persistenceUnitName, persistenceUnitConfig,
jdbcDataSources);

Optional<JdbcDataSourceBuildItem> jdbcDataSource = HibernateDataSourceUtil.findDataSourceWithNameDefault(
persistenceUnitName,
jdbcDataSources,
JdbcDataSourceBuildItem::getName,
JdbcDataSourceBuildItem::isDefault, persistenceUnitConfig.datasource());

Optional<ReactiveDataSourceBuildItem> reactiveDataSource = HibernateDataSourceUtil.findDataSourceWithNameDefault(
persistenceUnitName,
reactiveDataSources,
ReactiveDataSourceBuildItem::getName,
ReactiveDataSourceBuildItem::isDefault, persistenceUnitConfig.datasource());

if (jdbcDataSource.isEmpty() && reactiveDataSource.isPresent()) {
LOG.debugf("The datasource '%s' is only reactive, do not create this PU '%s' as blocking",
persistenceUnitConfig.datasource().orElse(DEFAULT_PERSISTENCE_UNIT_NAME), persistenceUnitName);
return;
}

boolean explicitDataSource = persistenceUnitConfig.datasource().isPresent();
if (jdbcDataSource.isEmpty() && explicitDataSource) {
String dataSourceName = persistenceUnitConfig.datasource().get();
throw PersistenceUnitUtil.unableToFindDataSource(persistenceUnitName, dataSourceName,
DataSourceUtil.dataSourceNotConfigured(dataSourceName));
}

Optional<String> dataSourceName = jdbcDataSource.map(JdbcDataSourceBuildItem::getName);

QuarkusPersistenceUnitDescriptor descriptor = new QuarkusPersistenceUnitDescriptor(
Expand Down Expand Up @@ -1099,25 +1129,6 @@ private static void collectDialectConfigForPersistenceXml(String persistenceUnit
}
}

private static Optional<JdbcDataSourceBuildItem> findJdbcDataSource(String persistenceUnitName,
HibernateOrmConfigPersistenceUnit persistenceUnitConfig, List<JdbcDataSourceBuildItem> jdbcDataSources) {
if (persistenceUnitConfig.datasource().isPresent()) {
String dataSourceName = persistenceUnitConfig.datasource().get();
return Optional.of(jdbcDataSources.stream()
.filter(i -> dataSourceName.equals(i.getName()))
.findFirst()
.orElseThrow(() -> PersistenceUnitUtil.unableToFindDataSource(persistenceUnitName, dataSourceName,
DataSourceUtil.dataSourceNotConfigured(dataSourceName))));
} else if (PersistenceUnitUtil.isDefaultPersistenceUnit(persistenceUnitName)) {
return jdbcDataSources.stream()
.filter(i -> i.isDefault())
.findFirst();
} else {
// if it's not the default persistence unit, we mandate an explicit datasource to prevent common errors
return Optional.empty();
}
}

@SuppressWarnings("deprecation")
private void enhanceEntities(final JpaModelBuildItem jpaModel,
BuildProducer<BytecodeTransformerBuildItem> transformers,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
import java.util.logging.Level;

import jakarta.persistence.PersistenceUnitTransactionType;
Expand Down Expand Up @@ -49,6 +48,7 @@
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.hibernate.orm.deployment.HibernateDataSourceUtil;
import io.quarkus.hibernate.orm.deployment.HibernateOrmConfig;
import io.quarkus.hibernate.orm.deployment.HibernateOrmConfigPersistenceUnit;
import io.quarkus.hibernate.orm.deployment.HibernateOrmProcessor;
Expand Down Expand Up @@ -189,27 +189,27 @@ private static void producePersistenceUnitFromConfig(HibernateOrmConfig hibernat
BuildProducer<PersistenceUnitDescriptorBuildItem> persistenceUnitDescriptors,
BuildProducer<UnremovableBeanBuildItem> unremovableBeans,
List<DatabaseKindDialectBuildItem> dbKindDialectBuildItems) {
boolean datasourceNamed = persistenceUnitConfig.datasource().isPresent();

Optional<JdbcDataSourceBuildItem> jdbcDataSource = findDataSourceWithNameDefault(persistenceUnitName,
persistenceUnitConfig,
Optional<JdbcDataSourceBuildItem> jdbcDataSource = HibernateDataSourceUtil.findDataSourceWithNameDefault(
persistenceUnitName,
jdbcDataSources,
JdbcDataSourceBuildItem::getName,
JdbcDataSourceBuildItem::isDefault);
JdbcDataSourceBuildItem::isDefault, persistenceUnitConfig.datasource());

Optional<ReactiveDataSourceBuildItem> reactiveDataSource = findDataSourceWithNameDefault(persistenceUnitName,
persistenceUnitConfig,
Optional<ReactiveDataSourceBuildItem> reactiveDataSource = HibernateDataSourceUtil.findDataSourceWithNameDefault(
persistenceUnitName,
reactiveDataSources,
ReactiveDataSourceBuildItem::getName,
ReactiveDataSourceBuildItem::isDefault);
ReactiveDataSourceBuildItem::isDefault, persistenceUnitConfig.datasource());

if (jdbcDataSource.isPresent() && reactiveDataSource.isEmpty() && datasourceNamed) {
LOG.debugf("The datasource '%s' is blocking, do not create this PU '%s' as reactive",
persistenceUnitConfig.datasource().get(), persistenceUnitName);
boolean explicitDataSource = persistenceUnitConfig.datasource().isPresent();
if (jdbcDataSource.isPresent() && reactiveDataSource.isEmpty()) {
LOG.debugf("The datasource '%s' is only blocking, do not create this PU '%s' as reactive",
persistenceUnitConfig.datasource().orElse(DEFAULT_PERSISTENCE_UNIT_NAME), persistenceUnitName);
return;
}

if (jdbcDataSource.isEmpty() && reactiveDataSource.isEmpty() && datasourceNamed) {
if (reactiveDataSource.isEmpty() && explicitDataSource) {
String dataSourceName = persistenceUnitConfig.datasource().get();
throw PersistenceUnitUtil.unableToFindDataSource(persistenceUnitName, dataSourceName,
DataSourceUtil.dataSourceNotConfigured(dataSourceName));
Expand Down Expand Up @@ -271,25 +271,6 @@ private static void producePersistenceUnitFromConfig(HibernateOrmConfig hibernat
isHibernateValidatorPresent(capabilities), jsonMapper, xmlMapper));
}

private static <T> Optional<T> findDataSourceWithNameDefault(String persistenceUnitName,
HibernateOrmConfigPersistenceUnit persistenceUnitConfig,
List<T> datasSources,
Function<T, String> nameExtractor, Function<T, Boolean> defaultExtractor) {
if (persistenceUnitConfig.datasource().isPresent()) {
String dataSourceName = persistenceUnitConfig.datasource().get();
return datasSources.stream()
.filter(i -> dataSourceName.equals(nameExtractor.apply(i)))
.findFirst();
} else if (PersistenceUnitUtil.isDefaultPersistenceUnit(persistenceUnitName)) {
return datasSources.stream()
.filter(i -> defaultExtractor.apply(i))
.findFirst();
} else {
// if it's not the default persistence unit, we mandate an explicit datasource to prevent common errors
return Optional.empty();
}
}

@BuildStep
@Consume(VertxPoolBuildItem.class)
void waitForVertxPool(List<PersistenceUnitDescriptorBuildItem> persistenceUnitDescriptorBuildItems,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ public class ORMReactiveCompatbilityDifferentNamedDataSourceNamedPersistenceUnit
.setForcedDependencies(List.of(
Dependency.of("io.quarkus", "quarkus-jdbc-postgresql-deployment", Version.getVersion()) // this triggers Agroal
))
.withConfigurationResource("application-unittest-both-named.properties")
.withConfigurationResource("application-unittest-both-named-different.properties")

// Reactive named datasource
.overrideConfigKey("quarkus.datasource.\"named-datasource-reactive\".jdbc", "false")
.overrideConfigKey("quarkus.datasource.\"named-datasource-reactive\".reactive", "true")
.overrideConfigKey("quarkus.datasource.\"named-datasource-reactive\".db-kind", POSTGRES_KIND)
.overrideConfigKey("quarkus.datasource.\"named-datasource-reactive\".username", USERNAME_PWD)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.quarkus.hibernate.reactive.compatibility;

import java.util.List;

import org.hibernate.reactive.mutiny.Mutiny;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.builder.Version;
import io.quarkus.hibernate.orm.PersistenceUnit;
import io.quarkus.hibernate.reactive.entities.Hero;
import io.quarkus.maven.dependency.Dependency;
import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.test.vertx.RunOnVertxContext;
import io.quarkus.test.vertx.UniAsserter;

public class ORMReactiveCompatibilityNamedReactiveDefaultBlockingUnitTest extends CompatibilityUnitTestBase {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(Hero.class)
.addAsResource("complexMultilineImports.sql", "import.sql"))
.setForcedDependencies(List.of(
Dependency.of("io.quarkus", "quarkus-jdbc-postgresql-deployment", Version.getVersion()) // this triggers Agroal
))
.withConfigurationResource("application-unittest-both-named-reactive-and-default-blocking.properties")
// If we want the named PU to be reactive only we need to explicitly disable the blocking the JDBC data source
.overrideConfigKey("quarkus.datasource.\"named-datasource\".jdbc", "false")
.overrideConfigKey("quarkus.datasource.\"named-datasource\".reactive", "true")
.overrideConfigKey("quarkus.hibernate-orm.\"named-pu\".schema-management.strategy", SCHEMA_MANAGEMENT_STRATEGY)
.overrideConfigKey("quarkus.hibernate-orm.\"named-pu\".datasource", "named-datasource")
.overrideConfigKey("quarkus.hibernate-orm.\"named-pu\".packages", "io.quarkus.hibernate.reactive.entities")
.overrideConfigKey("quarkus.datasource.\"named-datasource\".db-kind", POSTGRES_KIND)
.overrideConfigKey("quarkus.datasource.\"named-datasource\".username", USERNAME_PWD)
.overrideConfigKey("quarkus.datasource.\"named-datasource\".password", USERNAME_PWD)

// In this test we want the default PU as blocking only, so we need to disable reactive on the datasource.
// JDBC is enabled by default.
.overrideConfigKey("quarkus.datasource.reactive", "false")
// In this case packages for the default PU should be explicit as well
.overrideConfigKey("quarkus.hibernate-orm.packages", "io.quarkus.hibernate.reactive.entities")
.overrideConfigKey("quarkus.datasource.username", USERNAME_PWD)
.overrideConfigKey("quarkus.datasource.password", USERNAME_PWD)
.overrideConfigKey("quarkus.datasource.db-kind", POSTGRES_KIND)
.overrideConfigKey("quarkus.log.category.\"io.quarkus.hibernate\".level", "DEBUG");

@PersistenceUnit("named-pu")
Mutiny.SessionFactory namedMutinySessionFactory;

@Test
@RunOnVertxContext
public void test(UniAsserter uniAsserter) {
testReactiveWorks(namedMutinySessionFactory, uniAsserter);
}

@Test
public void testBlocking() {
testBlockingWorks();
}
}
Loading
Loading