HHH-17772 new approach to PU injection in Quarkus

as discussed with @FroMage
This commit is contained in:
Gavin King 2024-02-29 21:22:05 +01:00
parent 5d2527383e
commit 25d0899f28
5 changed files with 58 additions and 34 deletions

View File

@ -87,6 +87,7 @@ public final class Context {
private boolean addTransactionScopedAnnotation; private boolean addTransactionScopedAnnotation;
private AccessType persistenceUnitDefaultAccessType; private AccessType persistenceUnitDefaultAccessType;
private boolean generateJakartaDataStaticMetamodel; private boolean generateJakartaDataStaticMetamodel;
private boolean quarkusInjection;
// keep track of all classes for which model have been generated // keep track of all classes for which model have been generated
private final Set<Metamodel> generatedModelClasses = new HashSet<>(); private final Set<Metamodel> generatedModelClasses = new HashSet<>();
@ -196,6 +197,14 @@ public final class Context {
this.addTransactionScopedAnnotation = addTransactionScopedAnnotation; this.addTransactionScopedAnnotation = addTransactionScopedAnnotation;
} }
public boolean isQuarkusInjection() {
return quarkusInjection;
}
public void setQuarkusInjection(boolean quarkusInjection) {
this.quarkusInjection = quarkusInjection;
}
public Elements getElementUtils() { public Elements getElementUtils() {
return processingEnvironment.getElementUtils(); return processingEnvironment.getElementUtils();
} }

View File

