@@ -1907,34 +1907,27 @@ private void addStaticQueryMethod(
19071907 boolean isNative ) {
19081908 final var value = getAnnotationValue ( mirror );
19091909 if ( value != null && value .getValue () instanceof String queryString ) {
1910+ final var validate = shouldValidateStaticQueryMethod ( method );
19101911 final var methodReturnType =
19111912 unwrappedReturnTypeIfPossible ( method , memberMethodType ( method ).getReturnType () );
19121913 final var queryReturnType =
1913- staticQueryReturnType ( method , methodReturnType , mirror , value , queryString );
1914+ staticQueryReturnType ( method , methodReturnType , mirror , value , queryString , validate );
19141915 if ( queryReturnType != null ) {
19151916 final var paramNames = staticQueryParameterNames ( method );
19161917 final var paramTypes = parameterTypes ( method );
1917- final TypeElement entity ;
1918- if ( isNative ) {
1919- entity = null ;
1920- if ( !repository || method .isDefault () ) {
1921- validateNativeQueryHasNoDynamicAugmentation ( method , mirror , paramTypes );
1918+ final var returnType = queryReturnType .validationReturnType ;
1919+ final var entityType =
1920+ isNative ? null : querySelectionEntity ( method , returnType , mirror , queryString , validate );
1921+ if ( validate ) {
1922+ final var type = entityType == null ? returnType : entityType .asType ();
1923+ checkParameters ( method , type , paramNames , paramTypes , mirror , value , queryString , isNative );
1924+ if ( isNative ) {
1925+ validateSql ( method , mirror , queryString , paramNames , value );
1926+ }
1927+ else {
1928+ final var processedQuery = staticQueryValidationString ( type , mirror , queryString );
1929+ validateHql ( method , type , mirror , value , processedQuery , paramNames , paramTypes );
19221930 }
1923- }
1924- else {
1925- entity = querySelectionEntity ( method , queryReturnType .validationReturnType , mirror , queryString );
1926- }
1927- final var validationReturnType = entity == null ? queryReturnType .validationReturnType : entity .asType ();
1928- final var processedQuery =
1929- staticQueryValidationString ( validationReturnType , mirror , queryString );
1930- checkParameters ( method , validationReturnType ,
1931- paramNames , paramTypes , mirror , value , queryString , isNative );
1932- if ( isNative ) {
1933- validateSql ( method , mirror , queryString , paramNames , value );
1934- }
1935- else {
1936- validateHql ( method , validationReturnType ,
1937- mirror , value , processedQuery , paramNames , paramTypes );
19381931 }
19391932 if ( canBindReferenceArguments ( queryString , isNative , paramNames , paramTypes ) ) {
19401933 final var referenceParamNames = queryParameterNames ( paramNames , paramTypes );
@@ -1947,12 +1940,12 @@ private void addStaticQueryMethod(
19471940 method .getSimpleName ().toString (),
19481941 queryReturnType .statement ,
19491942 isNative ,
1950- entity == null
1943+ entityType == null
19511944 ? queryReturnType .resultTypeName
1952- : entity .getQualifiedName ().toString (),
1953- entity == null
1945+ : entityType .getQualifiedName ().toString (),
1946+ entityType == null
19541947 ? queryReturnType .resultTypeClass
1955- : entity .getQualifiedName ().toString (),
1948+ : entityType .getQualifiedName ().toString (),
19561949 paramTypes ,
19571950 referenceParamNames ,
19581951 referenceParamTypes ,
@@ -1964,6 +1957,16 @@ private void addStaticQueryMethod(
19641957 }
19651958 }
19661959
1960+ /**
1961+ * For a repository method validation is done during generation of
1962+ * the {@code _Repo} class, and we don't need to duplicate it for
1963+ * the {@code Repo_} class which contains only static references.
1964+ */
1965+ private boolean shouldValidateStaticQueryMethod (ExecutableElement method ) {
1966+ return !repositoryQueryMetamodel
1967+ || method .isDefault (); //TODO: is this necessary?
1968+ }
1969+
19671970 private String staticQueryValidationString (
19681971 @ Nullable TypeMirror returnType ,
19691972 AnnotationMirror mirror ,
@@ -1985,17 +1988,18 @@ private String staticQueryValidationString(
19851988 TypeMirror methodReturnType ,
19861989 AnnotationMirror mirror ,
19871990 AnnotationValue value ,
1988- String queryString ) {
1991+ String queryString ,
1992+ boolean validate ) {
19891993 final var statement = isMutationStatement ( queryString );
19901994 return switch ( methodReturnType .getKind () ) {
19911995 case VOID -> statement
19921996 ? new StaticQueryReturnType ( true , null , null , methodReturnType )
1993- : illegalStaticQueryReturnType ( method , mirror , value );
1997+ : illegalStaticQueryReturnType ( method , mirror , value , validate );
19941998 case BOOLEAN , BYTE , SHORT , INT , LONG , CHAR , FLOAT , DOUBLE -> {
19951999 if ( statement ) {
19962000 yield switch ( methodReturnType .getKind () ) {
19972001 case BOOLEAN , INT , LONG -> new StaticQueryReturnType ( true , null , null , methodReturnType );
1998- default -> illegalStaticQueryReturnType ( method , mirror , value );
2002+ default -> illegalStaticQueryReturnType ( method , mirror , value , validate );
19992003 };
20002004 }
20012005 else {
@@ -2012,7 +2016,9 @@ yield new StaticQueryReturnType( false,
20122016 }
20132017 else {
20142018 final var queryResultType = staticQueryResultType ( (DeclaredType ) methodReturnType );
2015- resultType ( method , queryResultType , mirror , value );
2019+ if ( validate ) {
2020+ resultType ( method , queryResultType , mirror , value );
2021+ }
20162022 yield new StaticQueryReturnType ( false ,
20172023 typeAsString ( queryResultType ),
20182024 returnTypeClass ( queryResultType ),
@@ -2026,18 +2032,21 @@ yield new StaticQueryReturnType( false,
20262032 returnTypeClass ( queryResultType ),
20272033 queryResultType );
20282034 }
2029- default -> illegalStaticQueryReturnType ( method , mirror , value );
2035+ default -> illegalStaticQueryReturnType ( method , mirror , value , validate );
20302036 };
20312037 }
20322038
20332039 private @ Nullable StaticQueryReturnType illegalStaticQueryReturnType (
20342040 ExecutableElement method ,
20352041 AnnotationMirror mirror ,
2036- AnnotationValue value ) {
2037- message ( method , mirror , value ,
2038- "static query method must return a referenceable query result type,"
2039- + " or a legal mutation result type: 'void', 'boolean', 'int', or 'long'" ,
2040- Diagnostic .Kind .ERROR );
2042+ AnnotationValue value ,
2043+ boolean validate ) {
2044+ if ( validate ) {
2045+ message ( method , mirror , value ,
2046+ "static query method must return a referenceable query result type,"
2047+ + " or a legal mutation result type: 'void', 'boolean', 'int', or 'long'" ,
2048+ Diagnostic .Kind .ERROR );
2049+ }
20412050 return null ;
20422051 }
20432052
@@ -3114,17 +3123,26 @@ private record SelectedAttribute(String path, TypeMirror type) {
31143123 @ Nullable TypeMirror returnType ,
31153124 AnnotationMirror query ,
31163125 String queryString ) {
3126+ return querySelectionEntity ( method , returnType , query , queryString , true );
3127+ }
3128+
3129+ private @ Nullable TypeElement querySelectionEntity (
3130+ ExecutableElement method ,
3131+ @ Nullable TypeMirror returnType ,
3132+ AnnotationMirror query ,
3133+ String queryString ,
3134+ boolean validate ) {
31173135 final var explicitMethodSelect = hasSelectAnnotation ( method );
31183136 if ( returnType == null ) {
3119- if ( explicitMethodSelect ) {
3137+ if ( validate && explicitMethodSelect ) {
31203138 message ( method , query ,
31213139 "'@Select' requires a concrete query result type" ,
31223140 Diagnostic .Kind .ERROR );
31233141 }
31243142 return null ;
31253143 }
31263144 if ( isMutationStatement ( queryString ) ) {
3127- if ( explicitMethodSelect ) {
3145+ if ( validate && explicitMethodSelect ) {
31283146 message ( method , query ,
31293147 "'@Select' may not be used on a mutation query" ,
31303148 Diagnostic .Kind .ERROR );
@@ -3136,23 +3154,23 @@ private record SelectedAttribute(String path, TypeMirror type) {
31363154 }
31373155 if ( returnType .getKind () == TypeKind .DECLARED
31383156 && containsAnnotation ( ((DeclaredType ) returnType ).asElement (), ENTITY ) ) {
3139- if ( explicitMethodSelect ) {
3157+ if ( validate && explicitMethodSelect ) {
31403158 message ( method , query ,
31413159 "'@Select' may not be used on a '@Query' method that returns entity type '" + returnType + "'" ,
31423160 Diagnostic .Kind .ERROR );
31433161 }
31443162 return null ;
31453163 }
31463164 if ( hasSelectClause ( queryString ) ) {
3147- if ( explicitMethodSelect ) {
3165+ if ( validate && explicitMethodSelect ) {
31483166 message ( method , query ,
31493167 "'@Select' may not be used on a '@Query' method with an explicit SELECT clause" ,
31503168 Diagnostic .Kind .ERROR );
31513169 }
31523170 return null ;
31533171 }
31543172 final var entity = querySelectionEntity ( queryString );
3155- if ( entity == null ) {
3173+ if ( validate && entity == null ) {
31563174 message ( method , query ,
31573175 "repository method has no well-defined entity type" ,
31583176 Diagnostic .Kind .ERROR );
0 commit comments