when CDI is missing, do still add an @Inject annotation on the constructor

at least when jakarta.inject is available

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-03-31 14:38:04 +02:00 committed by Christian Beikov
parent 01ee8eacd8
commit 8db57d791b
2 changed files with 35 additions and 5 deletions

View File

@ -535,13 +535,28 @@ public class AnnotationMetaEntity extends AnnotationMeta {
sessionType = HIB_STATELESS_SESSION; sessionType = HIB_STATELESS_SESSION;
addDaoConstructor( null ); addDaoConstructor( null );
} }
if ( jakartaDataRepository && !quarkusInjection if ( needsDefaultConstructor() ) {
&& context.addDependentAnnotation() ) {
addDefaultConstructor(); addDefaultConstructor();
} }
} }
} }
/**
* For usage with CDI, but outside Quarkus, Jakarta Data
* repositories use {@code @PersistenceUnit} to obtain an
* {@code EntityManagerFactory} via field injection. So in
* that case we will need a {@link DefaultConstructor default
* constructor}. We don't do this in Quarkus, because there
* we can just inject the {@code StatelessSession} directly,
* and so in Quarkus we don't need the default constructor
* at all.
*/
boolean needsDefaultConstructor() {
return jakartaDataRepository
&& !quarkusInjection
&& context.addDependentAnnotation();
}
private @Nullable ExecutableElement findSessionGetter(TypeElement type) { private @Nullable ExecutableElement findSessionGetter(TypeElement type) {
if ( !hasAnnotation( type, ENTITY, MAPPED_SUPERCLASS, EMBEDDABLE ) if ( !hasAnnotation( type, ENTITY, MAPPED_SUPERCLASS, EMBEDDABLE )
|| isPanacheType( type ) ) { || isPanacheType( type ) ) {

View File

@ -17,7 +17,7 @@ import org.hibernate.processor.util.Constants;
* @author Gavin King * @author Gavin King
*/ */
public class RepositoryConstructor implements MetaAttribute { public class RepositoryConstructor implements MetaAttribute {
private final Metamodel annotationMetaEntity; private final AnnotationMetaEntity annotationMetaEntity;
private final String constructorName; private final String constructorName;
private final String methodName; private final String methodName;
private final String sessionTypeName; private final String sessionTypeName;
@ -30,7 +30,7 @@ public class RepositoryConstructor implements MetaAttribute {
private final boolean quarkusInjection; private final boolean quarkusInjection;
public RepositoryConstructor( public RepositoryConstructor(
Metamodel annotationMetaEntity, AnnotationMetaEntity annotationMetaEntity,
String constructorName, String constructorName,
String methodName, String methodName,
String sessionTypeName, String sessionTypeName,
@ -135,6 +135,11 @@ public class RepositoryConstructor implements MetaAttribute {
return declaration.toString(); return declaration.toString();
} }
/**
* In Quarkus we use the Quarkus-specific {@code @PersistenceUnit}
* CDI qualifier annotation to inject the {@code StatelessSession}
* directly.
*/
private void qualifier(StringBuilder declaration) { private void qualifier(StringBuilder declaration) {
if ( addInjectAnnotation && quarkusInjection && dataStore != null ) { if ( addInjectAnnotation && quarkusInjection && dataStore != null ) {
declaration declaration
@ -146,13 +151,23 @@ public class RepositoryConstructor implements MetaAttribute {
} }
} }
/**
* In Quarkus we inject the {@code StatelessSession}
* directly via the constructor. But this doesn't work
* in other CDI implementations, where we need to use
* the JPA {@code @PersistenceUnit} annotation for
* field injection of an {@code EntityManager}. In
* that case, CDI will instantiate the repository via
* a {@link DefaultConstructor default constructor},
* so we don't need to mark this one {@code @Inject}.
*/
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, unless // case, this one is just for testing, unless
// we are in Quarkus where we can use // we are in Quarkus where we can use
// constructor injection // constructor injection
if ( addInjectAnnotation && (!dataRepository || quarkusInjection) ) { if ( addInjectAnnotation && !annotationMetaEntity.needsDefaultConstructor() ) {
declaration declaration
.append('@') .append('@')
.append(annotationMetaEntity.importType("jakarta.inject.Inject")) .append(annotationMetaEntity.importType("jakarta.inject.Inject"))