Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.List;
import java.util.Set;

import static org.hibernate.processor.util.Constants.SPRING_COMPONENT;
import static org.hibernate.processor.util.TypeUtils.getGeneratedClassFullyQualifiedName;
import static org.hibernate.processor.util.TypeUtils.isMemberType;

Expand Down Expand Up @@ -94,6 +95,9 @@ private static StringBuffer generateBody(Metamodel entity, Context context) {

pw.println( entity.javadoc() );

if ( context.addComponentAnnotation() && entity.isInjectable() ) {
pw.println( writeComponentAnnotation( entity ) );
}
if ( context.addDependentAnnotation() && entity.isInjectable() ) {
pw.println( writeScopeAnnotation( entity ) );
}
Expand Down Expand Up @@ -314,6 +318,10 @@ private static String writeScopeAnnotation(Metamodel entity) {
return "@" + entity.importType( entity.scope() );
}

private static String writeComponentAnnotation(Metamodel entity) {
return "@" + entity.importType( SPRING_COMPONENT );
}

private static String writeStaticMetaModelAnnotation(Metamodel entity) {
final String annotation = entity.isJakartaDataStyle()
? "jakarta.data.metamodel.StaticMetamodel"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public final class Context {
private Boolean fullyXmlConfigured;
private boolean addInjectAnnotation = false;
private boolean addDependentAnnotation = false;
private boolean addComponentAnnotation = false;
private boolean addNonnullAnnotation = false;
private boolean addGeneratedAnnotation = true;
private boolean addGenerationDate;
Expand All @@ -92,6 +93,7 @@ public final class Context {
private AccessType persistenceUnitDefaultAccessType;
private boolean generateJakartaDataStaticMetamodel;
private boolean quarkusInjection;
private boolean springInjection;
private boolean dataEventPackageAvailable;

// keep track of all classes for which model have been generated
Expand Down Expand Up @@ -173,6 +175,14 @@ public void setAddDependentAnnotation(boolean addDependentAnnotation) {
this.addDependentAnnotation = addDependentAnnotation;
}

public boolean addComponentAnnotation() {
return addComponentAnnotation;
}

public void setAddComponentAnnotation(boolean addComponentAnnotation) {
this.addComponentAnnotation = addComponentAnnotation;
}

public boolean addNonnullAnnotation() {
return addNonnullAnnotation;
}
Expand Down Expand Up @@ -225,6 +235,14 @@ public void setQuarkusInjection(boolean quarkusInjection) {
this.quarkusInjection = quarkusInjection;
}

public boolean isSpringInjection() {
return springInjection;
}

public void setSpringInjection(boolean springInjection) {
this.springInjection = springInjection;
}

public boolean isDataEventPackageAvailable() {
return dataEventPackageAvailable;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,13 @@ && packagePresent(quarkusOrmPanachePackage) ) {
quarkusOrmPanachePackage = quarkusReactivePanachePackage = null;
}

final PackageElement springBeansPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "org.springframework.beans.factory" );
final PackageElement springStereotypePackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "org.springframework.stereotype" );

context.setAddInjectAnnotation( packagePresent(jakartaInjectPackage) );
context.setAddNonnullAnnotation( packagePresent(jakartaAnnotationPackage) );
context.setAddGeneratedAnnotation( packagePresent(jakartaAnnotationPackage) );
Expand All @@ -275,6 +282,8 @@ && packagePresent(quarkusOrmPanachePackage) ) {
context.setQuarkusInjection( packagePresent(quarkusOrmPackage) || packagePresent(quarkusReactivePackage) );
context.setUsesQuarkusOrm( packagePresent(quarkusOrmPanachePackage) );
context.setUsesQuarkusReactive( packagePresent(quarkusReactivePanachePackage) );
context.setSpringInjection( packagePresent(springBeansPackage) );
context.setAddComponentAnnotation( packagePresent(springStereotypePackage) );

final Map<String, String> options = environment.getOptions();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ String localSessionName() {
return isReactiveSessionAccess() ? "_session" : sessionName;
}

String getObjectCall() {
return annotationMetaEntity.isProvidedSessionAccess() ? ".getObject()" : "";
}

@Override
public List<AnnotationMirror> inheritedAnnotations() {
if ( annotationMetaEntity.isJakartaDataRepository() ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,13 @@ void createQuery(StringBuilder declaration) {
declaration
.append("_spec.createQuery(")
.append(localSessionName())
.append(getObjectCall())
.append(")\n");
}
else {
declaration
.append(localSessionName())
.append(getObjectCall())
.append(".")
.append(createQueryMethod())
.append('(');
Expand Down Expand Up @@ -138,6 +140,7 @@ private void createBuilder(StringBuilder declaration) {
declaration
.append("\tvar _builder = ")
.append(localSessionName())
.append(getObjectCall())
.append(".getCriteriaBuilder();\n");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ void tryReturn(StringBuilder declaration) {
}
declaration
.append("\treturn ")
.append(sessionName);
.append(sessionName)
.append(getObjectCall());
}

void modifiers(StringBuilder declaration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
private final boolean managed;
private boolean jakartaDataRepository;
private final boolean quarkusInjection;
private final boolean springInjection;
private String qualifiedName;
private final boolean jakartaDataStaticModel;

Expand Down Expand Up @@ -180,6 +181,7 @@ public AnnotationMetaEntity(
this.managed = managed;
this.members = new LinkedHashMap<>();
this.quarkusInjection = context.isQuarkusInjection();
this.springInjection = context.isSpringInjection();
this.importContext = parent != null ? parent : new ImportContextImpl( getPackageName( context, element ) );
jakartaDataStaticModel = jakartaDataStaticMetamodel;
importContext.importType(
Expand Down Expand Up @@ -769,20 +771,24 @@ private void setupSession() {
sessionType = addDaoConstructor( getter );
}
else {
// For Panache subtypes, we look at the session type, but no DAO, we want static methods
// For Panache subtypes, we look at the session type, but no DAO,
// we want static methods
sessionType = fullReturnType(getter);
}
}
else if ( element.getKind() == ElementKind.INTERFACE
&& !jakartaDataRepository
&& ( context.usesQuarkusOrm() || context.usesQuarkusReactive() ) ) {
// if we don't have a getter, and not a JD repository, but we're in Quarkus, we know how to find the default sessions
// if we don't have a getter, and not a JD repository, 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;
sessionType = springInjection
? SPRING_STATELESS_SESSION_PROVIDER
: HIB_STATELESS_SESSION;
addDaoConstructor( null );
}
if ( needsDefaultConstructor() ) {
Expand Down Expand Up @@ -819,6 +825,7 @@ void addEventBus() {
boolean needsDefaultConstructor() {
return jakartaDataRepository
&& !quarkusInjection
&& !springInjection
&& context.addDependentAnnotation();
}

Expand Down Expand Up @@ -863,6 +870,10 @@ public boolean isReactiveSessionAccess() {
return usingReactiveSessionAccess(sessionType);
}

public boolean isProvidedSessionAccess() {
return sessionType.startsWith(SPRING_OBJECT_PROVIDER);
}

private boolean isPanacheType(TypeElement type) {
return context.usesQuarkusOrm() && isOrmPanacheType( type )
|| context.usesQuarkusReactive() && isReactivePanacheType( type );
Expand Down Expand Up @@ -940,7 +951,7 @@ private String setupQuarkusDaoConstructor() {
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;
return UNI_MUTINY_SESSION;
}
}

Expand All @@ -950,23 +961,37 @@ private String setupQuarkusDaoConstructor() {
* needed return types.
*/
private static boolean isSessionGetter(ExecutableElement method) {
if ( method.getParameters().isEmpty() ) {
final TypeMirror returnType = method.getReturnType();
if ( returnType.getKind() == TypeKind.DECLARED ) {
final DeclaredType declaredType = (DeclaredType) ununi(returnType);
final Element element = declaredType.asElement();
if ( element.getKind() == ElementKind.INTERFACE ) {
final TypeElement typeElement = (TypeElement) element;
final Name name = typeElement.getQualifiedName();
return method.getParameters().isEmpty()
&& isSessionGetterType( method.getReturnType() );
}

private static boolean isSessionGetterType(TypeMirror returnType) {
if ( returnType.getKind() == TypeKind.DECLARED ) {
final DeclaredType declaredType = (DeclaredType) ununi( returnType );
final Element element = declaredType.asElement();
if ( element.getKind() == ElementKind.INTERFACE ) {
final TypeElement typeElement = (TypeElement) element;
final Name name = typeElement.getQualifiedName();
if ( name.contentEquals(UNI) || name.contentEquals(SPRING_OBJECT_PROVIDER) ) {
final var typeArguments = declaredType.getTypeArguments();
return typeArguments.size() == 1
&& isSessionGetterType( typeArguments.get( 0 ) );
}
else {
return name.contentEquals(HIB_SESSION)
|| name.contentEquals(HIB_STATELESS_SESSION)
|| name.contentEquals(MUTINY_SESSION)
|| name.contentEquals(MUTINY_STATELESS_SESSION)
|| name.contentEquals(ENTITY_MANAGER);
}
}
else {
return false;
}
}
else {
return false;
}
return false;
}

/**
Expand Down Expand Up @@ -2054,7 +2079,9 @@ protected String getSessionVariableName() {

private String getSessionVariableName(String sessionType) {
return switch (sessionType) {
case HIB_SESSION, HIB_STATELESS_SESSION, MUTINY_SESSION, MUTINY_STATELESS_SESSION -> "session";
case HIB_SESSION, HIB_STATELESS_SESSION,
MUTINY_SESSION, MUTINY_STATELESS_SESSION,
SPRING_STATELESS_SESSION_PROVIDER -> "session";
// case UNI_MUTINY_SESSION, UNI_MUTINY_STATELESS_SESSION -> "session";
default -> sessionGetter;
};
Expand Down Expand Up @@ -3388,7 +3415,8 @@ private static boolean usingReactiveSession(String sessionType) {
private static boolean usingStatelessSession(String sessionType) {
return HIB_STATELESS_SESSION.equals(sessionType)
|| MUTINY_STATELESS_SESSION.equals(sessionType)
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType);
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType)
|| SPRING_STATELESS_SESSION_PROVIDER.equals(sessionType);
}

private static boolean usingReactiveSessionAccess(String sessionType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ else if (!nullable && !isReactive()) {
.append("\treturn ");
}
declaration
.append(sessionName);
.append(sessionName)
.append(getObjectCall());
}

private void findWithFetchProfiles(StringBuilder declaration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,13 @@ private void delegateBlockingly(StringBuilder declaration) {
declaration
.append("\t\tif (")
.append(sessionName)
.append(getObjectCall())
.append(".getIdentifier(")
.append(parameterName)
.append(") == null)\n")
.append("\t\t\t")
.append(sessionName)
.append(getObjectCall())
.append('.')
.append("insert");
argument( declaration );
Expand All @@ -231,6 +233,7 @@ private void delegateBlockingly(StringBuilder declaration) {
declaration
.append("\t\t")
.append(sessionName)
.append(getObjectCall())
.append('.')
.append(operationName);
argument( declaration );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,14 @@ void createQuery(StringBuilder declaration) {
declaration
.append("_spec.createQuery(")
.append(localSessionName())
.append(getObjectCall())
.append(")\n");
}
}
else {
declaration
.append(localSessionName())
.append(getObjectCall())
.append('.')
.append(createQueryMethod())
.append("(")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public String getAttributeDeclarationString() {
}
declaration
.append("}");
// resource accessor method a.k.a. session getter
if ( annotationMetaEntity.getSuperTypeElement() == null ) {
declaration
.append("\n\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,23 +158,30 @@ public final class Constants {
public static final String PANACHE_REACTIVE_REPOSITORY_BASE = "io.quarkus.hibernate.reactive.panache.PanacheRepositoryBase";
public static final String PANACHE_REACTIVE_ENTITY_BASE = "io.quarkus.hibernate.reactive.panache.PanacheEntityBase";

public static final String SPRING_OBJECT_PROVIDER = "org.springframework.beans.factory.ObjectProvider";
public static final String SPRING_STATELESS_SESSION_PROVIDER = SPRING_OBJECT_PROVIDER + "<" + HIB_STATELESS_SESSION + ">";
public static final String SPRING_COMPONENT = "org.springframework.stereotype.Component";

public static final Map<String, String> COLLECTIONS = Map.of(
COLLECTION, Constants.COLLECTION_ATTRIBUTE,
SET, Constants.SET_ATTRIBUTE,
LIST, Constants.LIST_ATTRIBUTE,
MAP, Constants.MAP_ATTRIBUTE,
COLLECTION, COLLECTION_ATTRIBUTE,
SET, SET_ATTRIBUTE,
LIST, LIST_ATTRIBUTE,
MAP, MAP_ATTRIBUTE,
// Hibernate also supports the SortedSet and SortedMap interfaces
java.util.SortedSet.class.getName(), Constants.SET_ATTRIBUTE,
java.util.SortedMap.class.getName(), Constants.MAP_ATTRIBUTE
java.util.SortedSet.class.getName(), SET_ATTRIBUTE,
java.util.SortedMap.class.getName(), MAP_ATTRIBUTE
);

public static final Set<String> SESSION_TYPES =
Set.of(
Constants.ENTITY_MANAGER,
Constants.HIB_SESSION,
Constants.HIB_STATELESS_SESSION,
Constants.MUTINY_SESSION,
Constants.UNI_MUTINY_SESSION
ENTITY_MANAGER,
HIB_SESSION,
HIB_STATELESS_SESSION,
MUTINY_SESSION,
MUTINY_STATELESS_SESSION,
UNI_MUTINY_SESSION,
UNI_MUTINY_STATELESS_SESSION,
SPRING_STATELESS_SESSION_PROVIDER
);

//TODO: this is not even an exhaustive list of built-in basic types
Expand Down