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
parent c945b16b4f
commit 70f906045a
2 changed files with 35 additions and 5 deletions

View File

@ -535,13 +535,28 @@ public class AnnotationMetaEntity extends AnnotationMeta {
sessionType = HIB_STATELESS_SESSION;
addDaoConstructor( null );
}
if ( jakartaDataRepository && !quarkusInjection
&& context.addDependentAnnotation() ) {
if ( needsDefaultConstructor() ) {
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) {
if ( !hasAnnotation( type, ENTITY, MAPPED_SUPERCLASS, EMBEDDABLE )
|| isPanacheType( type ) ) {

View File

@ -17,7 +17,7 @@ import org.hibernate.processor.util.Constants;
* @author Gavin King
*/
public class RepositoryConstructor implements MetaAttribute {
private final Metamodel annotationMetaEntity;
private final AnnotationMetaEntity annotationMetaEntity;
private final String constructorName;
private final String methodName;
private final String sessionTypeName;
@ -30,7 +30,7 @@ public class RepositoryConstructor implements MetaAttribute {
private final boolean quarkusInjection;
public RepositoryConstructor(
Metamodel annotationMetaEntity,
AnnotationMetaEntity annotationMetaEntity,
String constructorName,
String methodName,
String sessionTypeName,
@ -135,6 +135,11 @@ public class RepositoryConstructor implements MetaAttribute {
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) {
if ( addInjectAnnotation && quarkusInjection && dataStore != null ) {
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) {
// Jakarta Data repositories are instantiated
// via the default constructor, so in that
// case, this one is just for testing, unless
// we are in Quarkus where we can use
// constructor injection
if ( addInjectAnnotation && (!dataRepository || quarkusInjection) ) {
if ( addInjectAnnotation && !annotationMetaEntity.needsDefaultConstructor() ) {
declaration
.append('@')
.append(annotationMetaEntity.importType("jakarta.inject.Inject"))