Skip to content

Commit

Permalink
Merge pull request #15822 from Sanne/Ban
Browse files Browse the repository at this point in the history
Avoid class initializations more aggressively in the Hibernate ORM extension
  • Loading branch information
gsmet committed Apr 8, 2021
2 parents 6beb4c9 + 50aca25 commit 6f05492
Show file tree
Hide file tree
Showing 20 changed files with 248 additions and 180 deletions.
@@ -1,17 +1,25 @@
package io.quarkus.deployment.builditem;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import io.quarkus.builder.item.MultiBuildItem;

public final class AdditionalIndexedClassesBuildItem extends MultiBuildItem {

private final Set<String> classesToIndex = new HashSet<>();
private final Set<String> classesToIndex;

public AdditionalIndexedClassesBuildItem(String... classesToIndex) {
this.classesToIndex.addAll(Arrays.asList(classesToIndex));
Set<String> toIndex = new HashSet<>(classesToIndex.length);
for (String s : classesToIndex) {
toIndex.add(s);
}
this.classesToIndex = toIndex;
}

public AdditionalIndexedClassesBuildItem(String classToIndex) {
this.classesToIndex = Collections.singleton(classToIndex);
}

public Set<String> getClassesToIndex() {
Expand Down
Expand Up @@ -36,8 +36,8 @@ CapabilityBuildItem capability() {
@BuildStep
List<AdditionalJpaModelBuildItem> addJpaModelClasses() {
return Arrays.asList(
new AdditionalJpaModelBuildItem(org.hibernate.envers.DefaultRevisionEntity.class),
new AdditionalJpaModelBuildItem(org.hibernate.envers.DefaultTrackingModifiedEntitiesRevisionEntity.class));
new AdditionalJpaModelBuildItem("org.hibernate.envers.DefaultRevisionEntity"),
new AdditionalJpaModelBuildItem("org.hibernate.envers.DefaultTrackingModifiedEntitiesRevisionEntity"));
}

@BuildStep
Expand Down
Empty file.
2 changes: 2 additions & 0 deletions extensions/hibernate-orm/deployment/banned-signatures.txt
@@ -0,0 +1,2 @@
@defaultMessage Don't use the pattern MyClass.class.getName() or DotName.createSimple("org.mycompany.MyClass"). Instead, create constants using createConstant("org.mycompany.MyClass") in io.quarkus.hibernate.orm.deployment.ClassNames. That way, all class names will get checked against the classpath in ConstantsTest.
java.lang.Class#getName()
@@ -1,5 +1,7 @@
package io.quarkus.hibernate.orm.deployment;

import java.util.Objects;

import io.quarkus.builder.item.MultiBuildItem;

/**
Expand All @@ -11,8 +13,9 @@ public final class AdditionalJpaModelBuildItem extends MultiBuildItem {

private final String className;

public AdditionalJpaModelBuildItem(Class<?> klass) {
this.className = klass.getName();
public AdditionalJpaModelBuildItem(String className) {
Objects.requireNonNull(className);
this.className = className;
}

public String getClassName() {
Expand Down
@@ -0,0 +1,51 @@
package io.quarkus.hibernate.orm.deployment;

import java.util.HashSet;
import java.util.Set;

import org.jboss.jandex.DotName;

public class ClassNames {

static final Set<DotName> CREATED_CONSTANTS = new HashSet<>();

private ClassNames() {
}

private static DotName createConstant(String fqcn) {
DotName result = DotName.createSimple(fqcn);
CREATED_CONSTANTS.add(result);
return result;
}

public static final DotName ENUM = createConstant("java.lang.Enum");

public static final DotName TENANT_CONNECTION_RESOLVER = createConstant(
"io.quarkus.hibernate.orm.runtime.tenant.TenantConnectionResolver");
public static final DotName TENANT_RESOLVER = createConstant("io.quarkus.hibernate.orm.runtime.tenant.TenantResolver");

public static final DotName STATIC_METAMODEL = createConstant("javax.persistence.metamodel.StaticMetamodel");

public static final DotName QUARKUS_PERSISTENCE_UNIT = createConstant("io.quarkus.hibernate.orm.PersistenceUnit");
public static final DotName QUARKUS_PERSISTENCE_UNIT_REPEATABLE_CONTAINER = createConstant(
"io.quarkus.hibernate.orm.PersistenceUnit$List");
public static final DotName JPA_PERSISTENCE_UNIT = createConstant("javax.persistence.PersistenceUnit");
public static final DotName JPA_PERSISTENCE_CONTEXT = createConstant("javax.persistence.PersistenceContext");

public static final DotName JPA_ENTITY = createConstant("javax.persistence.Entity");
public static final DotName MAPPED_SUPERCLASS = createConstant("javax.persistence.MappedSuperclass");
public static final DotName EMBEDDABLE = createConstant("javax.persistence.Embeddable");
public static final DotName EMBEDDED = createConstant("javax.persistence.Embedded");
public static final DotName ELEMENT_COLLECTION = createConstant("javax.persistence.ElementCollection");
public static final DotName PROXY = createConstant("org.hibernate.annotations.Proxy");
public static final DotName HIBERNATE_PROXY = createConstant("org.hibernate.proxy.HibernateProxy");
public static final DotName TYPE = createConstant("org.hibernate.annotations.Type");
public static final DotName TYPE_DEFINITION = createConstant("org.hibernate.annotations.TypeDef");
public static final DotName TYPE_DEFINITIONS = createConstant("org.hibernate.annotations.TypeDefs");

public static final DotName ENTITY_MANAGER_FACTORY = createConstant("javax.persistence.EntityManagerFactory");
public static final DotName SESSION_FACTORY = createConstant("org.hibernate.SessionFactory");
public static final DotName ENTITY_MANAGER = createConstant("javax.persistence.EntityManager");
public static final DotName SESSION = createConstant("org.hibernate.Session");

}
@@ -0,0 +1,47 @@
package io.quarkus.hibernate.orm.deployment;

import java.util.Optional;

import io.quarkus.datasource.common.runtime.DatabaseKind;
import io.quarkus.deployment.configuration.ConfigurationError;

public final class Dialects {

private Dialects() {
//utility
}

public static Optional<String> guessDialect(String resolvedDbKind) {
// For now select the latest dialect from the driver
// later, we can keep doing that but also avoid DCE
// of all the dialects we want in so that people can override them
if (DatabaseKind.isDB2(resolvedDbKind)) {
return Optional.of("org.hibernate.dialect.DB297Dialect");
}
if (DatabaseKind.isPostgreSQL(resolvedDbKind)) {
return Optional.of("io.quarkus.hibernate.orm.runtime.dialect.QuarkusPostgreSQL10Dialect");
}
if (DatabaseKind.isH2(resolvedDbKind)) {
return Optional.of("io.quarkus.hibernate.orm.runtime.dialect.QuarkusH2Dialect");
}
if (DatabaseKind.isMariaDB(resolvedDbKind)) {
return Optional.of("org.hibernate.dialect.MariaDB103Dialect");
}
if (DatabaseKind.isMySQL(resolvedDbKind)) {
return Optional.of("org.hibernate.dialect.MySQL8Dialect");
}
if (DatabaseKind.isOracle(resolvedDbKind)) {
return Optional.of("org.hibernate.dialect.Oracle12cDialect");
}
if (DatabaseKind.isDerby(resolvedDbKind)) {
return Optional.of("org.hibernate.dialect.DerbyTenSevenDialect");
}
if (DatabaseKind.isMsSQL(resolvedDbKind)) {
return Optional.of("org.hibernate.dialect.SQLServer2012Dialect");
}

String error = "Hibernate extension could not guess the dialect from the database kind '" + resolvedDbKind
+ "'. Add an explicit '" + HibernateOrmProcessor.HIBERNATE_ORM_CONFIG_PREFIX + "dialect' property.";
throw new ConfigurationError(error);
}
}
Expand Up @@ -4,21 +4,6 @@
import java.util.Collections;
import java.util.List;

import org.hibernate.annotations.AnyMetaDef;
import org.hibernate.annotations.AnyMetaDefs;
import org.hibernate.annotations.FetchProfile;
import org.hibernate.annotations.FetchProfiles;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.FilterDefs;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.GenericGenerators;
import org.hibernate.annotations.ListIndexBase;
import org.hibernate.annotations.NamedNativeQueries;
import org.hibernate.annotations.NamedNativeQuery;
import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
import org.jboss.jandex.DotName;

public final class HibernateOrmAnnotations {
Expand All @@ -27,20 +12,20 @@ private HibernateOrmAnnotations() {
}

public static final List<DotName> PACKAGE_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(
DotName.createSimple(AnyMetaDef.class.getName()),
DotName.createSimple(AnyMetaDefs.class.getName()),
DotName.createSimple(FetchProfile.class.getName()),
DotName.createSimple(FetchProfile.FetchOverride.class.getName()),
DotName.createSimple(FetchProfiles.class.getName()),
DotName.createSimple(FilterDef.class.getName()),
DotName.createSimple(FilterDefs.class.getName()),
DotName.createSimple(GenericGenerator.class.getName()),
DotName.createSimple(GenericGenerators.class.getName()),
DotName.createSimple(ListIndexBase.class.getName()),
DotName.createSimple(NamedNativeQueries.class.getName()),
DotName.createSimple(NamedNativeQuery.class.getName()),
DotName.createSimple(NamedQueries.class.getName()),
DotName.createSimple(NamedQuery.class.getName()),
DotName.createSimple(TypeDef.class.getName()),
DotName.createSimple(TypeDefs.class.getName())));
DotName.createSimple("org.hibernate.annotations.AnyMetaDef"),
DotName.createSimple("org.hibernate.annotations.AnyMetaDefs"),
DotName.createSimple("org.hibernate.annotations.FetchProfile"),
DotName.createSimple("org.hibernate.annotations.FetchProfile$FetchOverride"),
DotName.createSimple("org.hibernate.annotations.FetchProfiles"),
DotName.createSimple("org.hibernate.annotations.FilterDef"),
DotName.createSimple("org.hibernate.annotations.FilterDefs"),
DotName.createSimple("org.hibernate.annotations.GenericGenerator"),
DotName.createSimple("org.hibernate.annotations.GenericGenerators"),
DotName.createSimple("org.hibernate.annotations.ListIndexBase"),
DotName.createSimple("org.hibernate.annotations.NamedNativeQueries"),
DotName.createSimple("org.hibernate.annotations.NamedNativeQuery"),
DotName.createSimple("org.hibernate.annotations.NamedQueries"),
DotName.createSimple("org.hibernate.annotations.NamedQuery"),
DotName.createSimple("org.hibernate.annotations.TypeDef"),
DotName.createSimple("org.hibernate.annotations.TypeDefs")));
}
Expand Up @@ -6,8 +6,6 @@

import javax.enterprise.inject.Default;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
Expand All @@ -33,19 +31,9 @@

public class HibernateOrmCdiProcessor {

private static final List<DotName> SESSION_FACTORY_EXPOSED_TYPES = Arrays.asList(
DotName.createSimple(EntityManagerFactory.class.getName()),
DotName.createSimple(SessionFactory.class.getName()));
private static final List<DotName> SESSION_EXPOSED_TYPES = Arrays.asList(
DotName.createSimple(EntityManager.class.getName()),
DotName.createSimple(Session.class.getName()));

private static final DotName PERSISTENCE_UNIT_QUALIFIER = DotName.createSimple(PersistenceUnit.class.getName());

private static final DotName JPA_PERSISTENCE_UNIT = DotName.createSimple(javax.persistence.PersistenceUnit.class.getName());

private static final DotName JPA_PERSISTENCE_CONTEXT = DotName
.createSimple(javax.persistence.PersistenceContext.class.getName());
private static final List<DotName> SESSION_FACTORY_EXPOSED_TYPES = Arrays.asList(ClassNames.ENTITY_MANAGER_FACTORY,
ClassNames.SESSION_FACTORY);
private static final List<DotName> SESSION_EXPOSED_TYPES = Arrays.asList(ClassNames.ENTITY_MANAGER, ClassNames.SESSION);

@BuildStep
AnnotationsTransformerBuildItem convertJpaResourceAnnotationsToQualifier(
Expand All @@ -71,10 +59,10 @@ public void transform(TransformationContext transformationContext) {
}

DotName jpaAnnotation;
if (field.hasAnnotation(JPA_PERSISTENCE_UNIT)) {
jpaAnnotation = JPA_PERSISTENCE_UNIT;
} else if (field.hasAnnotation(JPA_PERSISTENCE_CONTEXT)) {
jpaAnnotation = JPA_PERSISTENCE_CONTEXT;
if (field.hasAnnotation(ClassNames.JPA_PERSISTENCE_UNIT)) {
jpaAnnotation = ClassNames.JPA_PERSISTENCE_UNIT;
} else if (field.hasAnnotation(ClassNames.JPA_PERSISTENCE_CONTEXT)) {
jpaAnnotation = ClassNames.JPA_PERSISTENCE_CONTEXT;
} else {
return;
}
Expand All @@ -93,7 +81,7 @@ public void transform(TransformationContext transformationContext) {
// in this case, we consider it the default too if the name matches
transformation.add(DotNames.DEFAULT);
} else {
transformation.add(PERSISTENCE_UNIT_QUALIFIER,
transformation.add(ClassNames.QUARKUS_PERSISTENCE_UNIT,
AnnotationValue.createStringValue("value", persistenceUnitNameAnnotationValue.asString()));
}
transformation.done();
Expand Down

0 comments on commit 6f05492

Please sign in to comment.