HHH-16633 correct handling of null values in criteria-based @Find methods

This commit is contained in:
Gavin King 2023-07-10 12:30:51 +02:00
parent 78843fb2a9
commit 02e395c96d
2 changed files with 49 additions and 5 deletions

View File

@ -479,6 +479,9 @@ public class AnnotationMetaEntity extends AnnotationMeta {
} }
} }
/**
* Create a finder method which returns multiple results.
*/
private void createCriteriaFinder( private void createCriteriaFinder(
ExecutableElement method, TypeMirror returnType, @Nullable TypeElement containerType, TypeElement entity) { ExecutableElement method, TypeMirror returnType, @Nullable TypeElement containerType, TypeElement entity) {
final String methodName = method.getSimpleName().toString(); final String methodName = method.getSimpleName().toString();
@ -496,6 +499,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
containerType == null ? null : containerType.toString(), containerType == null ? null : containerType.toString(),
paramNames, paramNames,
paramTypes, paramTypes,
false,
dao, dao,
sessionType, sessionType,
enabledFetchProfiles( method ) enabledFetchProfiles( method )
@ -550,6 +554,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
null, null,
paramNames, paramNames,
paramTypes, paramTypes,
false,
dao, dao,
sessionType, sessionType,
enabledFetchProfiles( method ) enabledFetchProfiles( method )
@ -607,6 +612,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
null, null,
List.of( parameter.getSimpleName().toString() ), List.of( parameter.getSimpleName().toString() ),
List.of( parameter.asType().toString() ), List.of( parameter.asType().toString() ),
fieldType == FieldType.ID,
dao, dao,
sessionType, sessionType,
enabledFetchProfiles( method ) enabledFetchProfiles( method )

View File

@ -11,6 +11,7 @@ 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;
/** /**
* @author Gavin King * @author Gavin King
@ -18,18 +19,21 @@ import java.util.List;
public class CriteriaFinderMethod extends AbstractFinderMethod { public class CriteriaFinderMethod extends AbstractFinderMethod {
private final @Nullable String containerType; private final @Nullable String containerType;
private final boolean isId;
public CriteriaFinderMethod( public CriteriaFinderMethod(
Metamodel annotationMetaEntity, Metamodel annotationMetaEntity,
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,
boolean isId,
boolean belongsToDao, boolean belongsToDao,
String sessionType, String sessionType,
List<String> fetchProfiles) { List<String> fetchProfiles) {
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles, super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
paramNames, paramTypes ); paramNames, paramTypes );
this.containerType = containerType; this.containerType = containerType;
this.isId = isId;
} }
@Override @Override
@ -43,7 +47,14 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
.append(methodName); .append(methodName);
parameters( declaration ); parameters( declaration );
declaration declaration
.append(" {") .append(" {");
if ( isId ) {
declaration
.append("\n\tif (")
.append(paramNames.get(0))
.append(" == null) throw new IllegalArgumentException(\"Null identifier\");");
}
declaration
.append("\n\tvar builder = entityManager") .append("\n\tvar builder = entityManager")
.append(usingEntityManager .append(usingEntityManager
? ".getEntityManagerFactory()" ? ".getEntityManagerFactory()"
@ -62,11 +73,24 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
.append(", "); .append(", ");
} }
final String paramName = paramNames.get(i); final String paramName = paramNames.get(i);
final String paramType = paramTypes.get(i);
declaration
.append("\n\t\t\t");
if ( !isId && !isPrimitive( paramType ) ) { //TODO: check the entity to see if it's @Basic(optional=false)
declaration
.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 );
declaration declaration
.append("\n\t\t\tbuilder.equal(entity.get(")
.append(annotationMetaEntity.importType(entity + '_'))
.append('.')
.append(paramName)
.append("), ") .append("), ")
//TODO: only safe if we are binding literals as parameters!!! //TODO: only safe if we are binding literals as parameters!!!
.append(paramName) .append(paramName)
@ -106,6 +130,20 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
return declaration.toString(); return declaration.toString();
} }
private static boolean isPrimitive(String paramType) {
return PRIMITIVE_TYPES.contains( paramType );
}
private static final Set<String> PRIMITIVE_TYPES =
Set.of("boolean", "char", "long", "int", "short", "byte", "double", "float");
private void attributeRef(StringBuilder declaration, String paramName) {
declaration
.append(annotationMetaEntity.importType(entity + '_'))
.append('.')
.append(paramName);
}
private StringBuilder returnType() { private StringBuilder returnType() {
StringBuilder type = new StringBuilder(); StringBuilder type = new StringBuilder();
if ( containerType != null ) { if ( containerType != null ) {