Skip to content

Commit

Permalink
Merge pull request #11519 from gsmet/multi-persistence-units-follow-up
Browse files Browse the repository at this point in the history
Multiple persistence units follow up
  • Loading branch information
gsmet authored Aug 26, 2020
2 parents 09496dd + 140dfcf commit dcf945f
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
Expand All @@ -26,6 +27,7 @@

import javax.inject.Singleton;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.metamodel.StaticMetamodel;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.transaction.TransactionManager;
Expand Down Expand Up @@ -136,7 +138,9 @@ CapabilityBuildItem capability() {

@BuildStep
void checkTransactionsSupport(Capabilities capabilities) {
if (capabilities.isMissing(Capability.TRANSACTIONS)) {
// JTA is necessary for blocking Hibernate ORM but not necessarily for Hibernate Reactive
if (capabilities.isMissing(Capability.TRANSACTIONS)
&& capabilities.isMissing(Capability.HIBERNATE_REACTIVE)) {
throw new ConfigurationException("The Hibernate ORM extension is only functional in a JTA environment.");
}
}
Expand Down Expand Up @@ -236,6 +240,7 @@ public void configurationDescriptorBuilding(
LaunchModeBuildItem launchMode,
JpaEntitiesBuildItem jpaEntities,
List<NonJpaModelBuildItem> nonJpaModelBuildItems,
Capabilities capabilities,
BuildProducer<SystemPropertyBuildItem> systemProperties,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFiles,
Expand All @@ -255,7 +260,7 @@ public void configurationDescriptorBuilding(

if (impliedPU.shouldGenerateImpliedBlockingPersistenceUnit()) {
handleHibernateORMWithNoPersistenceXml(hibernateOrmConfig, persistenceXmlDescriptors,
jdbcDataSources, applicationArchivesBuildItem, launchMode.getLaunchMode(), jpaEntities,
jdbcDataSources, applicationArchivesBuildItem, launchMode.getLaunchMode(), jpaEntities, capabilities,
systemProperties, nativeImageResources, hotDeploymentWatchedFiles, persistenceUnitDescriptors);
}
}
Expand Down Expand Up @@ -528,6 +533,7 @@ private void handleHibernateORMWithNoPersistenceXml(
ApplicationArchivesBuildItem applicationArchivesBuildItem,
LaunchMode launchMode,
JpaEntitiesBuildItem jpaEntities,
Capabilities capabilities,
BuildProducer<SystemPropertyBuildItem> systemProperties,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFiles,
Expand All @@ -550,7 +556,7 @@ private void handleHibernateORMWithNoPersistenceXml(
.filter(i -> i.isDefault())
.findFirst();

Set<Optional<String>> storageEngines = new HashSet<>();
Set<String> storageEngineCollector = new HashSet<>();

if ((defaultJdbcDataSource.isPresent() && hibernateOrmConfig.persistenceUnits.isEmpty()) ||
hibernateOrmConfig.defaultPersistenceUnit.isAnyPropertySet()) {
Expand All @@ -559,24 +565,22 @@ private void handleHibernateORMWithNoPersistenceXml(
hibernateOrmConfig.defaultPersistenceUnit,
modelClassesPerPersistencesUnits.getOrDefault(PersistenceUnitUtil.DEFAULT_PERSISTENCE_UNIT_NAME,
Collections.emptySet()),
jdbcDataSources, applicationArchivesBuildItem, launchMode,
systemProperties, nativeImageResources, hotDeploymentWatchedFiles, persistenceUnitDescriptors);

storageEngines.add(hibernateOrmConfig.defaultPersistenceUnit.dialect.storageEngine);
jdbcDataSources, applicationArchivesBuildItem, launchMode, capabilities,
systemProperties, nativeImageResources, hotDeploymentWatchedFiles, persistenceUnitDescriptors,
storageEngineCollector);
}

for (Entry<String, HibernateOrmConfigPersistenceUnit> persistenceUnitEntry : hibernateOrmConfig.persistenceUnits
.entrySet()) {
producePersistenceUnitDescriptorFromConfig(
hibernateOrmConfig, persistenceUnitEntry.getKey(), persistenceUnitEntry.getValue(),
modelClassesPerPersistencesUnits.getOrDefault(persistenceUnitEntry.getKey(), Collections.emptySet()),
jdbcDataSources, applicationArchivesBuildItem, launchMode,
systemProperties, nativeImageResources, hotDeploymentWatchedFiles, persistenceUnitDescriptors);

storageEngines.add(persistenceUnitEntry.getValue().dialect.storageEngine);
jdbcDataSources, applicationArchivesBuildItem, launchMode, capabilities,
systemProperties, nativeImageResources, hotDeploymentWatchedFiles, persistenceUnitDescriptors,
storageEngineCollector);
}

if (storageEngines.size() > 1) {
if (storageEngineCollector.size() > 1) {
throw new ConfigurationException(
"The dialect storage engine is a global configuration property: it must be consistent across all persistence units.");
}
Expand All @@ -590,10 +594,12 @@ private static void producePersistenceUnitDescriptorFromConfig(
List<JdbcDataSourceBuildItem> jdbcDataSources,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
LaunchMode launchMode,
Capabilities capabilities,
BuildProducer<SystemPropertyBuildItem> systemProperties,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFiles,
BuildProducer<PersistenceUnitDescriptorBuildItem> persistenceUnitDescriptors) {
BuildProducer<PersistenceUnitDescriptorBuildItem> persistenceUnitDescriptors,
Set<String> storageEngineCollector) {
// Find the associated datasource
JdbcDataSourceBuildItem jdbcDataSource;
String dataSource;
Expand Down Expand Up @@ -770,6 +776,17 @@ private static void producePersistenceUnitDescriptorFromConfig(
p.put(JPA_SHARED_CACHE_MODE, SharedCacheMode.NONE);
}

// Hibernate Validator integration: we force the callback mode to have bootstrap errors reported rather than validation ignored
// if there is any issue when bootstrapping Hibernate Validator.
if (capabilities.isPresent(Capability.HIBERNATE_VALIDATOR)) {
descriptor.getProperties().setProperty(AvailableSettings.JPA_VALIDATION_MODE, ValidationMode.CALLBACK.name());
}

// Collect the storage engines if MySQL or MariaDB
if (isMySQLOrMariaDB(dialect.get()) && persistenceUnitConfig.dialect.storageEngine.isPresent()) {
storageEngineCollector.add(persistenceUnitConfig.dialect.storageEngine.get());
}

persistenceUnitDescriptors.produce(
new PersistenceUnitDescriptorBuildItem(descriptor, dataSource,
getMultiTenancyStrategy(hibernateOrmConfig),
Expand Down Expand Up @@ -983,4 +1000,9 @@ private static Class[] toArray(final Set<Class<?>> interfaces) {
}
return interfaces.toArray(new Class[interfaces.size()]);
}

private static boolean isMySQLOrMariaDB(String dialect) {
String lowercaseDialect = dialect.toLowerCase(Locale.ROOT);
return lowercaseDialect.contains("mysql") || lowercaseDialect.contains("mariadb");
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.hibernate.orm.multiplepersistenceunits;

import org.hibernate.dialect.H2Dialect;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Assertions;
Expand Down Expand Up @@ -30,4 +31,10 @@ public void testInvalidConfiguration() {
// deployment exception should happen first
Assertions.fail();
}

/**
* This is just to have the dialect matching MySQL and trigger the MySQL + storage engines check.
*/
public static class H2DialectWithMySQLInTheName extends H2Dialect {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ public class MultiplePersistenceUnitsUndefinedPackagesTest {
.setExpectedException(ConfigurationException.class)
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClass(User.class)
.addAsResource("application-multiple-persistence-units-invalid.properties", "application.properties"));
.addAsResource("application-multiple-persistence-units-undefined-packages.properties",
"application.properties"));

@Test
public void testInvalidConfiguration() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ quarkus.datasource.users.jdbc.url=jdbc:h2:mem:users;DB_CLOSE_DELAY=-1
quarkus.datasource.inventory.db-kind=h2
quarkus.datasource.inventory.jdbc.url=jdbc:h2:mem:inventory;DB_CLOSE_DELAY=-1

quarkus.hibernate-orm.dialect=org.hibernate.dialect.H2Dialect
quarkus.hibernate-orm.dialect=io.quarkus.hibernate.orm.multiplepersistenceunits.MultiplePersistenceUnitsInconsistentStorageEnginesTest$H2DialectWithMySQLInTheName
quarkus.hibernate-orm.dialect.storage-engine=engine1
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.hibernate-orm.packages=io.quarkus.hibernate.orm.multiplepersistenceunits.model

quarkus.hibernate-orm."users".dialect=org.hibernate.dialect.H2Dialect
quarkus.hibernate-orm."users".dialect=io.quarkus.hibernate.orm.multiplepersistenceunits.MultiplePersistenceUnitsInconsistentStorageEnginesTest$H2DialectWithMySQLInTheName
quarkus.hibernate-orm."users".dialect.storage-engine=engine2
quarkus.hibernate-orm."users".database.generation=drop-and-create
quarkus.hibernate-orm."users".datasource=users
quarkus.hibernate-orm."users".packages=io.quarkus.hibernate.orm.multiplepersistenceunits.model.user

quarkus.hibernate-orm."inventory".dialect=org.hibernate.dialect.H2Dialect
quarkus.hibernate-orm."inventory".dialect=io.quarkus.hibernate.orm.multiplepersistenceunits.MultiplePersistenceUnitsInconsistentStorageEnginesTest$H2DialectWithMySQLInTheName
quarkus.hibernate-orm."inventory".database.generation=drop-and-create
quarkus.hibernate-orm."inventory".datasource=inventory
quarkus.hibernate-orm."inventory".packages=io.quarkus.hibernate.orm.multiplepersistenceunits.model.inventory

0 comments on commit dcf945f

Please sign in to comment.