HHH-16633 allow finder and query methods to accept the session type as a parameter
This commit is contained in:
parent
a80224f921
commit
803cd6aa1e
|
@ -7,7 +7,6 @@
|
|||
package org.hibernate.jpamodelgen.annotation;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
|
||||
|
@ -19,41 +18,24 @@ import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFr
|
|||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public abstract class AbstractFinderMethod implements MetaAttribute {
|
||||
final Metamodel annotationMetaEntity;
|
||||
final String methodName;
|
||||
public abstract class AbstractFinderMethod extends AbstractQueryMethod {
|
||||
final String entity;
|
||||
final boolean belongsToDao;
|
||||
final String sessionType;
|
||||
final boolean usingEntityManager;
|
||||
final boolean reactive;
|
||||
private final boolean addNonnullAnnotation;
|
||||
final List<String> fetchProfiles;
|
||||
|
||||
final List<String> paramNames;
|
||||
final List<String> paramTypes;
|
||||
|
||||
public AbstractFinderMethod(
|
||||
Metamodel annotationMetaEntity,
|
||||
String methodName,
|
||||
String entity,
|
||||
boolean belongsToDao,
|
||||
String sessionType,
|
||||
String sessionName,
|
||||
List<String> fetchProfiles,
|
||||
List<String> paramNames,
|
||||
List<String> paramTypes,
|
||||
boolean addNonnullAnnotation) {
|
||||
this.annotationMetaEntity = annotationMetaEntity;
|
||||
this.methodName = methodName;
|
||||
super( annotationMetaEntity, methodName, paramNames, paramTypes, sessionType, sessionName, belongsToDao, addNonnullAnnotation );
|
||||
this.entity = entity;
|
||||
this.belongsToDao = belongsToDao;
|
||||
this.sessionType = sessionType;
|
||||
this.fetchProfiles = fetchProfiles;
|
||||
this.paramNames = paramNames;
|
||||
this.paramTypes = paramTypes;
|
||||
this.addNonnullAnnotation = addNonnullAnnotation;
|
||||
this.usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
|
||||
this.reactive = Constants.MUTINY_SESSION.equals(sessionType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,26 +48,11 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetaType() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPropertyName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metamodel getHostingEntity() {
|
||||
return annotationMetaEntity;
|
||||
}
|
||||
|
||||
abstract boolean isId();
|
||||
|
||||
@Override
|
||||
|
@ -104,20 +71,6 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
|
|||
.toString();
|
||||
}
|
||||
|
||||
private String parameterList() {
|
||||
return paramTypes.stream()
|
||||
.map(this::strip)
|
||||
.map(annotationMetaEntity::importType)
|
||||
.reduce((x, y) -> x + ',' + y)
|
||||
.orElse("");
|
||||
}
|
||||
|
||||
private String strip(String type) {
|
||||
int index = type.indexOf("<");
|
||||
String stripped = index > 0 ? type.substring(0, index) : type;
|
||||
return type.endsWith("...") ? stripped + "..." : stripped;
|
||||
}
|
||||
|
||||
String constantName() {
|
||||
return getUpperUnderscoreCaseFromLowerCamelCase(methodName) + "_BY_"
|
||||
+ paramNames.stream()
|
||||
|
@ -212,7 +165,8 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
|
|||
parameters( declaration) ;
|
||||
declaration
|
||||
.append(" {")
|
||||
.append("\n\treturn entityManager");
|
||||
.append("\n\treturn ")
|
||||
.append(sessionName);
|
||||
}
|
||||
|
||||
private void entityType(StringBuilder declaration) {
|
||||
|
@ -237,12 +191,7 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
|
|||
void parameters(StringBuilder declaration) {
|
||||
declaration
|
||||
.append("(");
|
||||
if ( !belongsToDao ) {
|
||||
notNull( declaration );
|
||||
declaration
|
||||
.append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER))
|
||||
.append(" entityManager");
|
||||
}
|
||||
sessionParameter( declaration );
|
||||
for ( int i = 0; i < paramNames.size(); i ++ ) {
|
||||
if ( !belongsToDao || i > 0 ) {
|
||||
declaration
|
||||
|
@ -259,13 +208,4 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
|
|||
declaration
|
||||
.append(')');
|
||||
}
|
||||
|
||||
private void notNull(StringBuilder declaration) {
|
||||
if ( addNonnullAnnotation ) {
|
||||
declaration
|
||||
.append('@')
|
||||
.append(annotationMetaEntity.importType("jakarta.annotation.Nonnull"))
|
||||
.append(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpamodelgen.annotation;
|
||||
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hibernate.jpamodelgen.util.Constants.SESSION_TYPES;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public abstract class AbstractQueryMethod implements MetaAttribute {
|
||||
final Metamodel annotationMetaEntity;
|
||||
final String methodName;
|
||||
final List<String> paramNames;
|
||||
final List<String> paramTypes;
|
||||
final String sessionType;
|
||||
final String sessionName;
|
||||
final boolean belongsToDao;
|
||||
final boolean usingEntityManager;
|
||||
final boolean reactive;
|
||||
final boolean addNonnullAnnotation;
|
||||
|
||||
public AbstractQueryMethod(
|
||||
Metamodel annotationMetaEntity,
|
||||
String methodName,
|
||||
List<String> paramNames, List<String> paramTypes,
|
||||
String sessionType,
|
||||
String sessionName,
|
||||
boolean belongsToDao,
|
||||
boolean addNonnullAnnotation) {
|
||||
this.annotationMetaEntity = annotationMetaEntity;
|
||||
this.methodName = methodName;
|
||||
this.paramNames = paramNames;
|
||||
this.paramTypes = paramTypes;
|
||||
this.sessionType = sessionType;
|
||||
this.sessionName = sessionName;
|
||||
this.belongsToDao = belongsToDao;
|
||||
this.addNonnullAnnotation = addNonnullAnnotation;
|
||||
this.usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
|
||||
this.reactive = Constants.MUTINY_SESSION.equals(sessionType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metamodel getHostingEntity() {
|
||||
return annotationMetaEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetaType() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPropertyName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
String parameterList() {
|
||||
return paramTypes.stream()
|
||||
.map(this::strip)
|
||||
.map(annotationMetaEntity::importType)
|
||||
.reduce((x, y) -> x + ',' + y)
|
||||
.orElse("");
|
||||
}
|
||||
|
||||
String strip(String type) {
|
||||
int index = type.indexOf("<");
|
||||
String stripped = index > 0 ? type.substring(0, index) : type;
|
||||
return type.endsWith("...") ? stripped + "..." : stripped;
|
||||
}
|
||||
|
||||
void sessionParameter(StringBuilder declaration) {
|
||||
if ( !belongsToDao ) {
|
||||
notNull(declaration);
|
||||
declaration
|
||||
.append(annotationMetaEntity.importType(sessionType))
|
||||
.append(' ')
|
||||
.append(sessionName);
|
||||
}
|
||||
}
|
||||
|
||||
void notNull(StringBuilder declaration) {
|
||||
if ( addNonnullAnnotation ) {
|
||||
declaration
|
||||
.append('@')
|
||||
.append(annotationMetaEntity.importType("jakarta.annotation.Nonnull"))
|
||||
.append(' ');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,6 +49,7 @@ import static javax.lang.model.util.ElementFilter.fieldsIn;
|
|||
import static javax.lang.model.util.ElementFilter.methodsIn;
|
||||
import static org.hibernate.jpamodelgen.annotation.QueryMethod.isOrderParam;
|
||||
import static org.hibernate.jpamodelgen.annotation.QueryMethod.isPageParam;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.SESSION_TYPES;
|
||||
import static org.hibernate.jpamodelgen.util.NullnessUtil.castNonNull;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.containsAnnotation;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.determineAccessTypeForHierarchy;
|
||||
|
@ -494,7 +495,11 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
createCriteriaFinder( method, returnType, containerType, entity );
|
||||
}
|
||||
else {
|
||||
switch ( method.getParameters().size() ) {
|
||||
final long parameterCount =
|
||||
method.getParameters().stream()
|
||||
.filter(AnnotationMetaEntity::isFinderParameterMappingToAttribute)
|
||||
.count();
|
||||
switch ( (int) parameterCount ) {
|
||||
case 0:
|
||||
context.message( method, "missing parameter", Diagnostic.Kind.ERROR );
|
||||
break;
|
||||
|
@ -517,9 +522,13 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
final String methodName = method.getSimpleName().toString();
|
||||
final List<String> paramNames = parameterNames(method);
|
||||
final List<String> paramTypes = parameterTypes(method);
|
||||
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
|
||||
removeSessionFromParameters(paramNames, paramTypes);
|
||||
final String methodKey = methodName + paramTypes;
|
||||
for ( VariableElement param : method.getParameters() ) {
|
||||
validateFinderParameter(entity, param );
|
||||
if ( isFinderParameterMappingToAttribute( param ) ) {
|
||||
validateFinderParameter( entity, param );
|
||||
}
|
||||
}
|
||||
putMember( methodKey,
|
||||
new CriteriaFinderMethod(
|
||||
|
@ -531,13 +540,40 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
paramTypes,
|
||||
false,
|
||||
dao,
|
||||
sessionType,
|
||||
sessionType[0],
|
||||
sessionType[1],
|
||||
enabledFetchProfiles( method ),
|
||||
context.addNonnullAnnotation()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean isFinderParameterMappingToAttribute(VariableElement param) {
|
||||
return !SESSION_TYPES.contains(param.asType().toString());
|
||||
}
|
||||
|
||||
private static void removeSessionFromParameters(List<String> paramNames, List<String> paramTypes) {
|
||||
for ( int i = 0; i < paramNames.size(); i ++ ) {
|
||||
final String type = paramTypes.get(i);
|
||||
if ( SESSION_TYPES.contains(type) ) {
|
||||
paramNames.remove(i);
|
||||
paramTypes.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String[] sessionTypeFromParameters(List<String> paramNames, List<String> paramTypes) {
|
||||
for ( int i = 0; i < paramNames.size(); i ++ ) {
|
||||
final String type = paramTypes.get(i);
|
||||
final String name = paramNames.get(i);
|
||||
if ( SESSION_TYPES.contains(type) ) {
|
||||
return new String[] { type, name };
|
||||
}
|
||||
}
|
||||
return new String[] { sessionType, "entityManager" };
|
||||
}
|
||||
|
||||
private static List<String> enabledFetchProfiles(ExecutableElement method) {
|
||||
final Object enabledFetchProfiles =
|
||||
getAnnotationValue( castNonNull( getAnnotationMirror( method, Constants.FIND ) ),
|
||||
|
@ -560,8 +596,10 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
final String methodName = method.getSimpleName().toString();
|
||||
final List<String> paramNames = parameterNames( method );
|
||||
final List<String> paramTypes = parameterTypes( method );
|
||||
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
|
||||
removeSessionFromParameters( paramNames, paramTypes );
|
||||
final String methodKey = methodName + paramTypes;
|
||||
if ( !usingStatelessSession() // no byNaturalId() lookup API for SS
|
||||
if ( !usingStatelessSession(sessionType[0]) // no byNaturalId() lookup API for SS
|
||||
&& matchesNaturalKey( method, entity ) ) {
|
||||
putMember( methodKey,
|
||||
new NaturalIdFinderMethod(
|
||||
|
@ -571,7 +609,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
paramNames,
|
||||
paramTypes,
|
||||
dao,
|
||||
sessionType,
|
||||
sessionType[0],
|
||||
sessionType[1],
|
||||
enabledFetchProfiles( method ),
|
||||
context.addNonnullAnnotation()
|
||||
)
|
||||
|
@ -588,7 +627,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
paramTypes,
|
||||
false,
|
||||
dao,
|
||||
sessionType,
|
||||
sessionType[0],
|
||||
sessionType[1],
|
||||
enabledFetchProfiles( method ),
|
||||
context.addNonnullAnnotation()
|
||||
)
|
||||
|
@ -598,22 +638,30 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
|
||||
private void createSingleParameterFinder(ExecutableElement method, TypeMirror returnType, TypeElement entity) {
|
||||
final String methodName = method.getSimpleName().toString();
|
||||
final VariableElement parameter = method.getParameters().get(0);
|
||||
final VariableElement parameter =
|
||||
method.getParameters().stream()
|
||||
.filter(AnnotationMetaEntity::isFinderParameterMappingToAttribute)
|
||||
.findFirst().orElseThrow();
|
||||
final List<String> paramNames = parameterNames(method);
|
||||
final List<String> paramTypes = parameterTypes(method);
|
||||
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
|
||||
removeSessionFromParameters(paramNames, paramTypes);
|
||||
final FieldType fieldType = validateFinderParameter( entity, parameter );
|
||||
if ( fieldType != null ) {
|
||||
final String methodKey = methodName + "!";
|
||||
final List<String> profiles = enabledFetchProfiles( method );
|
||||
switch ( pickStrategy( fieldType, profiles ) ) {
|
||||
switch ( pickStrategy( fieldType, sessionType[0], profiles ) ) {
|
||||
case ID:
|
||||
putMember( methodKey,
|
||||
new IdFinderMethod(
|
||||
this,
|
||||
methodName,
|
||||
returnType.toString(),
|
||||
parameter.getSimpleName().toString(),
|
||||
parameter.asType().toString(),
|
||||
paramNames.get(0),
|
||||
paramTypes.get(0),
|
||||
dao,
|
||||
sessionType,
|
||||
sessionType[0],
|
||||
sessionType[1],
|
||||
profiles,
|
||||
context.addNonnullAnnotation()
|
||||
)
|
||||
|
@ -625,10 +673,11 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
this,
|
||||
methodName,
|
||||
returnType.toString(),
|
||||
List.of( parameter.getSimpleName().toString() ),
|
||||
List.of( parameter.asType().toString() ),
|
||||
paramNames,
|
||||
paramTypes,
|
||||
dao,
|
||||
sessionType,
|
||||
sessionType[0],
|
||||
sessionType[1],
|
||||
profiles,
|
||||
context.addNonnullAnnotation()
|
||||
)
|
||||
|
@ -641,11 +690,12 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
methodName,
|
||||
returnType.toString(),
|
||||
null,
|
||||
List.of( parameter.getSimpleName().toString() ),
|
||||
List.of( parameter.asType().toString() ),
|
||||
paramNames,
|
||||
paramTypes,
|
||||
fieldType == FieldType.ID,
|
||||
dao,
|
||||
sessionType,
|
||||
sessionType[0],
|
||||
sessionType[1],
|
||||
profiles,
|
||||
context.addNonnullAnnotation()
|
||||
)
|
||||
|
@ -655,16 +705,16 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
}
|
||||
}
|
||||
|
||||
private FieldType pickStrategy(FieldType fieldType, List<String> profiles) {
|
||||
private FieldType pickStrategy(FieldType fieldType, String sessionType, List<String> profiles) {
|
||||
switch (fieldType) {
|
||||
case ID:
|
||||
// no byId() API for SS or M.S, only get()
|
||||
return (usingStatelessSession() || usingReactiveSession()) && !profiles.isEmpty()
|
||||
return (usingStatelessSession(sessionType) || usingReactiveSession(sessionType)) && !profiles.isEmpty()
|
||||
? FieldType.BASIC : FieldType.ID;
|
||||
case NATURAL_ID:
|
||||
// no byNaturalId() lookup API for SS
|
||||
// no byNaturalId() in M.S, but we do have Identifier workaround
|
||||
return usingStatelessSession() || (usingReactiveSession() && !profiles.isEmpty())
|
||||
return usingStatelessSession(sessionType) || (usingReactiveSession(sessionType) && !profiles.isEmpty())
|
||||
? FieldType.BASIC : FieldType.NATURAL_ID;
|
||||
default:
|
||||
return FieldType.BASIC;
|
||||
|
@ -673,12 +723,14 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
|
||||
private boolean matchesNaturalKey(ExecutableElement method, TypeElement entity) {
|
||||
boolean result = true;
|
||||
List<? extends VariableElement> parameters = method.getParameters();
|
||||
for ( VariableElement param : parameters) {
|
||||
if ( validateFinderParameter( entity, param ) != FieldType.NATURAL_ID ) {
|
||||
// no short-circuit here because we want to validate
|
||||
// all of them and get the nice error report
|
||||
result = false;
|
||||
final List<? extends VariableElement> parameters = method.getParameters();
|
||||
for ( VariableElement param : parameters ) {
|
||||
if ( isFinderParameterMappingToAttribute( param ) ) {
|
||||
if ( validateFinderParameter( entity, param ) != FieldType.NATURAL_ID ) {
|
||||
// no short-circuit here because we want to validate
|
||||
// all of them and get the nice error report
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result && countNaturalIdFields( entity ) == parameters.size() ;
|
||||
|
@ -781,7 +833,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
final String hql = (String) query;
|
||||
final List<String> paramNames = parameterNames( method );
|
||||
final List<String> paramTypes = parameterTypes( method );
|
||||
|
||||
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
|
||||
removeSessionFromParameters(paramNames, paramTypes);
|
||||
final QueryMethod attribute =
|
||||
new QueryMethod(
|
||||
this,
|
||||
|
@ -793,7 +846,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
paramTypes,
|
||||
isNative,
|
||||
dao,
|
||||
sessionType,
|
||||
sessionType[0],
|
||||
sessionType[1],
|
||||
context.addNonnullAnnotation()
|
||||
);
|
||||
putMember( attribute.getPropertyName() + paramTypes, attribute );
|
||||
|
@ -923,11 +977,11 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
&& !isOrderParam(type);
|
||||
}
|
||||
|
||||
private boolean usingReactiveSession() {
|
||||
private boolean usingReactiveSession(String sessionType) {
|
||||
return Constants.MUTINY_SESSION.equals(sessionType);
|
||||
}
|
||||
|
||||
private boolean usingStatelessSession() {
|
||||
private boolean usingStatelessSession(String sessionType) {
|
||||
return Constants.HIB_STATELESS_SESSION.equals(sessionType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,9 +29,10 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
boolean isId,
|
||||
boolean belongsToDao,
|
||||
String sessionType,
|
||||
String sessionName,
|
||||
List<String> fetchProfiles,
|
||||
boolean addNonnullAnnotation) {
|
||||
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
|
||||
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles,
|
||||
paramNames, paramTypes, addNonnullAnnotation );
|
||||
this.containerType = containerType;
|
||||
this.isId = isId;
|
||||
|
@ -61,7 +62,8 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
.append(" == null) throw new IllegalArgumentException(\"Null identifier\");");
|
||||
}
|
||||
declaration
|
||||
.append("\n\tvar builder = entityManager")
|
||||
.append("\n\tvar builder = ")
|
||||
.append(sessionName)
|
||||
.append(usingEntityManager
|
||||
? ".getEntityManagerFactory()"
|
||||
: ".getFactory()")
|
||||
|
@ -104,7 +106,9 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
}
|
||||
declaration
|
||||
.append("\n\t);")
|
||||
.append("\n\treturn entityManager.createQuery(query)");
|
||||
.append("\n\treturn ")
|
||||
.append(sessionName)
|
||||
.append(".createQuery(query)");
|
||||
final boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty();
|
||||
final boolean hasNativeReturnType = containerType != null && containerType.startsWith("org.hibernate");
|
||||
final boolean unwrap =
|
||||
|
|
|
@ -25,9 +25,10 @@ public class IdFinderMethod extends AbstractFinderMethod {
|
|||
String paramName, String paramType,
|
||||
boolean belongsToDao,
|
||||
String sessionType,
|
||||
String sessionName,
|
||||
List<String> fetchProfiles,
|
||||
boolean addNonnullAnnotation) {
|
||||
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
|
||||
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles,
|
||||
List.of(paramName), List.of(paramType), addNonnullAnnotation );
|
||||
this.paramName = paramName;
|
||||
usingStatelessSession = Constants.HIB_STATELESS_SESSION.equals(sessionType);
|
||||
|
|
|
@ -21,9 +21,10 @@ public class NaturalIdFinderMethod extends AbstractFinderMethod {
|
|||
List<String> paramNames, List<String> paramTypes,
|
||||
boolean belongsToDao,
|
||||
String sessionType,
|
||||
String sessionName,
|
||||
List<String> fetchProfiles,
|
||||
boolean addNonnullAnnotation) {
|
||||
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
|
||||
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles,
|
||||
paramNames, paramTypes, addNonnullAnnotation );
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.jpamodelgen.annotation;
|
|||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
import org.hibernate.query.Order;
|
||||
|
@ -22,19 +21,11 @@ import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFr
|
|||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class QueryMethod implements MetaAttribute {
|
||||
private final Metamodel annotationMetaEntity;
|
||||
private final String methodName;
|
||||
public class QueryMethod extends AbstractQueryMethod {
|
||||
private final String queryString;
|
||||
private final @Nullable String returnTypeName;
|
||||
private final @Nullable String containerTypeName;
|
||||
private final List<String> paramNames;
|
||||
private final List<String> paramTypes;
|
||||
private final boolean isNative;
|
||||
private final boolean belongsToDao;
|
||||
private final boolean usingEntityManager;
|
||||
private final boolean reactive;
|
||||
private final boolean addNonnullAnnotation;
|
||||
|
||||
public QueryMethod(
|
||||
Metamodel annotationMetaEntity,
|
||||
|
@ -49,19 +40,13 @@ public class QueryMethod implements MetaAttribute {
|
|||
boolean isNative,
|
||||
boolean belongsToDao,
|
||||
String sessionType,
|
||||
String sessionName,
|
||||
boolean addNonnullAnnotation) {
|
||||
this.annotationMetaEntity = annotationMetaEntity;
|
||||
this.methodName = methodName;
|
||||
super( annotationMetaEntity, methodName, paramNames, paramTypes, sessionType, sessionName, belongsToDao, addNonnullAnnotation );
|
||||
this.queryString = queryString;
|
||||
this.returnTypeName = returnTypeName;
|
||||
this.containerTypeName = containerTypeName;
|
||||
this.paramNames = paramNames;
|
||||
this.paramTypes = paramTypes;
|
||||
this.isNative = isNative;
|
||||
this.belongsToDao = belongsToDao;
|
||||
this.addNonnullAnnotation = addNonnullAnnotation;
|
||||
this.usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
|
||||
this.reactive = Constants.MUTINY_SESSION.equals(sessionType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -98,8 +83,8 @@ public class QueryMethod implements MetaAttribute {
|
|||
.append(") ");
|
||||
}
|
||||
declaration
|
||||
.append("entityManager.")
|
||||
.append(isNative ? "createNativeQuery" : "createQuery")
|
||||
.append(sessionName)
|
||||
.append(isNative ? ".createNativeQuery" : ".createQuery")
|
||||
.append("(")
|
||||
.append(getConstantName());
|
||||
if ( returnTypeName != null ) {
|
||||
|
@ -210,30 +195,22 @@ public class QueryMethod implements MetaAttribute {
|
|||
}
|
||||
|
||||
private void parameters(List<String> paramTypes, StringBuilder declaration) {
|
||||
declaration.append("(");
|
||||
if ( !belongsToDao ) {
|
||||
notNull( declaration );
|
||||
declaration
|
||||
.append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER))
|
||||
.append(" entityManager");
|
||||
}
|
||||
|
||||
for (int i = 0; i<paramNames.size(); i++ ) {
|
||||
String ptype = paramTypes.get(i);
|
||||
String param = paramNames.get(i);
|
||||
String rptype = returnTypeName != null
|
||||
? ptype.replace(returnTypeName, annotationMetaEntity.importType(returnTypeName))
|
||||
: ptype;
|
||||
|
||||
if ( !belongsToDao || i>0 ) {
|
||||
declaration
|
||||
.append("(");
|
||||
sessionParameter( declaration );
|
||||
for ( int i = 0; i < paramNames.size(); i++ ) {
|
||||
if ( !belongsToDao || i > 0 ) {
|
||||
declaration
|
||||
.append(", ");
|
||||
}
|
||||
|
||||
final String type = paramTypes.get(i);
|
||||
final String paramType = returnTypeName != null
|
||||
? type.replace(returnTypeName, annotationMetaEntity.importType(returnTypeName))
|
||||
: type;
|
||||
declaration
|
||||
.append(annotationMetaEntity.importType(rptype))
|
||||
.append(annotationMetaEntity.importType(paramType))
|
||||
.append(" ")
|
||||
.append(param);
|
||||
.append(paramNames.get(i));
|
||||
}
|
||||
declaration
|
||||
.append(")");
|
||||
|
@ -301,20 +278,6 @@ public class QueryMethod implements MetaAttribute {
|
|||
}
|
||||
}
|
||||
|
||||
private String parameterList() {
|
||||
return paramTypes.stream()
|
||||
.map(this::strip)
|
||||
.map(annotationMetaEntity::importType)
|
||||
.reduce((x, y) -> x + ',' + y)
|
||||
.orElse("");
|
||||
}
|
||||
|
||||
private String strip(String type) {
|
||||
int index = type.indexOf("<");
|
||||
String stripped = index > 0 ? type.substring(0, index) : type;
|
||||
return type.endsWith("...") ? stripped + "..." : stripped;
|
||||
}
|
||||
|
||||
static boolean isPageParam(String parameterType) {
|
||||
return Page.class.getName().equals(parameterType);
|
||||
}
|
||||
|
@ -359,32 +322,7 @@ public class QueryMethod implements MetaAttribute {
|
|||
}
|
||||
}
|
||||
|
||||
private void notNull(StringBuilder declaration) {
|
||||
if ( addNonnullAnnotation ) {
|
||||
declaration
|
||||
.append('@')
|
||||
.append(annotationMetaEntity.importType("jakarta.annotation.Nonnull"))
|
||||
.append(' ');
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetaType() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPropertyName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration() {
|
||||
return Constants.QUERY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metamodel getHostingEntity() {
|
||||
return annotationMetaEntity;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,14 @@ public final class Constants {
|
|||
java.util.SortedMap.class.getName(), Constants.MAP_ATTRIBUTE
|
||||
);
|
||||
|
||||
public static final Set<String> SESSION_TYPES =
|
||||
Set.of(
|
||||
Constants.ENTITY_MANAGER,
|
||||
Constants.HIB_SESSION,
|
||||
Constants.HIB_STATELESS_SESSION,
|
||||
Constants.MUTINY_SESSION
|
||||
);
|
||||
|
||||
//TODO: this is not even an exhaustive list of built-in basic types
|
||||
// so any logic that relies on incomplete this list is broken!
|
||||
public static final Set<String> BASIC_TYPES = Set.of(
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package org.hibernate.jpamodelgen.test.hqlsql;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.StatelessSession;
|
||||
import org.hibernate.annotations.processing.Find;
|
||||
import org.hibernate.annotations.processing.HQL;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Books {
|
||||
@Find
|
||||
abstract Book getBook(EntityManager entityManager, String isbn);
|
||||
|
||||
@Find
|
||||
abstract Book getBook(StatelessSession session, String title, String isbn);
|
||||
|
||||
@Find
|
||||
abstract Book getBookByNaturalKey(Session session, String authorName, String title);
|
||||
|
||||
@HQL("from Book where title like ?1")
|
||||
abstract TypedQuery<Book> findByTitle(EntityManager entityManager, String title);
|
||||
|
||||
@HQL("from Book where title like ?1 order by title fetch first ?2 rows only")
|
||||
abstract List<Book> findFirstNByTitle(Session session, String title, int N);
|
||||
|
||||
|
||||
}
|
|
@ -18,10 +18,12 @@ import static org.hibernate.jpamodelgen.test.util.TestUtil.assertMetamodelClassG
|
|||
*/
|
||||
public class QueryMethodTest extends CompilationTest {
|
||||
@Test
|
||||
@WithClasses({ Book.class, Dao.class })
|
||||
@WithClasses({ Book.class, Dao.class, Books.class })
|
||||
public void testQueryMethod() {
|
||||
System.out.println( TestUtil.getMetaModelSourceAsString( Dao.class ) );
|
||||
System.out.println( TestUtil.getMetaModelSourceAsString( Books.class ) );
|
||||
assertMetamodelClassGeneratedFor( Book.class );
|
||||
assertMetamodelClassGeneratedFor( Dao.class );
|
||||
assertMetamodelClassGeneratedFor( Books.class );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue