2121
2222import org .slf4j .Logger ;
2323import org .slf4j .LoggerFactory ;
24-
2524import org .springframework .data .jpa .repository .Query ;
2625import org .springframework .data .projection .ProjectionFactory ;
2726import org .springframework .data .repository .core .NamedQueries ;
2827import org .springframework .data .repository .core .RepositoryMetadata ;
2928import org .springframework .data .repository .query .QueryLookupStrategy ;
3029import org .springframework .data .repository .query .QueryLookupStrategy .Key ;
30+ import org .springframework .data .repository .query .QueryMethod ;
3131import org .springframework .data .repository .query .QueryMethodEvaluationContextProvider ;
3232import org .springframework .data .repository .query .RepositoryQuery ;
3333import org .springframework .lang .Nullable ;
@@ -46,6 +46,12 @@ public final class JpaQueryLookupStrategy {
4646
4747 private static final Logger LOG = LoggerFactory .getLogger (JpaQueryLookupStrategy .class );
4848
49+ /**
50+ * A null-value instance used to signal if no declared query could be found. It checks many different formats before
51+ * falling through to this value object.
52+ */
53+ private static final RepositoryQuery NO_QUERY = new NoQuery ();
54+
4955 /**
5056 * Private constructor to prevent instantiation.
5157 */
@@ -161,24 +167,20 @@ protected RepositoryQuery resolveQuery(JpaQueryMethod method, EntityManager em,
161167 }
162168
163169 return JpaQueryFactory .INSTANCE .fromMethodWithQueryString (method , em , method .getRequiredAnnotatedQuery (),
164- getCountQuery (method , namedQueries , em ),
165- evaluationContextProvider );
170+ getCountQuery (method , namedQueries , em ), evaluationContextProvider );
166171 }
167172
168173 String name = method .getNamedQueryName ();
169174 if (namedQueries .hasQuery (name )) {
170- return JpaQueryFactory .INSTANCE .fromMethodWithQueryString (method , em , namedQueries .getQuery (name ), getCountQuery ( method , namedQueries , em ),
171- evaluationContextProvider );
175+ return JpaQueryFactory .INSTANCE .fromMethodWithQueryString (method , em , namedQueries .getQuery (name ),
176+ getCountQuery ( method , namedQueries , em ), evaluationContextProvider );
172177 }
173178
174179 RepositoryQuery query = NamedQuery .lookupFrom (method , em );
175180
176- if (null != query ) {
177- return query ;
178- }
179-
180- throw new IllegalStateException (
181- String .format ("Did neither find a NamedQuery nor an annotated query for method %s!" , method ));
181+ return query != null //
182+ ? query //
183+ : NO_QUERY ;
182184 }
183185
184186 @ Nullable
@@ -248,11 +250,13 @@ public CreateIfNotFoundQueryLookupStrategy(EntityManager em, JpaQueryMethodFacto
248250 @ Override
249251 protected RepositoryQuery resolveQuery (JpaQueryMethod method , EntityManager em , NamedQueries namedQueries ) {
250252
251- try {
252- return lookupStrategy . resolveQuery ( method , em , namedQueries );
253- } catch ( IllegalStateException e ) {
254- return createStrategy . resolveQuery ( method , em , namedQueries ) ;
253+ RepositoryQuery lookupQuery = lookupStrategy . resolveQuery ( method , em , namedQueries );
254+
255+ if ( lookupQuery != NO_QUERY ) {
256+ return lookupQuery ;
255257 }
258+
259+ return createStrategy .resolveQuery (method , em , namedQueries );
256260 }
257261 }
258262
@@ -286,4 +290,20 @@ public static QueryLookupStrategy create(EntityManager em, JpaQueryMethodFactory
286290 throw new IllegalArgumentException (String .format ("Unsupported query lookup strategy %s!" , key ));
287291 }
288292 }
293+
294+ /**
295+ * A null value type that represents the lack of a defined query.
296+ */
297+ static class NoQuery implements RepositoryQuery {
298+
299+ @ Override
300+ public Object execute (Object [] parameters ) {
301+ throw new IllegalStateException ("NoQuery should not be executed!" );
302+ }
303+
304+ @ Override
305+ public QueryMethod getQueryMethod () {
306+ throw new IllegalStateException ("NoQuery does not have a QueryMethod!" );
307+ }
308+ }
289309}
0 commit comments