HHH-16633 allow finder and query methods to accept the session (better impl)

This commit is contained in:
Gavin King 2023-07-14 13:58:57 +02:00
parent 803cd6aa1e
commit ded5451436
8 changed files with 211 additions and 170 deletions

View File

@ -33,7 +33,11 @@ public AbstractFinderMethod(
List<String> paramNames, List<String> paramNames,
List<String> paramTypes, List<String> paramTypes,
boolean addNonnullAnnotation) { boolean addNonnullAnnotation) {
super( annotationMetaEntity, methodName, paramNames, paramTypes, sessionType, sessionName, belongsToDao, addNonnullAnnotation ); super( annotationMetaEntity,
methodName,
paramNames, paramTypes, entity,
sessionType, sessionName,
belongsToDao, addNonnullAnnotation );
this.entity = entity; this.entity = entity;
this.fetchProfiles = fetchProfiles; this.fetchProfiles = fetchProfiles;
} }
@ -111,14 +115,8 @@ void comment(StringBuilder declaration) {
} }
declaration declaration
.append('.') .append('.')
.append("\n *") .append("\n *");
.append("\n * @see ") see( declaration );
.append(annotationMetaEntity.getQualifiedName())
.append("#")
.append(methodName)
.append("(")
.append(parameterList())
.append(")");
// declaration // declaration
// .append("\n *"); // .append("\n *");
// for (String param : paramNames) { // for (String param : paramNames) {
@ -133,7 +131,7 @@ void comment(StringBuilder declaration) {
} }
void unwrapSession(StringBuilder declaration) { void unwrapSession(StringBuilder declaration) {
if ( usingEntityManager ) { if ( isUsingEntityManager() ) {
declaration declaration
.append(".unwrap(") .append(".unwrap(")
.append(annotationMetaEntity.importType(Constants.HIB_SESSION)) .append(annotationMetaEntity.importType(Constants.HIB_SESSION))
@ -162,7 +160,7 @@ void preamble(StringBuilder declaration) {
declaration declaration
.append(" ") .append(" ")
.append(methodName); .append(methodName);
parameters( declaration) ; parameters( paramTypes, declaration) ;
declaration declaration
.append(" {") .append(" {")
.append("\n\treturn ") .append("\n\treturn ")
@ -170,14 +168,14 @@ void preamble(StringBuilder declaration) {
} }
private void entityType(StringBuilder declaration) { private void entityType(StringBuilder declaration) {
if ( reactive ) { if ( isReactive() ) {
declaration declaration
.append(annotationMetaEntity.importType(Constants.UNI)) .append(annotationMetaEntity.importType(Constants.UNI))
.append('<'); .append('<');
} }
declaration declaration
.append(annotationMetaEntity.importType(entity)); .append(annotationMetaEntity.importType(entity));
if ( reactive ) { if ( isReactive() ) {
declaration declaration
.append('>'); .append('>');
} }
@ -187,25 +185,4 @@ void modifiers(StringBuilder declaration) {
declaration declaration
.append(belongsToDao ? "@Override\npublic " : "public static "); .append(belongsToDao ? "@Override\npublic " : "public static ");
} }
void parameters(StringBuilder declaration) {
declaration
.append("(");
sessionParameter( declaration );
for ( int i = 0; i < paramNames.size(); i ++ ) {
if ( !belongsToDao || i > 0 ) {
declaration
.append(", ");
}
if ( isId() ) {
notNull( declaration );
}
declaration
.append(annotationMetaEntity.importType(paramTypes.get(i)))
.append(" ")
.append(paramNames.get(i));
}
declaration
.append(')');
}
} }

View File

@ -6,12 +6,12 @@
*/ */
package org.hibernate.jpamodelgen.annotation; package org.hibernate.jpamodelgen.annotation;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.jpamodelgen.model.MetaAttribute; import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel; import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants; import org.hibernate.jpamodelgen.util.Constants;
import java.util.List; import java.util.List;
import java.util.Set;
import static org.hibernate.jpamodelgen.util.Constants.SESSION_TYPES; import static org.hibernate.jpamodelgen.util.Constants.SESSION_TYPES;
@ -23,17 +23,17 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
final String methodName; final String methodName;
final List<String> paramNames; final List<String> paramNames;
final List<String> paramTypes; final List<String> paramTypes;
final @Nullable String returnTypeName;
final String sessionType; final String sessionType;
final String sessionName; final String sessionName;
final boolean belongsToDao; final boolean belongsToDao;
final boolean usingEntityManager;
final boolean reactive;
final boolean addNonnullAnnotation; final boolean addNonnullAnnotation;
public AbstractQueryMethod( public AbstractQueryMethod(
Metamodel annotationMetaEntity, Metamodel annotationMetaEntity,
String methodName, String methodName,
List<String> paramNames, List<String> paramTypes, List<String> paramNames, List<String> paramTypes,
@Nullable String returnTypeName,
String sessionType, String sessionType,
String sessionName, String sessionName,
boolean belongsToDao, boolean belongsToDao,
@ -42,12 +42,11 @@ public AbstractQueryMethod(
this.methodName = methodName; this.methodName = methodName;
this.paramNames = paramNames; this.paramNames = paramNames;
this.paramTypes = paramTypes; this.paramTypes = paramTypes;
this.returnTypeName = returnTypeName;
this.sessionType = sessionType; this.sessionType = sessionType;
this.sessionName = sessionName; this.sessionName = sessionName;
this.belongsToDao = belongsToDao; this.belongsToDao = belongsToDao;
this.addNonnullAnnotation = addNonnullAnnotation; this.addNonnullAnnotation = addNonnullAnnotation;
this.usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
this.reactive = Constants.MUTINY_SESSION.equals(sessionType);
} }
@Override @Override
@ -65,6 +64,8 @@ public String getPropertyName() {
return methodName; return methodName;
} }
abstract boolean isId();
String parameterList() { String parameterList() {
return paramTypes.stream() return paramTypes.stream()
.map(this::strip) .map(this::strip)
@ -79,13 +80,49 @@ String strip(String type) {
return type.endsWith("...") ? stripped + "..." : stripped; return type.endsWith("...") ? stripped + "..." : stripped;
} }
void parameters(List<String> paramTypes, StringBuilder declaration) {
declaration
.append("(");
sessionParameter( declaration );
for ( int i = 0; i < paramNames.size(); i++ ) {
if ( i > 0 ) {
declaration
.append(", ");
}
final String paramType = paramTypes.get(i);
if ( isId() || isSessionParameter(paramType) ) {
notNull( declaration );
}
declaration
.append(annotationMetaEntity.importType(importReturnTypeArgument(paramType)))
.append(" ")
.append(paramNames.get(i));
}
declaration
.append(")");
}
static boolean isSessionParameter(String paramType) {
return SESSION_TYPES.contains(paramType);
}
private String importReturnTypeArgument(String type) {
return returnTypeName != null
? type.replace(returnTypeName, annotationMetaEntity.importType(returnTypeName))
: type;
}
void sessionParameter(StringBuilder declaration) { void sessionParameter(StringBuilder declaration) {
if ( !belongsToDao ) { if ( !belongsToDao && paramTypes.stream().noneMatch(SESSION_TYPES::contains) ) {
notNull(declaration); notNull(declaration);
declaration declaration
.append(annotationMetaEntity.importType(sessionType)) .append(annotationMetaEntity.importType(sessionType))
.append(' ') .append(' ')
.append(sessionName); .append(sessionName);
if ( !paramNames.isEmpty() ) {
declaration
.append(", ");
}
} }
} }
@ -97,4 +134,27 @@ void notNull(StringBuilder declaration) {
.append(' '); .append(' ');
} }
} }
void see(StringBuilder declaration) {
declaration
.append("\n * @see ")
.append(annotationMetaEntity.getQualifiedName())
.append("#")
.append(methodName)
.append("(")
.append(parameterList())
.append(")");
}
boolean isUsingEntityManager() {
return Constants.ENTITY_MANAGER.equals(sessionType);
}
boolean isUsingStatelessSession() {
return Constants.HIB_STATELESS_SESSION.equals(sessionType);
}
boolean isReactive() {
return Constants.MUTINY_SESSION.equals(sessionType);
}
} }

