1 /*
2 * Copyright 2013-2020 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.springframework.data.jpa.repository.query;
17
18 import javax.persistence.EntityManager;
19
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 import org.springframework.data.jpa.repository.Query;
23 import org.springframework.data.repository.query.QueryMethod;
24 import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
25 import org.springframework.data.repository.query.RepositoryQuery;
26 import org.springframework.expression.spel.standard.SpelExpressionParser;
27 import org.springframework.lang.Nullable;
28
29 /**
30 * Factory to create the appropriate {@link RepositoryQuery} for a {@link JpaQueryMethod}.
31 *
32 * @author Thomas Darimont
33 * @author Mark Paluch
34 */
35 enum JpaQueryFactory {
36
37 INSTANCE;
38
39 private static final SpelExpressionParser PARSER = new SpelExpressionParser();
40 private static final Logger LOG = LoggerFactory.getLogger(JpaQueryFactory.class);
41
42 /**
43 * Creates a {@link RepositoryQuery} from the given {@link QueryMethod} that is potentially annotated with
44 * {@link Query}.
45 *
46 * @param method must not be {@literal null}.
47 * @param em must not be {@literal null}.
48 * @param evaluationContextProvider
49 * @return the {@link RepositoryQuery} derived from the annotation or {@code null} if no annotation found.
50 */
51 @Nullable
52 AbstractJpaQuery fromQueryAnnotation(JpaQueryMethod method, EntityManager em,
53 QueryMethodEvaluationContextProvider evaluationContextProvider) {
54
55 LOG.debug("Looking up query for method {}", method.getName());
56 return fromMethodWithQueryString(method, em, method.getAnnotatedQuery(), evaluationContextProvider);
57 }
58
59 /**
60 * Creates a {@link RepositoryQuery} from the given {@link String} query.
61 *
62 * @param method must not be {@literal null}.
63 * @param em must not be {@literal null}.
64 * @param queryString must not be {@literal null} or empty.
65 * @param evaluationContextProvider
66 * @return
67 */
68 @Nullable
69 AbstractJpaQuery fromMethodWithQueryString(JpaQueryMethod method, EntityManager em, @Nullable String queryString,
70 QueryMethodEvaluationContextProvider evaluationContextProvider) {
71
72 if (queryString == null) {
73 return null;
74 }
75
76 return method.isNativeQuery() ? new NativeJpaQuery(method, em, queryString, evaluationContextProvider, PARSER)
77 : new SimpleJpaQuery(method, em, queryString, evaluationContextProvider, PARSER);
78 }
79
80 /**
81 * Creates a {@link StoredProcedureJpaQuery} from the given {@link JpaQueryMethod} query.
82 *
83 * @param method must not be {@literal null}.
84 * @param em must not be {@literal null}.
85 * @return
86 */
87 @Nullable
88 public StoredProcedureJpaQuery fromProcedureAnnotation(JpaQueryMethod method, EntityManager em) {
89
90 if (!method.isProcedureQuery()) {
91 return null;
92 }
93
94 return new StoredProcedureJpaQuery(method, em);
95 }
96 }
97