HHH-17891 support method-level interceptors for JD repositories

as required by the spec

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-03-26 20:33:49 +01:00 committed by Christian Beikov
parent 40440a6089
commit 72fab5af89
14 changed files with 86 additions and 21 deletions

View File

@ -3,11 +3,13 @@ package org.hibernate.processor.test.data.eg;
import jakarta.data.repository.CrudRepository; import jakarta.data.repository.CrudRepository;
import jakarta.data.repository.Find; import jakarta.data.repository.Find;
import jakarta.data.repository.Repository; import jakarta.data.repository.Repository;
import jakarta.transaction.Transactional;
import java.util.List; import java.util.List;
@Repository @Repository
public interface Bookshop extends CrudRepository<Book,String> { public interface Bookshop extends CrudRepository<Book,String> {
@Find @Find
@Transactional
List<Book> byPublisher(String publisher_name); List<Book> byPublisher(String publisher_name);
} }

View File

@ -104,7 +104,16 @@ public final class ClassWriter {
for ( MetaAttribute metaMember : members ) { for ( MetaAttribute metaMember : members ) {
if ( metaMember.hasTypedAttribute() ) { if ( metaMember.hasTypedAttribute() ) {
metaMember.getAttributeDeclarationString().lines() metaMember.getAttributeDeclarationString().lines()
.forEach(line -> pw.println('\t' + line)); .forEach(line -> {
pw.println('\t' + line);
if ( line.trim().startsWith("@Override") ) {
metaMember.inheritedAnnotations()
.forEach(x -> {
pw.print('\t');
pw.println(x);
});
}
});
} }
} }
pw.println(); pw.println();

View File

@ -9,10 +9,17 @@ package org.hibernate.processor.annotation;
import org.hibernate.processor.model.MetaAttribute; import org.hibernate.processor.model.MetaAttribute;
import org.hibernate.processor.model.Metamodel; import org.hibernate.processor.model.Metamodel;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.ExecutableElement;
import java.util.List;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import static org.hibernate.processor.annotation.AnnotationMetaEntity.usingReactiveSession; import static org.hibernate.processor.annotation.AnnotationMetaEntity.usingReactiveSession;
import static org.hibernate.processor.annotation.AnnotationMetaEntity.usingReactiveSessionAccess; import static org.hibernate.processor.annotation.AnnotationMetaEntity.usingReactiveSessionAccess;
import static org.hibernate.processor.annotation.AnnotationMetaEntity.usingStatelessSession; import static org.hibernate.processor.annotation.AnnotationMetaEntity.usingStatelessSession;
import static org.hibernate.processor.util.Constants.ENTITY_MANAGER; import static org.hibernate.processor.util.Constants.ENTITY_MANAGER;
import static org.hibernate.processor.util.TypeUtils.hasAnnotation;
/** /**
* @author Gavin King * @author Gavin King
@ -20,11 +27,16 @@ import static org.hibernate.processor.util.Constants.ENTITY_MANAGER;
public abstract class AbstractAnnotatedMethod implements MetaAttribute { public abstract class AbstractAnnotatedMethod implements MetaAttribute {
final AnnotationMetaEntity annotationMetaEntity; final AnnotationMetaEntity annotationMetaEntity;
private final ExecutableElement method;
final String sessionType; final String sessionType;
final String sessionName; final String sessionName;
public AbstractAnnotatedMethod(AnnotationMetaEntity annotationMetaEntity, String sessionName, String sessionType) { public AbstractAnnotatedMethod(
AnnotationMetaEntity annotationMetaEntity,
ExecutableElement method,
String sessionName, String sessionType) {
this.annotationMetaEntity = annotationMetaEntity; this.annotationMetaEntity = annotationMetaEntity;
this.method = method;
this.sessionName = sessionName; this.sessionName = sessionName;
this.sessionType = sessionType; this.sessionType = sessionType;
} }
@ -54,5 +66,16 @@ public abstract class AbstractAnnotatedMethod implements MetaAttribute {
return isReactiveSessionAccess() ? "_session" : sessionName; return isReactiveSessionAccess() ? "_session" : sessionName;
} }
@Override
public List<AnnotationMirror> inheritedAnnotations() {
if ( annotationMetaEntity.isJakartaDataRepository() ) {
return method.getAnnotationMirrors().stream()
.filter(annotationMirror -> hasAnnotation(annotationMirror.getAnnotationType().asElement(),
"jakarta.interceptor.InterceptorBinding"))
.collect(toList());
}
else {
return emptyList();
}
}
} }

View File

@ -6,6 +6,7 @@
*/ */
package org.hibernate.processor.annotation; package org.hibernate.processor.annotation;
import javax.lang.model.element.ExecutableElement;
import java.util.List; import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -21,6 +22,7 @@ public abstract class AbstractCriteriaMethod extends AbstractFinderMethod {
public AbstractCriteriaMethod( public AbstractCriteriaMethod(
AnnotationMetaEntity annotationMetaEntity, AnnotationMetaEntity annotationMetaEntity,
ExecutableElement method,
String methodName, String entity, String methodName, String entity,
boolean belongsToDao, boolean belongsToDao,
String sessionType, String sessionName, String sessionType, String sessionName,
@ -32,7 +34,7 @@ public abstract class AbstractCriteriaMethod extends AbstractFinderMethod {
boolean convertToDataExceptions, boolean convertToDataExceptions,
List<Boolean> multivalued, List<Boolean> multivalued,
List<Boolean> paramPatterns) { List<Boolean> paramPatterns) {
super(annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles, super(annotationMetaEntity, method, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles,
paramNames, paramTypes, orderBys, addNonnullAnnotation, convertToDataExceptions); paramNames, paramTypes, orderBys, addNonnullAnnotation, convertToDataExceptions);
this.multivalued = multivalued; this.multivalued = multivalued;
this.paramPatterns = paramPatterns; this.paramPatterns = paramPatterns;

View File

@ -8,6 +8,7 @@ package org.hibernate.processor.annotation;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import javax.lang.model.element.ExecutableElement;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -24,6 +25,7 @@ public abstract class AbstractFinderMethod extends AbstractQueryMethod {
AbstractFinderMethod( AbstractFinderMethod(
AnnotationMetaEntity annotationMetaEntity, AnnotationMetaEntity annotationMetaEntity,
ExecutableElement method,
String methodName, String methodName,
String entity, String entity,
boolean belongsToDao, boolean belongsToDao,
@ -35,7 +37,7 @@ public abstract class AbstractFinderMethod extends AbstractQueryMethod {
List<OrderBy> orderBys, List<OrderBy> orderBys,
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean convertToDataExceptions) { boolean convertToDataExceptions) {
super( annotationMetaEntity, super( annotationMetaEntity, method,
methodName, methodName,
paramNames, paramTypes, entity, paramNames, paramTypes, entity,
sessionType, sessionName, sessionType, sessionName,

View File

@ -9,6 +9,7 @@ package org.hibernate.processor.annotation;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import javax.lang.model.element.ExecutableElement;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -51,6 +52,7 @@ public abstract class AbstractQueryMethod extends AbstractAnnotatedMethod {
AbstractQueryMethod( AbstractQueryMethod(
AnnotationMetaEntity annotationMetaEntity, AnnotationMetaEntity annotationMetaEntity,
ExecutableElement method,
String methodName, String methodName,
List<String> paramNames, List<String> paramTypes, List<String> paramNames, List<String> paramTypes,
@Nullable String returnTypeName, @Nullable String returnTypeName,
@ -60,7 +62,7 @@ public abstract class AbstractQueryMethod extends AbstractAnnotatedMethod {
List<OrderBy> orderBys, List<OrderBy> orderBys,
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean dataRepository) { boolean dataRepository) {
super(annotationMetaEntity, sessionName, sessionType); super(annotationMetaEntity, method, sessionName, sessionType);
this.methodName = methodName; this.methodName = methodName;
this.paramNames = paramNames; this.paramNames = paramNames;
this.paramTypes = paramTypes; this.paramTypes = paramTypes;

View File

@ -304,6 +304,10 @@ public class AnnotationMetaEntity extends AnnotationMeta {
return repository; return repository;
} }
boolean isJakartaDataRepository() {
return jakartaDataRepository;
}
@Override @Override
String getSessionType() { String getSessionType() {
return sessionType; return sessionType;
@ -1206,7 +1210,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
putMember( putMember(
methodName + '.' + entity, methodName + '.' + entity,
new LifecycleMethod( new LifecycleMethod(
this, this, method,
entity, entity,
methodName, methodName,
parameter.getSimpleName().toString(), parameter.getSimpleName().toString(),
@ -1414,7 +1418,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
} }
putMember( methodKey, putMember( methodKey,
new CriteriaFinderMethod( new CriteriaFinderMethod(
this, this, method,
methodName, methodName,
returnType.toString(), returnType.toString(),
containerType, containerType,
@ -1458,7 +1462,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
} }
putMember( methodKey, putMember( methodKey,
new CriteriaDeleteMethod( new CriteriaDeleteMethod(
this, this, method,
methodName, methodName,
entity.getQualifiedName().toString(), entity.getQualifiedName().toString(),
returnType.toString(), returnType.toString(),
@ -1652,7 +1656,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
&& matchesNaturalKey( entity, fieldTypes ) ) { && matchesNaturalKey( entity, fieldTypes ) ) {
putMember( methodKey, putMember( methodKey,
new NaturalIdFinderMethod( new NaturalIdFinderMethod(
this, this, method,
methodName, methodName,
returnType.toString(), returnType.toString(),
paramNames, paramNames,
@ -1671,7 +1675,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
final List<Boolean> paramPatterns = parameterPatterns( method ); final List<Boolean> paramPatterns = parameterPatterns( method );
putMember( methodKey, putMember( methodKey,
new CriteriaFinderMethod( new CriteriaFinderMethod(
this, this, method,
methodName, methodName,
returnType.toString(), returnType.toString(),
null, null,
@ -1709,7 +1713,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
case ID: case ID:
putMember( methodKey, putMember( methodKey,
new IdFinderMethod( new IdFinderMethod(
this, this, method,
methodName, methodName,
returnType.toString(), returnType.toString(),
paramNames, paramNames,
@ -1726,7 +1730,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
case NATURAL_ID: case NATURAL_ID:
putMember( methodKey, putMember( methodKey,
new NaturalIdFinderMethod( new NaturalIdFinderMethod(
this, this, method,
methodName, methodName,
returnType.toString(), returnType.toString(),
paramNames, paramNames,
@ -1746,7 +1750,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
final List<Boolean> paramPatterns = parameterPatterns( method ); final List<Boolean> paramPatterns = parameterPatterns( method );
putMember( methodKey, putMember( methodKey,
new CriteriaFinderMethod( new CriteriaFinderMethod(
this, this, method,
methodName, methodName,
returnType.toString(), returnType.toString(),
null, null,
@ -2092,7 +2096,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
final QueryMethod attribute = final QueryMethod attribute =
new QueryMethod( new QueryMethod(
this, this, method,
method.getSimpleName().toString(), method.getSimpleName().toString(),
queryString, queryString,
returnType == null ? null : returnType.toString(), returnType == null ? null : returnType.toString(),

View File

@ -6,6 +6,7 @@
*/ */
package org.hibernate.processor.annotation; package org.hibernate.processor.annotation;
import javax.lang.model.element.ExecutableElement;
import java.util.List; import java.util.List;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
@ -20,6 +21,7 @@ public class CriteriaDeleteMethod extends AbstractCriteriaMethod {
CriteriaDeleteMethod( CriteriaDeleteMethod(
AnnotationMetaEntity annotationMetaEntity, AnnotationMetaEntity annotationMetaEntity,
ExecutableElement method,
String methodName, String entity, String returnType, String methodName, String entity, String returnType,
List<String> paramNames, List<String> paramNames,
List<String> paramTypes, List<String> paramTypes,
@ -31,7 +33,7 @@ public class CriteriaDeleteMethod extends AbstractCriteriaMethod {
String sessionName, String sessionName,
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean dataRepository) { boolean dataRepository) {
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, emptyList(), super( annotationMetaEntity, method, methodName, entity, belongsToDao, sessionType, sessionName, emptyList(),
paramNames, paramTypes, emptyList(), addNonnullAnnotation, dataRepository, multivalued, paramPatterns ); paramNames, paramTypes, emptyList(), addNonnullAnnotation, dataRepository, multivalued, paramPatterns );
this.paramNullability = paramNullability; this.paramNullability = paramNullability;
this.returnType = returnType; this.returnType = returnType;

View File

@ -10,6 +10,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.processor.util.Constants; import org.hibernate.processor.util.Constants;
import javax.lang.model.element.ExecutableElement;
import java.util.List; import java.util.List;
/** /**
@ -22,6 +23,7 @@ public class CriteriaFinderMethod extends AbstractCriteriaMethod {
CriteriaFinderMethod( CriteriaFinderMethod(
AnnotationMetaEntity annotationMetaEntity, AnnotationMetaEntity annotationMetaEntity,
ExecutableElement method,
String methodName, String entity, String methodName, String entity,
@Nullable String containerType, @Nullable String containerType,
List<String> paramNames, List<String> paramTypes, List<String> paramNames, List<String> paramTypes,
@ -35,7 +37,7 @@ public class CriteriaFinderMethod extends AbstractCriteriaMethod {
List<OrderBy> orderBys, List<OrderBy> orderBys,
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean dataRepository) { boolean dataRepository) {
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles, super( annotationMetaEntity, method, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles,
paramNames, paramTypes, orderBys, addNonnullAnnotation, dataRepository, multivalued, paramPatterns ); paramNames, paramTypes, orderBys, addNonnullAnnotation, dataRepository, multivalued, paramPatterns );
this.containerType = containerType; this.containerType = containerType;
this.paramNullability = paramNullability; this.paramNullability = paramNullability;

View File

@ -6,6 +6,7 @@
*/ */
package org.hibernate.processor.annotation; package org.hibernate.processor.annotation;
import javax.lang.model.element.ExecutableElement;
import java.util.List; import java.util.List;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
@ -21,6 +22,7 @@ public class IdFinderMethod extends AbstractFinderMethod {
public IdFinderMethod( public IdFinderMethod(
AnnotationMetaEntity annotationMetaEntity, AnnotationMetaEntity annotationMetaEntity,
ExecutableElement method,
String methodName, String entity, String methodName, String entity,
List<String> paramNames, List<String> paramTypes, List<String> paramNames, List<String> paramTypes,
boolean belongsToDao, boolean belongsToDao,
@ -29,7 +31,7 @@ public class IdFinderMethod extends AbstractFinderMethod {
List<String> fetchProfiles, List<String> fetchProfiles,
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean dataRepository) { boolean dataRepository) {
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles, super( annotationMetaEntity, method, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles,
paramNames, paramTypes, emptyList(), addNonnullAnnotation, dataRepository ); paramNames, paramTypes, emptyList(), addNonnullAnnotation, dataRepository );
int idParameter = idParameter(paramNames, paramTypes); int idParameter = idParameter(paramNames, paramTypes);
this.paramName = paramNames.get(idParameter); this.paramName = paramNames.get(idParameter);

View File

@ -6,6 +6,8 @@
*/ */
package org.hibernate.processor.annotation; package org.hibernate.processor.annotation;
import javax.lang.model.element.ExecutableElement;
import static org.hibernate.processor.util.Constants.UNI; import static org.hibernate.processor.util.Constants.UNI;
public class LifecycleMethod extends AbstractAnnotatedMethod { public class LifecycleMethod extends AbstractAnnotatedMethod {
@ -19,6 +21,7 @@ public class LifecycleMethod extends AbstractAnnotatedMethod {
public LifecycleMethod( public LifecycleMethod(
AnnotationMetaEntity annotationMetaEntity, AnnotationMetaEntity annotationMetaEntity,
ExecutableElement method,
String entity, String entity,
String methodName, String methodName,
String parameterName, String parameterName,
@ -28,7 +31,7 @@ public class LifecycleMethod extends AbstractAnnotatedMethod {
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean iterateParameter, boolean iterateParameter,
boolean returnArgument) { boolean returnArgument) {
super(annotationMetaEntity, sessionName, sessionType); super(annotationMetaEntity, method, sessionName, sessionType);
this.entity = entity; this.entity = entity;
this.methodName = methodName; this.methodName = methodName;
this.parameterName = parameterName; this.parameterName = parameterName;

View File

@ -6,6 +6,7 @@
*/ */
package org.hibernate.processor.annotation; package org.hibernate.processor.annotation;
import javax.lang.model.element.ExecutableElement;
import java.util.List; import java.util.List;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
@ -19,6 +20,7 @@ public class NaturalIdFinderMethod extends AbstractFinderMethod {
public NaturalIdFinderMethod( public NaturalIdFinderMethod(
AnnotationMetaEntity annotationMetaEntity, AnnotationMetaEntity annotationMetaEntity,
ExecutableElement method,
String methodName, String entity, String methodName, String entity,
List<String> paramNames, List<String> paramTypes, List<String> paramNames, List<String> paramTypes,
List<Boolean> paramNullability, List<Boolean> paramNullability,
@ -28,7 +30,7 @@ public class NaturalIdFinderMethod extends AbstractFinderMethod {
List<String> fetchProfiles, List<String> fetchProfiles,
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean dataRepository) { boolean dataRepository) {
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles, super( annotationMetaEntity, method, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles,
paramNames, paramTypes, emptyList(), addNonnullAnnotation, dataRepository ); paramNames, paramTypes, emptyList(), addNonnullAnnotation, dataRepository );
this.paramNullability = paramNullability; this.paramNullability = paramNullability;
} }

View File

@ -10,6 +10,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import javax.lang.model.element.ExecutableElement;
import java.util.List; import java.util.List;
import static org.hibernate.processor.util.Constants.QUERY; import static org.hibernate.processor.util.Constants.QUERY;
@ -28,6 +29,7 @@ public class QueryMethod extends AbstractQueryMethod {
QueryMethod( QueryMethod(
AnnotationMetaEntity annotationMetaEntity, AnnotationMetaEntity annotationMetaEntity,
ExecutableElement method,
String methodName, String methodName,
String queryString, String queryString,
@Nullable @Nullable
@ -44,7 +46,7 @@ public class QueryMethod extends AbstractQueryMethod {
List<OrderBy> orderBys, List<OrderBy> orderBys,
boolean addNonnullAnnotation, boolean addNonnullAnnotation,
boolean dataRepository) { boolean dataRepository) {
super( annotationMetaEntity, super( annotationMetaEntity, method,
methodName, methodName,
paramNames, paramTypes, returnTypeName, paramNames, paramTypes, returnTypeName,
sessionType, sessionName, sessionType, sessionName,

View File

@ -6,6 +6,11 @@
*/ */
package org.hibernate.processor.model; package org.hibernate.processor.model;
import javax.lang.model.element.AnnotationMirror;
import java.util.List;
import static java.util.Collections.emptyList;
/** /**
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
@ -27,4 +32,7 @@ public interface MetaAttribute {
Metamodel getHostingEntity(); Metamodel getHostingEntity();
default List<AnnotationMirror> inheritedAnnotations() {
return emptyList();
}
} }