HHH-17868 introduce @Pattern annotation
This commit is contained in:
parent
b5bfe07d36
commit
bcc3ea60de
|
@ -487,6 +487,14 @@ The natural syntax would be a parameter declaration like `String publisher.name`
|
||||||
List<Book> getBooksByPublisherName(String publisher$name);
|
List<Book> getBooksByPublisherName(String publisher$name);
|
||||||
----
|
----
|
||||||
|
|
||||||
|
The `@Pattern` annotation may be applied to a parameter of type `String`, indicating that the argument is a wildcarded pattern which will be compared using `like`.
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
@Find
|
||||||
|
List<Book> getBooksByTitle(@Pattern String title, Type type);
|
||||||
|
----
|
||||||
|
|
||||||
A finder method may specify <<fetch-profiles,fetch profiles>>, for example:
|
A finder method may specify <<fetch-profiles,fetch profiles>>, for example:
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* 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.annotations.processing;
|
||||||
|
|
||||||
|
import jakarta.persistence.criteria.Expression;
|
||||||
|
import org.hibernate.Incubating;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.PARAMETER;
|
||||||
|
import static java.lang.annotation.RetentionPolicy.CLASS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that a parameter of type {@link String} of a
|
||||||
|
* {@linkplain Find finder method} is a pattern involving
|
||||||
|
* wildcard characters {@code _} and {@code %}.
|
||||||
|
* <p>
|
||||||
|
* For example:
|
||||||
|
* <pre>
|
||||||
|
* @Find
|
||||||
|
* List<Book> getBooksWithTitle(@Pattern String title);
|
||||||
|
* </pre>
|
||||||
|
* <p>
|
||||||
|
* A parameter annotated {@code @Pattern} results in a
|
||||||
|
* {@link jakarta.persistence.criteria.CriteriaBuilder#like(Expression, String) like}
|
||||||
|
* condition in the generated code.
|
||||||
|
*
|
||||||
|
* @see Find
|
||||||
|
*
|
||||||
|
* @since 6.5
|
||||||
|
* @author Gavin King
|
||||||
|
*/
|
||||||
|
@Target(PARAMETER)
|
||||||
|
@Retention(CLASS)
|
||||||
|
@Incubating
|
||||||
|
public @interface Pattern {
|
||||||
|
}
|
|
@ -1010,6 +1010,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
final String methodName = method.getSimpleName().toString();
|
final String methodName = method.getSimpleName().toString();
|
||||||
final List<String> paramNames = parameterNames( method, entity );
|
final List<String> paramNames = parameterNames( method, entity );
|
||||||
final List<String> paramTypes = parameterTypes( method );
|
final List<String> paramTypes = parameterTypes( method );
|
||||||
|
final List<Boolean> paramPatterns = parameterPatterns( method );
|
||||||
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
|
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
|
||||||
final String methodKey = methodName + paramTypes;
|
final String methodKey = methodName + paramTypes;
|
||||||
final List<Boolean> multivalued = new ArrayList<>();
|
final List<Boolean> multivalued = new ArrayList<>();
|
||||||
|
@ -1044,6 +1045,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
paramTypes,
|
paramTypes,
|
||||||
parameterNullability(method, entity),
|
parameterNullability(method, entity),
|
||||||
multivalued,
|
multivalued,
|
||||||
|
paramPatterns,
|
||||||
repository,
|
repository,
|
||||||
sessionType[0],
|
sessionType[0],
|
||||||
sessionType[1],
|
sessionType[1],
|
||||||
|
@ -1243,6 +1245,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
final List<Boolean> paramPatterns = parameterPatterns( method );
|
||||||
putMember( methodKey,
|
putMember( methodKey,
|
||||||
new CriteriaFinderMethod(
|
new CriteriaFinderMethod(
|
||||||
this,
|
this,
|
||||||
|
@ -1253,6 +1256,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
paramTypes,
|
paramTypes,
|
||||||
parameterNullability(method, entity),
|
parameterNullability(method, entity),
|
||||||
multivalued,
|
multivalued,
|
||||||
|
paramPatterns,
|
||||||
repository,
|
repository,
|
||||||
sessionType[0],
|
sessionType[0],
|
||||||
sessionType[1],
|
sessionType[1],
|
||||||
|
@ -1316,6 +1320,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
break;
|
break;
|
||||||
case BASIC:
|
case BASIC:
|
||||||
case MULTIVALUED:
|
case MULTIVALUED:
|
||||||
|
final List<Boolean> paramPatterns = parameterPatterns( method );
|
||||||
putMember( methodKey,
|
putMember( methodKey,
|
||||||
new CriteriaFinderMethod(
|
new CriteriaFinderMethod(
|
||||||
this,
|
this,
|
||||||
|
@ -1329,6 +1334,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
.map(param -> isFinderParameterMappingToAttribute(param)
|
.map(param -> isFinderParameterMappingToAttribute(param)
|
||||||
&& fieldType == FieldType.MULTIVALUED)
|
&& fieldType == FieldType.MULTIVALUED)
|
||||||
.collect(toList()),
|
.collect(toList()),
|
||||||
|
paramPatterns,
|
||||||
repository,
|
repository,
|
||||||
sessionType[0],
|
sessionType[0],
|
||||||
sessionType[1],
|
sessionType[1],
|
||||||
|
@ -1398,6 +1404,14 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
if ( checkParameterType( entityType, param, memberType( member ) ) ) {
|
if ( checkParameterType( entityType, param, memberType( member ) ) ) {
|
||||||
return FieldType.MULTIVALUED;
|
return FieldType.MULTIVALUED;
|
||||||
}
|
}
|
||||||
|
else if ( containsAnnotation( param, PATTERN ) ) {
|
||||||
|
final AnnotationMirror mirror = getAnnotationMirror(param, PATTERN);
|
||||||
|
if ( mirror!=null && !param.asType().toString().equals( String.class.getName() ) ) {
|
||||||
|
context.message( param, mirror, "parameter annotated '@Pattern' is not of type 'String'",
|
||||||
|
Diagnostic.Kind.ERROR );
|
||||||
|
}
|
||||||
|
return FieldType.BASIC;
|
||||||
|
}
|
||||||
else if ( containsAnnotation( member, ID, EMBEDDED_ID ) ) {
|
else if ( containsAnnotation( member, ID, EMBEDDED_ID ) ) {
|
||||||
return FieldType.ID;
|
return FieldType.ID;
|
||||||
}
|
}
|
||||||
|
@ -2042,6 +2056,12 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
.collect(toList());
|
.collect(toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<Boolean> parameterPatterns(ExecutableElement method) {
|
||||||
|
return method.getParameters().stream()
|
||||||
|
.map(param -> hasAnnotation(param, PATTERN))
|
||||||
|
.collect(toList());
|
||||||
|
}
|
||||||
|
|
||||||
private List<String> parameterNames(ExecutableElement method, TypeElement entity) {
|
private List<String> parameterNames(ExecutableElement method, TypeElement entity) {
|
||||||
final String idName =
|
final String idName =
|
||||||
// account for special @By("#id") hack in Jakarta Data
|
// account for special @By("#id") hack in Jakarta Data
|
||||||
|
|
|
@ -26,6 +26,7 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
||||||
private final @Nullable String containerType;
|
private final @Nullable String containerType;
|
||||||
private final List<Boolean> paramNullability;
|
private final List<Boolean> paramNullability;
|
||||||
private final List<Boolean> multivalued;
|
private final List<Boolean> multivalued;
|
||||||
|
private final List<Boolean> paramPatterns;
|
||||||
|
|
||||||
CriteriaFinderMethod(
|
CriteriaFinderMethod(
|
||||||
AnnotationMetaEntity annotationMetaEntity,
|
AnnotationMetaEntity annotationMetaEntity,
|
||||||
|
@ -34,6 +35,7 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
||||||
List<String> paramNames, List<String> paramTypes,
|
List<String> paramNames, List<String> paramTypes,
|
||||||
List<Boolean> paramNullability,
|
List<Boolean> paramNullability,
|
||||||
List<Boolean> multivalued,
|
List<Boolean> multivalued,
|
||||||
|
List<Boolean> paramPatterns,
|
||||||
boolean belongsToDao,
|
boolean belongsToDao,
|
||||||
String sessionType,
|
String sessionType,
|
||||||
String sessionName,
|
String sessionName,
|
||||||
|
@ -46,6 +48,7 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
||||||
this.containerType = containerType;
|
this.containerType = containerType;
|
||||||
this.paramNullability = paramNullability;
|
this.paramNullability = paramNullability;
|
||||||
this.multivalued = multivalued;
|
this.multivalued = multivalued;
|
||||||
|
this.paramPatterns = paramPatterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -221,7 +224,9 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
||||||
else {
|
else {
|
||||||
//TODO: change to use Expression.equalTo() in JPA 3.2
|
//TODO: change to use Expression.equalTo() in JPA 3.2
|
||||||
declaration
|
declaration
|
||||||
.append("_builder.equal(_entity");
|
.append("_builder.")
|
||||||
|
.append(paramPatterns.get(i) ? "like" : "equal")
|
||||||
|
.append("(_entity");
|
||||||
path( declaration, paramName );
|
path( declaration, paramName );
|
||||||
declaration
|
declaration
|
||||||
.append(", ")
|
.append(", ")
|
||||||
|
|
|
@ -60,6 +60,7 @@ public final class Constants {
|
||||||
public static final String HQL = "org.hibernate.annotations.processing.HQL";
|
public static final String HQL = "org.hibernate.annotations.processing.HQL";
|
||||||
public static final String SQL = "org.hibernate.annotations.processing.SQL";
|
public static final String SQL = "org.hibernate.annotations.processing.SQL";
|
||||||
public static final String FIND = "org.hibernate.annotations.processing.Find";
|
public static final String FIND = "org.hibernate.annotations.processing.Find";
|
||||||
|
public static final String PATTERN = "org.hibernate.annotations.processing.Pattern";
|
||||||
|
|
||||||
public static final String JD_REPOSITORY = "jakarta.data.repository.Repository";
|
public static final String JD_REPOSITORY = "jakarta.data.repository.Repository";
|
||||||
public static final String JD_QUERY = "jakarta.data.repository.Query";
|
public static final String JD_QUERY = "jakarta.data.repository.Query";
|
||||||
|
|
|
@ -4,6 +4,7 @@ import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.TypedQuery;
|
import jakarta.persistence.TypedQuery;
|
||||||
import org.hibernate.annotations.processing.Find;
|
import org.hibernate.annotations.processing.Find;
|
||||||
import org.hibernate.annotations.processing.HQL;
|
import org.hibernate.annotations.processing.HQL;
|
||||||
|
import org.hibernate.annotations.processing.Pattern;
|
||||||
import org.hibernate.annotations.processing.SQL;
|
import org.hibernate.annotations.processing.SQL;
|
||||||
import org.hibernate.query.Order;
|
import org.hibernate.query.Order;
|
||||||
import org.hibernate.query.Page;
|
import org.hibernate.query.Page;
|
||||||
|
@ -35,7 +36,7 @@ public interface Dao {
|
||||||
Book getBookFetching(String isbn);
|
Book getBookFetching(String isbn);
|
||||||
|
|
||||||
@Find
|
@Find
|
||||||
Book getBook(String title, String author);
|
Book getBook(@Pattern String title, String author);
|
||||||
|
|
||||||
@Find(enabledFetchProfiles="Hello")
|
@Find(enabledFetchProfiles="Hello")
|
||||||
Book getBookFetching(String title, String author);
|
Book getBookFetching(String title, String author);
|
||||||
|
|
Loading…
Reference in New Issue