Skip to content

Commit 7b73bf0

Browse files
committed
HHH-19606 experimental Spring support for Jakarta Data repositories
1 parent af82013 commit 7b73bf0

File tree

12 files changed

+113
-28
lines changed

12 files changed

+113
-28
lines changed

tooling/metamodel-generator/src/main/java/org/hibernate/processor/ClassWriter.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.List;
3030
import java.util.Set;
3131

32+
import static org.hibernate.processor.util.Constants.SPRING_COMPONENT;
3233
import static org.hibernate.processor.util.TypeUtils.getGeneratedClassFullyQualifiedName;
3334
import static org.hibernate.processor.util.TypeUtils.isMemberType;
3435

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

9596
pw.println( entity.javadoc() );
9697

98+
if ( context.addComponentAnnotation() && entity.isInjectable() ) {
99+
pw.println( writeComponentAnnotation( entity ) );
100+
}
97101
if ( context.addDependentAnnotation() && entity.isInjectable() ) {
98102
pw.println( writeScopeAnnotation( entity ) );
99103
}
@@ -314,6 +318,10 @@ private static String writeScopeAnnotation(Metamodel entity) {
314318
return "@" + entity.importType( entity.scope() );
315319
}
316320

321+
private static String writeComponentAnnotation(Metamodel entity) {
322+
return "@" + entity.importType( SPRING_COMPONENT );
323+
}
324+
317325
private static String writeStaticMetaModelAnnotation(Metamodel entity) {
318326
final String annotation = entity.isJakartaDataStyle()
319327
? "jakarta.data.metamodel.StaticMetamodel"

tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public final class Context {
8484
private Boolean fullyXmlConfigured;
8585
private boolean addInjectAnnotation = false;
8686
private boolean addDependentAnnotation = false;
87+
private boolean addComponentAnnotation = false;
8788
private boolean addNonnullAnnotation = false;
8889
private boolean addGeneratedAnnotation = true;
8990
private boolean addGenerationDate;
@@ -92,6 +93,7 @@ public final class Context {
9293
private AccessType persistenceUnitDefaultAccessType;
9394
private boolean generateJakartaDataStaticMetamodel;
9495
private boolean quarkusInjection;
96+
private boolean springInjection;
9597
private boolean dataEventPackageAvailable;
9698

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

178+
public boolean addComponentAnnotation() {
179+
return addComponentAnnotation;
180+
}
181+
182+
public void setAddComponentAnnotation(boolean addComponentAnnotation) {
183+
this.addComponentAnnotation = addComponentAnnotation;
184+
}
185+
176186
public boolean addNonnullAnnotation() {
177187
return addNonnullAnnotation;
178188
}
@@ -225,6 +235,14 @@ public void setQuarkusInjection(boolean quarkusInjection) {
225235
this.quarkusInjection = quarkusInjection;
226236
}
227237

238+
public boolean isSpringInjection() {
239+
return springInjection;
240+
}
241+
242+
public void setSpringInjection(boolean springInjection) {
243+
this.springInjection = springInjection;
244+
}
245+
228246
public boolean isDataEventPackageAvailable() {
229247
return dataEventPackageAvailable;
230248
}

tooling/metamodel-generator/src/main/java/org/hibernate/processor/HibernateProcessor.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,13 @@ && packagePresent(quarkusOrmPanachePackage) ) {
266266
quarkusOrmPanachePackage = quarkusReactivePanachePackage = null;
267267
}
268268

269+
final PackageElement springBeansPackage =
270+
context.getProcessingEnvironment().getElementUtils()
271+
.getPackageElement( "org.springframework.beans.factory" );
272+
final PackageElement springStereotypePackage =
273+
context.getProcessingEnvironment().getElementUtils()
274+
.getPackageElement( "org.springframework.stereotype" );
275+
269276
context.setAddInjectAnnotation( packagePresent(jakartaInjectPackage) );
270277
context.setAddNonnullAnnotation( packagePresent(jakartaAnnotationPackage) );
271278
context.setAddGeneratedAnnotation( packagePresent(jakartaAnnotationPackage) );
@@ -275,6 +282,8 @@ && packagePresent(quarkusOrmPanachePackage) ) {
275282
context.setQuarkusInjection( packagePresent(quarkusOrmPackage) || packagePresent(quarkusReactivePackage) );
276283
context.setUsesQuarkusOrm( packagePresent(quarkusOrmPanachePackage) );
277284
context.setUsesQuarkusReactive( packagePresent(quarkusReactivePanachePackage) );
285+
context.setSpringInjection( packagePresent(springBeansPackage) );
286+
context.setAddComponentAnnotation( packagePresent(springStereotypePackage) );
278287

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

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AbstractAnnotatedMethod.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ String localSessionName() {
6363
return isReactiveSessionAccess() ? "_session" : sessionName;
6464
}
6565

66+
String getObjectCall() {
67+
return annotationMetaEntity.isProvidedSessionAccess() ? ".getObject()" : "";
68+
}
69+
6670
@Override
6771
public List<AnnotationMirror> inheritedAnnotations() {
6872
if ( annotationMetaEntity.isJakartaDataRepository() ) {

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AbstractCriteriaMethod.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,13 @@ void createQuery(StringBuilder declaration) {
8686
declaration
8787
.append("_spec.createQuery(")
8888
.append(localSessionName())
89+
.append(getObjectCall())
8990
.append(")\n");
9091
}
9192
else {
9293
declaration
9394
.append(localSessionName())
95+
.append(getObjectCall())
9496
.append(".")
9597
.append(createQueryMethod())
9698
.append('(');
@@ -138,6 +140,7 @@ private void createBuilder(StringBuilder declaration) {
138140
declaration
139141
.append("\tvar _builder = ")
140142
.append(localSessionName())
143+
.append(getObjectCall())
141144
.append(".getCriteriaBuilder();\n");
142145
}
143146

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AbstractFinderMethod.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ void tryReturn(StringBuilder declaration) {
170170
}
171171
declaration
172172
.append("\treturn ")
173-
.append(sessionName);
173+
.append(sessionName)
174+
.append(getObjectCall());
174175
}
175176

176177
void modifiers(StringBuilder declaration) {

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
124124
private final boolean managed;
125125
private boolean jakartaDataRepository;
126126
private final boolean quarkusInjection;
127+
private final boolean springInjection;
127128
private String qualifiedName;
128129
private final boolean jakartaDataStaticModel;
129130

@@ -180,6 +181,7 @@ public AnnotationMetaEntity(
180181
this.managed = managed;
181182
this.members = new LinkedHashMap<>();
182183
this.quarkusInjection = context.isQuarkusInjection();
184+
this.springInjection = context.isSpringInjection();
183185
this.importContext = parent != null ? parent : new ImportContextImpl( getPackageName( context, element ) );
184186
jakartaDataStaticModel = jakartaDataStaticMetamodel;
185187
importContext.importType(
@@ -769,20 +771,24 @@ private void setupSession() {
769771
sessionType = addDaoConstructor( getter );
770772
}
771773
else {
772-
// For Panache subtypes, we look at the session type, but no DAO, we want static methods
774+
// For Panache subtypes, we look at the session type, but no DAO,
775+
// we want static methods
773776
sessionType = fullReturnType(getter);
774777
}
775778
}
776779
else if ( element.getKind() == ElementKind.INTERFACE
777780
&& !jakartaDataRepository
778781
&& ( context.usesQuarkusOrm() || context.usesQuarkusReactive() ) ) {
779-
// 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
782+
// if we don't have a getter, and not a JD repository, but we're in Quarkus,
783+
// we know how to find the default sessions
780784
repository = true;
781785
sessionType = setupQuarkusDaoConstructor();
782786
}
783787
if ( !repository && jakartaDataRepository ) {
784788
repository = true;
785-
sessionType = HIB_STATELESS_SESSION;
789+
sessionType = springInjection
790+
? SPRING_STATELESS_SESSION_PROVIDER
791+
: HIB_STATELESS_SESSION;
786792
addDaoConstructor( null );
787793
}
788794
if ( needsDefaultConstructor() ) {
@@ -819,6 +825,7 @@ void addEventBus() {
819825
boolean needsDefaultConstructor() {
820826
return jakartaDataRepository
821827
&& !quarkusInjection
828+
&& !springInjection
822829
&& context.addDependentAnnotation();
823830
}
824831

@@ -863,6 +870,10 @@ public boolean isReactiveSessionAccess() {
863870
return usingReactiveSessionAccess(sessionType);
864871
}
865872

873+
public boolean isProvidedSessionAccess() {
874+
return sessionType.startsWith(SPRING_OBJECT_PROVIDER);
875+
}
876+
866877
private boolean isPanacheType(TypeElement type) {
867878
return context.usesQuarkusOrm() && isOrmPanacheType( type )
868879
|| context.usesQuarkusReactive() && isReactivePanacheType( type );
@@ -940,7 +951,7 @@ private String setupQuarkusDaoConstructor() {
940951
importType( Constants.QUARKUS_SESSION_OPERATIONS );
941952
// use this getter to get the method, do not generate an injection point for its type
942953
sessionGetter = "SessionOperations.getSession()";
943-
return Constants.UNI_MUTINY_SESSION;
954+
return UNI_MUTINY_SESSION;
944955
}
945956
}
946957

@@ -950,23 +961,37 @@ private String setupQuarkusDaoConstructor() {
950961
* needed return types.
951962
*/
952963
private static boolean isSessionGetter(ExecutableElement method) {
953-
if ( method.getParameters().isEmpty() ) {
954-
final TypeMirror returnType = method.getReturnType();
955-
if ( returnType.getKind() == TypeKind.DECLARED ) {
956-
final DeclaredType declaredType = (DeclaredType) ununi(returnType);
957-
final Element element = declaredType.asElement();
958-
if ( element.getKind() == ElementKind.INTERFACE ) {
959-
final TypeElement typeElement = (TypeElement) element;
960-
final Name name = typeElement.getQualifiedName();
964+
return method.getParameters().isEmpty()
965+
&& isSessionGetterType( method.getReturnType() );
966+
}
967+
968+
private static boolean isSessionGetterType(TypeMirror returnType) {
969+
if ( returnType.getKind() == TypeKind.DECLARED ) {
970+
final DeclaredType declaredType = (DeclaredType) ununi( returnType );
971+
final Element element = declaredType.asElement();
972+
if ( element.getKind() == ElementKind.INTERFACE ) {
973+
final TypeElement typeElement = (TypeElement) element;
974+
final Name name = typeElement.getQualifiedName();
975+
if ( name.contentEquals(UNI) || name.contentEquals(SPRING_OBJECT_PROVIDER) ) {
976+
final var typeArguments = declaredType.getTypeArguments();
977+
return typeArguments.size() == 1
978+
&& isSessionGetterType( typeArguments.get( 0 ) );
979+
}
980+
else {
961981
return name.contentEquals(HIB_SESSION)
962982
|| name.contentEquals(HIB_STATELESS_SESSION)
963983
|| name.contentEquals(MUTINY_SESSION)
964984
|| name.contentEquals(MUTINY_STATELESS_SESSION)
965985
|| name.contentEquals(ENTITY_MANAGER);
966986
}
967987
}
988+
else {
989+
return false;
990+
}
991+
}
992+
else {
993+
return false;
968994
}
969-
return false;
970995
}
971996

972997
/**
@@ -2054,7 +2079,9 @@ protected String getSessionVariableName() {
20542079

20552080
private String getSessionVariableName(String sessionType) {
20562081
return switch (sessionType) {
2057-
case HIB_SESSION, HIB_STATELESS_SESSION, MUTINY_SESSION, MUTINY_STATELESS_SESSION -> "session";
2082+
case HIB_SESSION, HIB_STATELESS_SESSION,
2083+
MUTINY_SESSION, MUTINY_STATELESS_SESSION,
2084+
SPRING_STATELESS_SESSION_PROVIDER -> "session";
20582085
// case UNI_MUTINY_SESSION, UNI_MUTINY_STATELESS_SESSION -> "session";
20592086
default -> sessionGetter;
20602087
};
@@ -3388,7 +3415,8 @@ private static boolean usingReactiveSession(String sessionType) {
33883415
private static boolean usingStatelessSession(String sessionType) {
33893416
return HIB_STATELESS_SESSION.equals(sessionType)
33903417
|| MUTINY_STATELESS_SESSION.equals(sessionType)
3391-
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType);
3418+
|| UNI_MUTINY_STATELESS_SESSION.equals(sessionType)
3419+
|| SPRING_STATELESS_SESSION_PROVIDER.equals(sessionType);
33923420
}
33933421

33943422
private static boolean usingReactiveSessionAccess(String sessionType) {

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/IdFinderMethod.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ else if (!nullable && !isReactive()) {
179179
.append("\treturn ");
180180
}
181181
declaration
182-
.append(sessionName);
182+
.append(sessionName)
183+
.append(getObjectCall());
183184
}
184185

185186
private void findWithFetchProfiles(StringBuilder declaration) {

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/LifecycleMethod.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,13 @@ private void delegateBlockingly(StringBuilder declaration) {
216216
declaration
217217
.append("\t\tif (")
218218
.append(sessionName)
219+
.append(getObjectCall())
219220
.append(".getIdentifier(")
220221
.append(parameterName)
221222
.append(") == null)\n")
222223
.append("\t\t\t")
223224
.append(sessionName)
225+
.append(getObjectCall())
224226
.append('.')
225227
.append("insert");
226228
argument( declaration );
@@ -231,6 +233,7 @@ private void delegateBlockingly(StringBuilder declaration) {
231233
declaration
232234
.append("\t\t")
233235
.append(sessionName)
236+
.append(getObjectCall())
234237
.append('.')
235238
.append(operationName);
236239
argument( declaration );

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/QueryMethod.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,14 @@ void createQuery(StringBuilder declaration) {
129129
declaration
130130
.append("_spec.createQuery(")
131131
.append(localSessionName())
132+
.append(getObjectCall())
132133
.append(")\n");
133134
}
134135
}
135136
else {
136137
declaration
137138
.append(localSessionName())
139+
.append(getObjectCall())
138140
.append('.')
139141
.append(createQueryMethod())
140142
.append("(")

0 commit comments

Comments
 (0)