Skip to content

Commit

Permalink
Merge pull request #10382 from Sanne/CandidateReactiveFix
Browse files Browse the repository at this point in the history
Hibernate Reactive services initiator fix
  • Loading branch information
gsmet authored Jul 1, 2020
2 parents 547badd + e132d42 commit 0413903
Show file tree
Hide file tree
Showing 24 changed files with 987 additions and 498 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.quarkus.hibernate.orm.deployment;

import io.quarkus.agroal.deployment.JdbcDataSourceBuildItem;
import io.quarkus.builder.item.SimpleBuildItem;

/**
* Quarkus attempts to automatically define a persistence unit when the Hibernate ORM
* extension is enabled, a default datasource is defined, and there are mapped entities.
* This build item represents the decision about creating such an implied persistence
* unit; it's modelled as a BuildItem so that other extensions can be aware of such
* a persistence unit being defined (e.g. Hibernate Reactive needs to know).
*/
public final class ImpliedBlockingPersistenceUnitTypeBuildItem extends SimpleBuildItem {

private static final ImpliedBlockingPersistenceUnitTypeBuildItem NONE = new ImpliedBlockingPersistenceUnitTypeBuildItem(
false, null);
private final boolean shouldGenerateOne;
private final JdbcDataSourceBuildItem datasourceConfig;

private ImpliedBlockingPersistenceUnitTypeBuildItem(boolean shouldGenerateOne, JdbcDataSourceBuildItem datasourceConfig) {
this.shouldGenerateOne = shouldGenerateOne;
this.datasourceConfig = datasourceConfig;
}

public static ImpliedBlockingPersistenceUnitTypeBuildItem none() {
return NONE;
}

public static ImpliedBlockingPersistenceUnitTypeBuildItem generateImpliedPersistenceUnit(
JdbcDataSourceBuildItem datasourceConfig) {
return new ImpliedBlockingPersistenceUnitTypeBuildItem(true, datasourceConfig);
}

public boolean shouldGenerateImpliedBlockingPersistenceUnit() {
return shouldGenerateOne;
}

public JdbcDataSourceBuildItem getDatasourceBuildTimeConfiguration() {
return datasourceConfig;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package io.quarkus.hibernate.orm.deployment;

import java.util.Set;

import org.hibernate.MultiTenancyStrategy;
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;

import io.quarkus.builder.item.MultiBuildItem;
import io.quarkus.hibernate.orm.runtime.boot.QuarkusPersistenceUnitDefinition;

/**
* Not to be confused with PersistenceXmlDescriptorBuildItem, which holds
Expand All @@ -13,12 +17,41 @@
public final class PersistenceUnitDescriptorBuildItem extends MultiBuildItem {

private final ParsedPersistenceXmlDescriptor descriptor;
private final MultiTenancyStrategy multiTenancyStrategy;
private final boolean isReactive;

public PersistenceUnitDescriptorBuildItem(ParsedPersistenceXmlDescriptor descriptor) {
public PersistenceUnitDescriptorBuildItem(ParsedPersistenceXmlDescriptor descriptor, boolean isReactive) {
this.descriptor = descriptor;
this.multiTenancyStrategy = MultiTenancyStrategy.NONE;
this.isReactive = isReactive;
}

public PersistenceUnitDescriptorBuildItem(ParsedPersistenceXmlDescriptor descriptor,
MultiTenancyStrategy multiTenancyStrategy, boolean isReactive) {
this.descriptor = descriptor;
this.multiTenancyStrategy = multiTenancyStrategy;
this.isReactive = isReactive;
}

/**
* Modifies the passed set by adding all explicitly listed classnames from this PU
* into the set.
*
* @param classNames the set to modify
*/
public void addListedEntityClassNamesTo(Set<String> classNames) {
classNames.addAll(descriptor.getManagedClassNames());
}

public String getExplicitSqlImportScriptResourceName() {
return descriptor.getProperties().getProperty("javax.persistence.sql-load-script-source");
}

public String getPersistenceUnitName() {
return descriptor.getName();
}

public ParsedPersistenceXmlDescriptor getDescriptor() {
return descriptor;
public QuarkusPersistenceUnitDefinition asOutputPersistenceUnitDefinition() {
return new QuarkusPersistenceUnitDefinition(descriptor, multiTenancyStrategy, isReactive);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package io.quarkus.hibernate.orm.deployment.metrics;

import org.eclipse.microprofile.metrics.Metadata;
import org.eclipse.microprofile.metrics.MetricType;

import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.hibernate.orm.deployment.HibernateOrmConfig;
import io.quarkus.hibernate.orm.runtime.metrics.HibernateCounter;
import io.quarkus.smallrye.metrics.deployment.spi.MetricBuildItem;

/**
* Responsible to produce all MetricBuildItem related to Hibernate ORM
*/
public final class HibernateOrmMetrics {

@BuildStep
public void metrics(HibernateOrmConfig config,
BuildProducer<MetricBuildItem> metrics) {
// TODO: When multiple PUs are supported, create metrics for each PU. For now we only assume the "default" PU.
boolean metricsEnabled = config.metricsEnabled && config.statistics.orElse(true);
metrics.produce(createMetricBuildItem("hibernate-orm.sessions.open",
"Global number of sessions opened",
"sessionsOpened",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.sessions.closed",
"Global number of sessions closed",
"sessionsClosed",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.sessions.closed",
"Global number of sessions closed",
"sessionsClosed",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.transactions",
"The number of transactions we know to have completed",
"transactionCount",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.transactions.successful",
"The number of transactions we know to have been successful",
"successfulTransactions",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.optimistic.lock.failures",
"The number of Hibernate StaleObjectStateExceptions or JPA OptimisticLockExceptions that occurred.",
"optimisticLockFailures",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.flushes",
"Global number of flush operations executed (either manual or automatic).",
"flushes",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.connections.obtained",
"Get the global number of connections asked by the sessions " +
"(the actual number of connections used may be much smaller depending " +
"whether you use a connection pool or not)",
"connectionsObtained",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.statements.prepared",
"The number of prepared statements that were acquired",
"statementsPrepared",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.statements.closed",
"The number of prepared statements that were released",
"statementsClosed",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.second-level-cache.puts",
"Global number of cacheable entities/collections put in the cache",
"secondLevelCachePuts",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.second-level-cache.hits",
"Global number of cacheable entities/collections successfully retrieved from the cache",
"secondLevelCacheHits",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.second-level-cache.misses",
"Global number of cacheable entities/collections not found in the cache and loaded from the database.",
"secondLevelCacheMisses",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.entities.loaded",
"Global number of entity loads",
"entitiesLoaded",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.entities.updated",
"Global number of entity updates",
"entitiesUpdated",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.entities.inserted",
"Global number of entity inserts",
"entitiesInserted",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.entities.deleted",
"Global number of entity deletes",
"entitiesDeleted",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.entities.fetched",
"Global number of entity fetches",
"entitiesFetched",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.collections.loaded",
"Global number of collections loaded",
"collectionsLoaded",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.collections.updated",
"Global number of collections updated",
"collectionsUpdated",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.collections.removed",
"Global number of collections removed",
"collectionsRemoved",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.collections.recreated",
"Global number of collections recreated",
"collectionsRecreated",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.collections.fetched",
"Global number of collections fetched",
"collectionsFetched",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.natural-id.queries.executions",
"Global number of natural id queries executed against the database",
"naturalIdQueriesExecutedToDatabase",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.natural-id.cache.hits",
"Global number of cached natural id lookups successfully retrieved from cache",
"naturalIdCacheHits",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.natural-id.cache.puts",
"Global number of cacheable natural id lookups put in cache",
"naturalIdCachePuts",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.natural-id.cache.misses",
"Global number of cached natural id lookups *not* found in cache",
"naturalIdCacheMisses",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.queries.executed",
"Global number of executed queries",
"queriesExecutedToDatabase",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.query-cache.puts",
"Global number of cacheable queries put in cache",
"queryCachePuts",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.query-cache.hits",
"Global number of cached queries successfully retrieved from cache",
"queryCacheHits",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.query-cache.misses",
"Global number of cached queries *not* found in cache",
"queryCacheMisses",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.timestamps-cache.puts",
"Global number of timestamps put in cache",
"updateTimestampsCachePuts",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.timestamps-cache.hits",
"Global number of timestamps successfully retrieved from cache",
"updateTimestampsCacheHits",
metricsEnabled));
metrics.produce(createMetricBuildItem("hibernate-orm.timestamps-cache.misses",
"Global number of timestamp requests that were not found in the cache",
"updateTimestampsCacheMisses",
metricsEnabled));
}

private MetricBuildItem createMetricBuildItem(String metricName, String description, String metric,
boolean metricsEnabled) {
return new MetricBuildItem(Metadata.builder()
.withName(metricName)
.withDescription(description)
.withType(MetricType.COUNTER)
.build(),
new HibernateCounter("default", metric),
metricsEnabled,
"hibernate-orm");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ private EntityManagerFactoryBuilder getEntityManagerFactoryBuilderOrNull(String

RecordedState recordedState = PersistenceUnitsHolder.getRecordedState(persistenceUnitName);

if (recordedState.isReactive()) {
throw new IllegalStateException(
"Attempting to boot a blocking Hibernate ORM instance on a reactive RecordedState");
}
final PrevalidatedQuarkusMetadata metadata = recordedState.getMetadata();
final BuildTimeSettings buildTimeSettings = recordedState.getBuildTimeSettings();
final IntegrationSettings integrationSettings = recordedState.getIntegrationSettings();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
import org.hibernate.MultiTenancyStrategy;
import org.hibernate.boot.archive.scan.spi.Scanner;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
import org.jboss.logging.Logger;

import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.arc.runtime.BeanContainerListener;
import io.quarkus.hibernate.orm.runtime.boot.QuarkusPersistenceUnitDefinition;
import io.quarkus.hibernate.orm.runtime.proxies.PreGeneratedProxies;
import io.quarkus.runtime.annotations.Recorder;

Expand Down Expand Up @@ -79,14 +79,14 @@ public void created(BeanContainer beanContainer) {
};
}

public BeanContainerListener initMetadata(List<ParsedPersistenceXmlDescriptor> parsedPersistenceXmlDescriptors,
public BeanContainerListener initMetadata(List<QuarkusPersistenceUnitDefinition> parsedPersistenceXmlDescriptors,
Scanner scanner, Collection<Class<? extends Integrator>> additionalIntegrators,
PreGeneratedProxies proxyDefinitions, MultiTenancyStrategy strategy) {
PreGeneratedProxies proxyDefinitions) {
return new BeanContainerListener() {
@Override
public void created(BeanContainer beanContainer) {
PersistenceUnitsHolder.initializeJpa(parsedPersistenceXmlDescriptors, scanner, additionalIntegrators,
proxyDefinitions, strategy);
proxyDefinitions);
}
};
}
Expand Down
Loading

0 comments on commit 0413903

Please sign in to comment.