@ -170,12 +170,16 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
final PackageElement jakartaDataPackage = final PackageElement jakartaDataPackage =
context.getProcessingEnvironment().getElementUtils() context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "jakarta.data" ); .getPackageElement( "jakarta.data" );
final PackageElement quarkusOrmPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "io.quarkus.hibernate.orm" );
context.setAddInjectAnnotation( jakartaInjectPackage != null ); context.setAddInjectAnnotation( jakartaInjectPackage != null );
context.setAddNonnullAnnotation( jakartaAnnotationPackage != null ); context.setAddNonnullAnnotation( jakartaAnnotationPackage != null );
context.setAddGeneratedAnnotation( jakartaAnnotationPackage != null ); context.setAddGeneratedAnnotation( jakartaAnnotationPackage != null );
context.setAddDependentAnnotation( jakartaContextPackage != null ); context.setAddDependentAnnotation( jakartaContextPackage != null );
context.setAddTransactionScopedAnnotation( jakartaTransactionsPackage != null ); context.setAddTransactionScopedAnnotation( jakartaTransactionsPackage != null );
context.setQuarkusInjection( quarkusOrmPackage != null );
final Map<String, String> options = environment.getOptions(); final Map<String, String> options = environment.getOptions();
@ -250,7 +254,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
final TypeElement typeElement = context.getElementUtils().getTypeElement( elementName ); final TypeElement typeElement = context.getElementUtils().getTypeElement( elementName );
try { try {
final AnnotationMetaEntity metaEntity = final AnnotationMetaEntity metaEntity =
AnnotationMetaEntity.create( typeElement, context, false, false ); AnnotationMetaEntity.create( typeElement, context );
context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity ); context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity );
context.removeElementToRedo( elementName ); context.removeElementToRedo( elementName );
} }
@ -278,7 +282,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|| provider.equalsIgnoreCase("hibernate") ) { || provider.equalsIgnoreCase("hibernate") ) {
context.logMessage( Diagnostic.Kind.OTHER, "Processing repository class '" + element + "'" ); context.logMessage( Diagnostic.Kind.OTHER, "Processing repository class '" + element + "'" );
final AnnotationMetaEntity metaEntity = final AnnotationMetaEntity metaEntity =
AnnotationMetaEntity.create( typeElement, context, false, false ); AnnotationMetaEntity.create( typeElement, context );
context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity ); context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity );
} }
} }
@ -287,7 +291,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
if ( hasAnnotation( member, HQL, SQL, FIND ) ) { if ( hasAnnotation( member, HQL, SQL, FIND ) ) {
context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class '" + element + "'" ); context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class '" + element + "'" );
final AnnotationMetaEntity metaEntity = final AnnotationMetaEntity metaEntity =
AnnotationMetaEntity.create( typeElement, context, false, false ); AnnotationMetaEntity.create( typeElement, context );
context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity ); context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity );
break; break;
} }
@ -454,7 +458,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
= hasAnnotation( element, EMBEDDABLE, MAPPED_SUPERCLASS ); = hasAnnotation( element, EMBEDDABLE, MAPPED_SUPERCLASS );
final AnnotationMetaEntity metaEntity = final AnnotationMetaEntity metaEntity =
AnnotationMetaEntity.create( typeElement, context, AnnotationMetaEntity.create( typeElement, context,
requiresLazyMemberInitialization, true ); requiresLazyMemberInitialization,
true, false );
if ( alreadyExistingMetaEntity != null ) { if ( alreadyExistingMetaEntity != null ) {
metaEntity.mergeInMembers( alreadyExistingMetaEntity ); metaEntity.mergeInMembers( alreadyExistingMetaEntity );
} }
@ -465,7 +470,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
&& alreadyExistingMetaEntity == null ) { && alreadyExistingMetaEntity == null ) {
final AnnotationMetaEntity dataMetaEntity = final AnnotationMetaEntity dataMetaEntity =
AnnotationMetaEntity.create( typeElement, context, AnnotationMetaEntity.create( typeElement, context,
requiresLazyMemberInitialization, true, true ); requiresLazyMemberInitialization,
true, true );
// final Metamodel alreadyExistingDataMetaEntity = // final Metamodel alreadyExistingDataMetaEntity =
// tryGettingExistingDataEntityFromContext( mirror, '_' + qualifiedName ); // tryGettingExistingDataEntityFromContext( mirror, '_' + qualifiedName );
// if ( alreadyExistingDataMetaEntity != null ) { // if ( alreadyExistingDataMetaEntity != null ) {
@ -481,7 +487,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
private void handleRootElementAuxiliaryAnnotationMirrors(final Element element) { private void handleRootElementAuxiliaryAnnotationMirrors(final Element element) {
if ( element instanceof TypeElement ) { if ( element instanceof TypeElement ) {
final AnnotationMetaEntity metaEntity = final AnnotationMetaEntity metaEntity =
AnnotationMetaEntity.create( (TypeElement) element, context, false, false ); AnnotationMetaEntity.create( (TypeElement) element, context );
context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity ); context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity );
} }
else if ( element instanceof PackageElement ) { else if ( element instanceof PackageElement ) {

View File

@ -101,6 +101,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
private final Context context; private final Context context;
private final boolean managed; private final boolean managed;
private boolean jakartaDataRepository; private boolean jakartaDataRepository;
private final boolean quarkusInjection;
private String qualifiedName; private String qualifiedName;
private final boolean jakartaDataStaticModel; private final boolean jakartaDataStaticModel;
@ -138,25 +139,28 @@ public class AnnotationMetaEntity extends AnnotationMeta {
private final Map<String,String> memberTypes = new HashMap<>(); private final Map<String,String> memberTypes = new HashMap<>();
public AnnotationMetaEntity(TypeElement element, Context context, boolean managed, boolean jakartaData) { public AnnotationMetaEntity(
TypeElement element, Context context, boolean managed,
boolean jakartaDataStaticMetamodel) {
this.element = element; this.element = element;
this.context = context; this.context = context;
this.managed = managed; this.managed = managed;
this.members = new HashMap<>(); this.members = new HashMap<>();
this.quarkusInjection = context.isQuarkusInjection();
this.importContext = new ImportContextImpl( getPackageName( context, element ) ); this.importContext = new ImportContextImpl( getPackageName( context, element ) );
jakartaDataStaticModel = jakartaData; jakartaDataStaticModel = jakartaDataStaticMetamodel;
}
public static AnnotationMetaEntity create(TypeElement element, Context context) {
return create( element,context, false, false, false );
} }
public static AnnotationMetaEntity create( public static AnnotationMetaEntity create(
TypeElement element, Context context, TypeElement element, Context context,
boolean lazilyInitialised, boolean managed) { boolean lazilyInitialised, boolean managed,
return create( element,context, lazilyInitialised, managed, false ); boolean jakartaData) {
} final AnnotationMetaEntity annotationMetaEntity =
new AnnotationMetaEntity( element, context, managed, jakartaData );
public static AnnotationMetaEntity create(
TypeElement element, Context context,
boolean lazilyInitialised, boolean managed, boolean jakartaData) {
final AnnotationMetaEntity annotationMetaEntity = new AnnotationMetaEntity( element, context, managed, jakartaData );
if ( !lazilyInitialised ) { if ( !lazilyInitialised ) {
annotationMetaEntity.init(); annotationMetaEntity.init();
} }
@ -293,7 +297,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
@Override @Override
public String scope() { public String scope() {
if (jakartaDataRepository) { if (jakartaDataRepository && !quarkusInjection) {
return context.addTransactionScopedAnnotation() return context.addTransactionScopedAnnotation()
? "javax.transaction.TransactionScoped" ? "javax.transaction.TransactionScoped"
: "jakarta.enterprise.context.RequestScoped"; : "jakarta.enterprise.context.RequestScoped";
@ -345,7 +349,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
sessionType = HIB_STATELESS_SESSION; sessionType = HIB_STATELESS_SESSION;
addDaoConstructor( null ); addDaoConstructor( null );
} }
if ( jakartaDataRepository ) { if ( jakartaDataRepository && !quarkusInjection ) {
addDefaultConstructor(); addDefaultConstructor();
} }
@ -439,7 +443,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
context.addInjectAnnotation(), context.addInjectAnnotation(),
context.addNonnullAnnotation(), context.addNonnullAnnotation(),
method != null, method != null,
jakartaDataRepository jakartaDataRepository,
quarkusInjection
) )
); );
return sessionType; return sessionType;

View File

@ -59,7 +59,6 @@ public class DefaultConstructor implements MetaAttribute {
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
StringBuilder declaration = new StringBuilder(); StringBuilder declaration = new StringBuilder();
declaration.append('\n'); declaration.append('\n');
inject( declaration );
declaration declaration
.append("@") .append("@")
.append(annotationMetaEntity.importType("jakarta.persistence.PersistenceUnit")); .append(annotationMetaEntity.importType("jakarta.persistence.PersistenceUnit"));

View File

@ -27,6 +27,7 @@ public class RepositoryConstructor implements MetaAttribute {
private final boolean addNonnullAnnotation; private final boolean addNonnullAnnotation;
private final boolean addOverrideAnnotation; private final boolean addOverrideAnnotation;
private final boolean dataRepository; private final boolean dataRepository;
private final boolean quarkusInjection;
public RepositoryConstructor( public RepositoryConstructor(
Metamodel annotationMetaEntity, Metamodel annotationMetaEntity,
@ -38,7 +39,8 @@ public class RepositoryConstructor implements MetaAttribute {
boolean addInjectAnnotation, boolean addInjectAnnotation,
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean addOverrideAnnotation, boolean addOverrideAnnotation,
boolean dataRepository) { boolean dataRepository,
boolean quarkusInjection) {
this.annotationMetaEntity = annotationMetaEntity; this.annotationMetaEntity = annotationMetaEntity;
this.constructorName = constructorName; this.constructorName = constructorName;
this.methodName = methodName; this.methodName = methodName;
@ -49,6 +51,7 @@ public class RepositoryConstructor implements MetaAttribute {
this.addNonnullAnnotation = addNonnullAnnotation; this.addNonnullAnnotation = addNonnullAnnotation;
this.addOverrideAnnotation = addOverrideAnnotation; this.addOverrideAnnotation = addOverrideAnnotation;
this.dataRepository = dataRepository; this.dataRepository = dataRepository;
this.quarkusInjection = quarkusInjection;
} }
@Override @Override
@ -86,7 +89,7 @@ public class RepositoryConstructor implements MetaAttribute {
.append(constructorName) .append(constructorName)
.append("("); .append("(");
notNull( declaration ); notNull( declaration );
// named( declaration ); qualifier( declaration );
declaration declaration
.append(annotationMetaEntity.importType(sessionTypeName)) .append(annotationMetaEntity.importType(sessionTypeName))
.append(" ") .append(" ")
@ -117,22 +120,24 @@ public class RepositoryConstructor implements MetaAttribute {
return declaration.toString(); return declaration.toString();
} }
// private void named(StringBuilder declaration) { private void qualifier(StringBuilder declaration) {
// if ( addInjectAnnotation && !dataRepository && dataStore != null ) { if ( addInjectAnnotation && quarkusInjection && dataStore != null ) {
// declaration declaration
// .append('@') .append('@')
// .append(annotationMetaEntity.importType("jakarta.inject.Named")) .append(annotationMetaEntity.importType("io.quarkus.hibernate.orm.PersistenceUnit"))
// .append("(\"") .append("(\"")
// .append(dataStore) .append(dataStore)
// .append("\") "); .append("\") ");
// } }
// } }
private void inject(StringBuilder declaration) { private void inject(StringBuilder declaration) {
// Jakarta Data repositories are instantiated // Jakarta Data repositories are instantiated
// via the default constructor, so in that // via the default constructor, so in that
// case, this one is just for testing // case, this one is just for testing, unless
if ( addInjectAnnotation && !dataRepository ) { // we are in Quarkus where we can use
// constructor injection
if ( addInjectAnnotation && (!dataRepository || quarkusInjection) ) {
declaration declaration
.append('@') .append('@')
.append(annotationMetaEntity.importType("jakarta.inject.Inject")) .append(annotationMetaEntity.importType("jakarta.inject.Inject"))