Auto-detect quarkus and default to dao with the proper session type

Unless there's a different session getter defined
This commit is contained in:
Stéphane Épardaud 2023-12-05 11:51:17 +01:00 committed by Gavin King
parent 5b184caf9b
commit b32296ff32
4 changed files with 80 additions and 0 deletions

View File

@ -95,6 +95,9 @@ public final class Context {
// keep track of which named queries have been checked
private final Set<String> checkedNamedQueries = new HashSet<>();
private boolean usesQuarkusOrm = false;
private boolean usesQuarkusReactive = false;
public Context(ProcessingEnvironment processingEnvironment) {
this.processingEnvironment = processingEnvironment;
@ -390,4 +393,20 @@ public final class Context {
public boolean checkNamedQuery(String name) {
return checkedNamedQueries.add(name);
}
public void setUsesQuarkusOrm(boolean b) {
usesQuarkusOrm = b;
}
public boolean usesQuarkusOrm() {
return usesQuarkusOrm;
}
public void setUsesQuarkusReactive(boolean b) {
usesQuarkusReactive = b;
}
public boolean usesQuarkusReactive() {
return usesQuarkusReactive;
}
}

View File

@ -174,12 +174,29 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "io.quarkus.hibernate.orm" );
PackageElement quarkusOrmPanachePackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "io.quarkus.hibernate.orm.panache" );
PackageElement quarkusReactivePanachePackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "io.quarkus.hibernate.reactive.panache" );
if ( quarkusReactivePanachePackage != null
&& quarkusOrmPanachePackage != null ) {
context.logMessage(
Diagnostic.Kind.WARNING,
"Both Quarkus Hibernate ORM and Hibernate Reactive with Panache detected: this is not supported, so will proceed as if none were there"
);
quarkusOrmPanachePackage = quarkusReactivePanachePackage = null;
}
context.setAddInjectAnnotation( jakartaInjectPackage != null );
context.setAddNonnullAnnotation( jakartaAnnotationPackage != null );
context.setAddGeneratedAnnotation( jakartaAnnotationPackage != null );
context.setAddDependentAnnotation( jakartaContextPackage != null );
context.setAddTransactionScopedAnnotation( jakartaTransactionsPackage != null );
context.setQuarkusInjection( quarkusOrmPackage != null );
context.setUsesQuarkusOrm( quarkusOrmPanachePackage != null );
context.setUsesQuarkusReactive( quarkusReactivePanachePackage != null );
final Map<String, String> options = environment.getOptions();

View File

@ -58,6 +58,8 @@ import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import jakarta.persistence.EntityManager;
import static java.beans.Introspector.decapitalize;
import static java.lang.Boolean.FALSE;
import static java.util.Collections.emptyList;
@ -407,6 +409,12 @@ public class AnnotationMetaEntity extends AnnotationMeta {
sessionType = getter.getReturnType().toString();
}
}
else if ( element.getKind() == ElementKind.INTERFACE
&& ( context.usesQuarkusOrm() || context.usesQuarkusReactive() ) ) {
// if we don't have a getter, but we're in Quarkus, we know how to find the default sessions
repository = true;
sessionType = setupQuarkusDaoConstructor();
}
if ( !repository && jakartaDataRepository ) {
repository = true;
sessionType = HIB_STATELESS_SESSION;
@ -514,6 +522,41 @@ public class AnnotationMetaEntity extends AnnotationMeta {
return sessionType;
}
/**
* For Quarkus, we generate a constructor with injection for EntityManager in ORM,
* and in HR, we define the static session getter.
*/
private String setupQuarkusDaoConstructor() {
final String typeName = element.getSimpleName().toString() + '_';
final String sessionVariableName = getSessionVariableName( sessionType );
if ( context.usesQuarkusOrm() ) {
String name = "getEntityManager";
putMember( name,
new RepositoryConstructor(
this,
typeName,
name,
sessionType,
sessionVariableName,
dataStore(),
context.addInjectAnnotation(),
context.addNonnullAnnotation(),
false,
false,
true
)
);
return Constants.ENTITY_MANAGER;
}
else {
importType( Constants.QUARKUS_SESSION_OPERATIONS );
// use this getter to get the method, do not generate an injection point for its type
sessionGetter = "SessionOperations.getSession()";
return Constants.UNI_MUTINY_SESSION;
}
}
/**
* The session getter method doesn't have to be a JavaBeans-style
* getter. It can be any method with no parameters and one of the

View File

@ -94,6 +94,7 @@ public final class Constants {
public static final String HIB_SESSION_FACTORY = "org.hibernate.SessionFactory";
public static final String HIB_STATELESS_SESSION = "org.hibernate.StatelessSession";
public static final String MUTINY_SESSION = "org.hibernate.reactive.mutiny.Mutiny.Session";
public static final String QUARKUS_SESSION_OPERATIONS = "io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations";
public static final String TUPLE = "jakarta.persistence.Tuple";