View File

@ -523,7 +523,6 @@ private void createCriteriaFinder(
final List<String> paramNames = parameterNames(method); final List<String> paramNames = parameterNames(method);
final List<String> paramTypes = parameterTypes(method); final List<String> paramTypes = parameterTypes(method);
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes ); final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
removeSessionFromParameters(paramNames, paramTypes);
final String methodKey = methodName + paramTypes; final String methodKey = methodName + paramTypes;
for ( VariableElement param : method.getParameters() ) { for ( VariableElement param : method.getParameters() ) {
if ( isFinderParameterMappingToAttribute( param ) ) { if ( isFinderParameterMappingToAttribute( param ) ) {
@ -549,25 +548,14 @@ private void createCriteriaFinder(
} }
private static boolean isFinderParameterMappingToAttribute(VariableElement param) { private static boolean isFinderParameterMappingToAttribute(VariableElement param) {
return !SESSION_TYPES.contains(param.asType().toString()); return !isSessionParameter( 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) { private String[] sessionTypeFromParameters(List<String> paramNames, List<String> paramTypes) {
for ( int i = 0; i < paramNames.size(); i ++ ) { for ( int i = 0; i < paramNames.size(); i ++ ) {
final String type = paramTypes.get(i); final String type = paramTypes.get(i);
final String name = paramNames.get(i); final String name = paramNames.get(i);
if ( SESSION_TYPES.contains(type) ) { if ( isSessionParameter(type) ) {
return new String[] { type, name }; return new String[] { type, name };
} }
} }
@ -597,7 +585,6 @@ private void createMultipleParameterFinder(ExecutableElement method, TypeMirror
final List<String> paramNames = parameterNames( method ); final List<String> paramNames = parameterNames( method );
final List<String> paramTypes = parameterTypes( method ); final List<String> paramTypes = parameterTypes( method );
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes ); final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
removeSessionFromParameters( paramNames, paramTypes );
final String methodKey = methodName + paramTypes; final String methodKey = methodName + paramTypes;
if ( !usingStatelessSession(sessionType[0]) // no byNaturalId() lookup API for SS if ( !usingStatelessSession(sessionType[0]) // no byNaturalId() lookup API for SS
&& matchesNaturalKey( method, entity ) ) { && matchesNaturalKey( method, entity ) ) {
@ -645,7 +632,6 @@ private void createSingleParameterFinder(ExecutableElement method, TypeMirror re
final List<String> paramNames = parameterNames(method); final List<String> paramNames = parameterNames(method);
final List<String> paramTypes = parameterTypes(method); final List<String> paramTypes = parameterTypes(method);
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes ); final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
removeSessionFromParameters(paramNames, paramTypes);
final FieldType fieldType = validateFinderParameter( entity, parameter ); final FieldType fieldType = validateFinderParameter( entity, parameter );
if ( fieldType != null ) { if ( fieldType != null ) {
final String methodKey = methodName + "!"; final String methodKey = methodName + "!";
@ -657,8 +643,8 @@ private void createSingleParameterFinder(ExecutableElement method, TypeMirror re
this, this,
methodName, methodName,
returnType.toString(), returnType.toString(),
paramNames.get(0), paramNames,
paramTypes.get(0), paramTypes,
dao, dao,
sessionType[0], sessionType[0],
sessionType[1], sessionType[1],
@ -724,8 +710,10 @@ private FieldType pickStrategy(FieldType fieldType, String sessionType, List<Str
private boolean matchesNaturalKey(ExecutableElement method, TypeElement entity) { private boolean matchesNaturalKey(ExecutableElement method, TypeElement entity) {
boolean result = true; boolean result = true;
final List<? extends VariableElement> parameters = method.getParameters(); final List<? extends VariableElement> parameters = method.getParameters();
int count = 0;
for ( VariableElement param : parameters ) { for ( VariableElement param : parameters ) {
if ( isFinderParameterMappingToAttribute( param ) ) { if ( isFinderParameterMappingToAttribute( param ) ) {
count ++;
if ( validateFinderParameter( entity, param ) != FieldType.NATURAL_ID ) { if ( validateFinderParameter( entity, param ) != FieldType.NATURAL_ID ) {
// no short-circuit here because we want to validate // no short-circuit here because we want to validate
// all of them and get the nice error report // all of them and get the nice error report
@ -733,7 +721,7 @@ private boolean matchesNaturalKey(ExecutableElement method, TypeElement entity)
} }
} }
} }
return result && countNaturalIdFields( entity ) == parameters.size() ; return result && countNaturalIdFields( entity ) == count;
} }
enum FieldType { enum FieldType {
@ -834,7 +822,6 @@ private void addQueryMethod(
final List<String> paramNames = parameterNames( method ); final List<String> paramNames = parameterNames( method );
final List<String> paramTypes = parameterTypes( method ); final List<String> paramTypes = parameterTypes( method );
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes ); final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
removeSessionFromParameters(paramNames, paramTypes);
final QueryMethod attribute = final QueryMethod attribute =
new QueryMethod( new QueryMethod(
this, this,
@ -973,10 +960,15 @@ private void checkParameters(
private static boolean parameterIsMissing(String hql, int i, String param, String type) { private static boolean parameterIsMissing(String hql, int i, String param, String type) {
return !hql.matches(".*(:" + param + "|\\?" + i + ")\\b.*") return !hql.matches(".*(:" + param + "|\\?" + i + ")\\b.*")
&& !isSessionParameter(type)
&& !isPageParam(type) && !isPageParam(type)
&& !isOrderParam(type); && !isOrderParam(type);
} }
private static boolean isSessionParameter(String type) {
return SESSION_TYPES.contains(type);
}
private boolean usingReactiveSession(String sessionType) { private boolean usingReactiveSession(String sessionType) {
return Constants.MUTINY_SESSION.equals(sessionType); return Constants.MUTINY_SESSION.equals(sessionType);
} }

View File

@ -52,7 +52,7 @@ public String getAttributeDeclarationString() {
.append(returnType()) .append(returnType())
.append(" ") .append(" ")
.append(methodName); .append(methodName);
parameters( declaration ); parameters( paramTypes, declaration );
declaration declaration
.append(" {"); .append(" {");
if ( isId ) { if ( isId ) {
@ -64,7 +64,7 @@ public String getAttributeDeclarationString() {
declaration declaration
.append("\n\tvar builder = ") .append("\n\tvar builder = ")
.append(sessionName) .append(sessionName)
.append(usingEntityManager .append(isUsingEntityManager()
? ".getEntityManagerFactory()" ? ".getEntityManagerFactory()"
: ".getFactory()") : ".getFactory()")
.append(".getCriteriaBuilder();") .append(".getCriteriaBuilder();")
@ -75,34 +75,40 @@ public String getAttributeDeclarationString() {
.append(annotationMetaEntity.importType(entity)) .append(annotationMetaEntity.importType(entity))
.append(".class);") .append(".class);")
.append("\n\tquery.where("); .append("\n\tquery.where(");
boolean first = true;
for ( int i = 0; i < paramNames.size(); i ++ ) { for ( int i = 0; i < paramNames.size(); i ++ ) {
if ( i>0 ) {
declaration
.append(", ");
}
final String paramName = paramNames.get(i); final String paramName = paramNames.get(i);
final String paramType = paramTypes.get(i); final String paramType = paramTypes.get(i);
declaration if ( !isSessionParameter(paramType) ) {
.append("\n\t\t\t"); if ( first ) {
if ( !isId && !isPrimitive( paramType ) ) { //TODO: check the entity to see if it's @Basic(optional=false) first = false;
}
else {
declaration
.append(", ");
}
declaration declaration
.append(paramName) .append("\n\t\t\t");
.append("==null") if ( !isId && !isPrimitive(paramType) ) { //TODO: check the entity to see if it's @Basic(optional=false)
.append("\n\t\t\t\t? ") declaration
.append("entity.get("); .append(paramName)
.append("==null")
.append("\n\t\t\t\t? ")
.append("entity.get(");
attributeRef( declaration, paramName );
declaration
.append(").isNull()")
.append("\n\t\t\t\t: ");
}
declaration
.append("builder.equal(entity.get(");
attributeRef( declaration, paramName ); attributeRef( declaration, paramName );
declaration declaration
.append(").isNull()") .append("), ")
.append("\n\t\t\t\t: "); //TODO: only safe if we are binding literals as parameters!!!
.append(paramName)
.append(")");
} }
declaration
.append("builder.equal(entity.get(");
attributeRef( declaration, paramName );
declaration
.append("), ")
//TODO: only safe if we are binding literals as parameters!!!
.append(paramName)
.append(")");
} }
declaration declaration
.append("\n\t);") .append("\n\t);")
@ -110,10 +116,11 @@ public String getAttributeDeclarationString() {
.append(sessionName) .append(sessionName)
.append(".createQuery(query)"); .append(".createQuery(query)");
final boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty(); final boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty();
final boolean hasNativeReturnType = containerType != null && containerType.startsWith("org.hibernate"); final boolean hasNativeReturnType =
containerType != null && containerType.startsWith("org.hibernate");
final boolean unwrap = final boolean unwrap =
( hasEnabledFetchProfiles || hasNativeReturnType ) ( hasEnabledFetchProfiles || hasNativeReturnType )
&& usingEntityManager; && isUsingEntityManager();
if ( unwrap ) { if ( unwrap ) {
declaration declaration
.append("\n\t\t\t.unwrap(") .append("\n\t\t\t.unwrap(")
@ -156,7 +163,7 @@ private void attributeRef(StringBuilder declaration, String paramName) {
private StringBuilder returnType() { private StringBuilder returnType() {
StringBuilder type = new StringBuilder(); StringBuilder type = new StringBuilder();
boolean returnsUni = reactive boolean returnsUni = isReactive()
&& (containerType == null || Constants.LIST.equals(containerType)); && (containerType == null || Constants.LIST.equals(containerType));
if ( returnsUni ) { if ( returnsUni ) {
type.append(annotationMetaEntity.importType(Constants.UNI)).append('<'); type.append(annotationMetaEntity.importType(Constants.UNI)).append('<');

View File

@ -17,21 +17,28 @@
public class IdFinderMethod extends AbstractFinderMethod { public class IdFinderMethod extends AbstractFinderMethod {
private final String paramName; private final String paramName;
private final boolean usingStatelessSession;
public IdFinderMethod( public IdFinderMethod(
Metamodel annotationMetaEntity, Metamodel annotationMetaEntity,
String methodName, String entity, String methodName, String entity,
String paramName, String paramType, List<String> paramNames, List<String> paramTypes,
boolean belongsToDao, boolean belongsToDao,
String sessionType, String sessionType,
String sessionName, String sessionName,
List<String> fetchProfiles, List<String> fetchProfiles,
boolean addNonnullAnnotation) { boolean addNonnullAnnotation) {
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles, super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles,
List.of(paramName), List.of(paramType), addNonnullAnnotation ); paramNames, paramTypes, addNonnullAnnotation );
this.paramName = paramName; this.paramName = idParameterName( paramNames, paramTypes );
usingStatelessSession = Constants.HIB_STATELESS_SESSION.equals(sessionType); }
private static String idParameterName(List<String> paramNames, List<String> paramTypes) {
for (int i = 0; i < paramNames.size(); i ++ ) {
if ( !isSessionParameter( paramTypes.get(i) ) ) {
return paramNames.get(i);
}
}
return ""; // should never occur!
} }
@Override @Override
@ -68,7 +75,7 @@ private void findWithFetchProfiles(StringBuilder declaration) {
private void findWithNoFetchProfiles(StringBuilder declaration) { private void findWithNoFetchProfiles(StringBuilder declaration) {
declaration declaration
.append(usingStatelessSession ? ".get(" : ".find(") .append(isUsingStatelessSession() ? ".get(" : ".find(")
.append(annotationMetaEntity.importType(entity)) .append(annotationMetaEntity.importType(entity))
.append(".class, ") .append(".class, ")
.append(paramName) .append(paramName)

View File

@ -40,7 +40,7 @@ public String getAttributeDeclarationString() {
comment( declaration ); comment( declaration );
preamble( declaration ); preamble( declaration );
unwrapSession( declaration ); unwrapSession( declaration );
if ( reactive ) { if ( isReactive() ) {
findReactively( declaration ); findReactively( declaration );
} }
else { else {
@ -57,22 +57,25 @@ private void findBlockingly(StringBuilder declaration) {
.append(".class)"); .append(".class)");
enableFetchProfile( declaration ); enableFetchProfile( declaration );
for ( int i = 0; i < paramNames.size(); i ++ ) { for ( int i = 0; i < paramNames.size(); i ++ ) {
final String paramName = paramNames.get(i); if ( !isSessionParameter( paramTypes.get(i) ) ) {
declaration final String paramName = paramNames.get(i);
.append("\n\t\t\t.using(") declaration
.append(annotationMetaEntity.importType(entity + '_')) .append("\n\t\t\t.using(")
.append('.') .append(annotationMetaEntity.importType(entity + '_'))
.append(paramName) .append('.')
.append(", ") .append(paramName)
.append(paramName) .append(", ")
.append(")"); .append(paramName)
.append(")");
}
} }
declaration declaration
.append("\n\t\t\t.load()"); .append("\n\t\t\t.load()");
} }
private void findReactively(StringBuilder declaration) { private void findReactively(StringBuilder declaration) {
boolean composite = paramNames.size() > 1; boolean composite = paramTypes.stream()
.filter(type -> !isSessionParameter(type)).count()>1;
declaration declaration
.append(".find("); .append(".find(");
if (composite) { if (composite) {
@ -87,25 +90,31 @@ private void findReactively(StringBuilder declaration) {
.append(annotationMetaEntity.importType("org.hibernate.reactive.common.Identifier")) .append(annotationMetaEntity.importType("org.hibernate.reactive.common.Identifier"))
.append(".composite("); .append(".composite(");
} }
boolean first = true;
for ( int i = 0; i < paramNames.size(); i ++ ) { for ( int i = 0; i < paramNames.size(); i ++ ) {
if ( i>0 ) { if ( !isSessionParameter( paramTypes.get(i) ) ) {
if ( first ) {
first = false;
}
else {
declaration
.append(", ");
}
if (composite) {
declaration
.append("\n\t\t\t\t");
}
final String paramName = paramNames.get(i);
declaration declaration
.append(", "); .append(annotationMetaEntity.importType("org.hibernate.reactive.common.Identifier"))
.append(".id(")
.append(annotationMetaEntity.importType(entity + '_'))
.append('.')
.append(paramName)
.append(", ")
.append(paramName)
.append(")");
} }
if (composite) {
declaration
.append("\n\t\t\t\t");
}
final String paramName = paramNames.get(i);
declaration
.append(annotationMetaEntity.importType("org.hibernate.reactive.common.Identifier"))
.append(".id(")
.append(annotationMetaEntity.importType(entity + '_'))
.append('.')
.append(paramName)
.append(", ")
.append(paramName)
.append(")");
} }
if (composite) { if (composite) {
declaration.append("\n\t\t\t)\n\t"); declaration.append("\n\t\t\t)\n\t");

View File

@ -42,7 +42,11 @@ public QueryMethod(
String sessionType, String sessionType,
String sessionName, String sessionName,
boolean addNonnullAnnotation) { boolean addNonnullAnnotation) {
super( annotationMetaEntity, methodName, paramNames, paramTypes, sessionType, sessionName, belongsToDao, addNonnullAnnotation ); super( annotationMetaEntity,
methodName,
paramNames, paramTypes, returnTypeName,
sessionType, sessionName,
belongsToDao, addNonnullAnnotation );
this.queryString = queryString; this.queryString = queryString;
this.returnTypeName = returnTypeName; this.returnTypeName = returnTypeName;
this.containerTypeName = containerTypeName; this.containerTypeName = containerTypeName;
@ -59,6 +63,11 @@ public boolean hasStringAttribute() {
return true; return true;
} }
@Override
boolean isId() {
return false;
}
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
final List<String> paramTypes = parameterTypes(); final List<String> paramTypes = parameterTypes();
@ -75,7 +84,7 @@ public String getAttributeDeclarationString() {
.append(" {") .append(" {")
.append("\n\treturn "); .append("\n\treturn ");
if ( isNative && returnTypeName != null && containerTypeName == null if ( isNative && returnTypeName != null && containerTypeName == null
&& usingEntityManager) { && isUsingEntityManager() ) {
// EntityManager.createNativeQuery() does not return TypedQuery, // EntityManager.createNativeQuery() does not return TypedQuery,
// so we need to cast to the entity type // so we need to cast to the entity type
declaration.append("(") declaration.append("(")
@ -104,7 +113,7 @@ else if ( containerTypeName.equals(Constants.LIST) ) {
.append("\n\t\t\t.getResultList()"); .append("\n\t\t\t.getResultList()");
} }
else { else {
if ( usingEntityManager && !unwrapped if ( isUsingEntityManager() && !unwrapped
&& ( containerTypeName.startsWith("org.hibernate") && ( containerTypeName.startsWith("org.hibernate")
|| isNative && returnTypeName != null ) ) { || isNative && returnTypeName != null ) ) {
declaration declaration
@ -119,21 +128,24 @@ else if ( containerTypeName.equals(Constants.LIST) ) {
} }
private boolean setParameters(List<String> paramTypes, StringBuilder declaration) { private boolean setParameters(List<String> paramTypes, StringBuilder declaration) {
boolean unwrapped = !usingEntityManager; boolean unwrapped = !isUsingEntityManager();
for (int i = 1; i <= paramNames.size(); i++) { for ( int i = 0; i < paramNames.size(); i++ ) {
final String paramName = paramNames.get(i-1); final String paramName = paramNames.get(i);
final String paramType = paramTypes.get(i-1); final String paramType = paramTypes.get(i);
if ( queryString.contains(":" + paramName) ) { if ( !isSessionParameter(paramType) ) {
setNamedParameter( declaration, paramName ); final int ordinal = i+1;
} if ( queryString.contains(":" + paramName) ) {
else if ( queryString.contains("?" + i) ) { setNamedParameter( declaration, paramName );
setOrdinalParameter( declaration, i, paramName ); }
} else if ( queryString.contains("?" + ordinal) ) {
else if ( isPageParam(paramType) ) { setOrdinalParameter( declaration, ordinal, paramName );
setPage( declaration, paramName ); }
} else if ( isPageParam(paramType) ) {
else if ( isOrderParam(paramType) ) { setPage( declaration, paramName );
unwrapped = setOrder( declaration, unwrapped, paramName, paramType ); }
else if ( isOrderParam(paramType) ) {
unwrapped = setOrder( declaration, unwrapped, paramName, paramType );
}
} }
} }
return unwrapped; return unwrapped;
@ -158,7 +170,7 @@ private static void setNamedParameter(StringBuilder declaration, String paramNam
} }
private void setPage(StringBuilder declaration, String paramName) { private void setPage(StringBuilder declaration, String paramName) {
if ( usingEntityManager ) { if ( isUsingEntityManager() ) {
declaration declaration
.append("\n\t\t\t.setFirstResult(") .append("\n\t\t\t.setFirstResult(")
.append(paramName) .append(paramName)
@ -194,31 +206,9 @@ private boolean setOrder(StringBuilder declaration, boolean unwrapped, String pa
return true; return true;
} }
private void parameters(List<String> paramTypes, StringBuilder declaration) {
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(paramType))
.append(" ")
.append(paramNames.get(i));
}
declaration
.append(")");
}
private StringBuilder returnType() { private StringBuilder returnType() {
StringBuilder type = new StringBuilder(); StringBuilder type = new StringBuilder();
boolean returnsUni = reactive boolean returnsUni = isReactive()
&& (containerTypeName == null || Constants.LIST.equals(containerTypeName)); && (containerTypeName == null || Constants.LIST.equals(containerTypeName));
if ( returnsUni ) { if ( returnsUni ) {
type.append(annotationMetaEntity.importType(Constants.UNI)).append('<'); type.append(annotationMetaEntity.importType(Constants.UNI)).append('<');
@ -248,13 +238,9 @@ private List<String> parameterTypes() {
private void comment(StringBuilder declaration) { private void comment(StringBuilder declaration) {
declaration declaration
.append("\n/**\n * @see ") .append("\n/**");
.append(annotationMetaEntity.getQualifiedName()) see( declaration );
.append("#") declaration
.append(methodName)
.append("(")
.append(parameterList())
.append(")")
.append("\n **/\n"); .append("\n **/\n");
} }

View File

@ -19,10 +19,13 @@ public abstract class Books {
@Find @Find
abstract Book getBookByNaturalKey(Session session, String authorName, String title); abstract Book getBookByNaturalKey(Session session, String authorName, String title);
@HQL("from Book where title like ?1") @HQL("from Book where title is not null")
abstract List<Book> allbooks(StatelessSession ss);
@HQL("from Book where title like ?2")
abstract TypedQuery<Book> findByTitle(EntityManager entityManager, String title); abstract TypedQuery<Book> findByTitle(EntityManager entityManager, String title);
@HQL("from Book where title like ?1 order by title fetch first ?2 rows only") @HQL("from Book where title like ?2 order by title fetch first ?3 rows only")
abstract List<Book> findFirstNByTitle(Session session, String title, int N); abstract List<Book> findFirstNByTitle(Session session, String title, int N);