1
16 package org.springframework.data.jpa.repository.query;
17
18 import javax.annotation.Nullable;
19 import javax.persistence.EntityManager;
20 import javax.persistence.Query;
21 import javax.persistence.Tuple;
22
23 import org.springframework.data.repository.query.Parameters;
24 import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
25 import org.springframework.data.repository.query.RepositoryQuery;
26 import org.springframework.data.repository.query.ReturnedType;
27 import org.springframework.expression.spel.standard.SpelExpressionParser;
28
29
38 final class NativeJpaQuery extends AbstractStringBasedJpaQuery {
39
40
48 public NativeJpaQuery(JpaQueryMethod method, EntityManager em, String queryString,
49 QueryMethodEvaluationContextProvider evaluationContextProvider, SpelExpressionParser parser) {
50
51 super(method, em, queryString, evaluationContextProvider, parser);
52
53 Parameters<?, ?> parameters = method.getParameters();
54
55 if (parameters.hasSortParameter() && !queryString.contains("#sort")) {
56 throw new InvalidJpaQueryMethodException("Cannot use native queries with dynamic sorting in method " + method);
57 }
58 }
59
60
64 @Override
65 protected Query createJpaQuery(String queryString, ReturnedType returnedType) {
66
67 EntityManager em = getEntityManager();
68 Class<?> type = getTypeToQueryFor(returnedType);
69
70 return type == null ? em.createNativeQuery(queryString) : em.createNativeQuery(queryString, type);
71 }
72
73 @Nullable
74 private Class<?> getTypeToQueryFor(ReturnedType returnedType) {
75
76 Class<?> result = getQueryMethod().isQueryForEntity() ? returnedType.getDomainType() : null;
77
78 if (this.getQuery().hasConstructorExpression() || this.getQuery().isDefaultProjection()) {
79 return result;
80 }
81
82 return returnedType.isProjecting() && !getMetamodel().isJpaManaged(returnedType.getReturnedType())
83 ? Tuple.class
84 : result;
85 }
86 }
87