36
36
import org .springframework .util .Assert ;
37
37
38
38
import com .querydsl .core .types .Predicate ;
39
- import com .querydsl .jpa .JPQLQuery ;
39
+ import com .querydsl .jpa .impl . AbstractJPAQuery ;
40
40
41
41
/**
42
42
* Immutable implementation of {@link FetchableFluentQuery} based on a Querydsl {@link Predicate}. All methods that
46
46
* @param <R> Result type
47
47
* @author Greg Turnquist
48
48
* @author Mark Paluch
49
+ * @author Jens Schauder
49
50
* @since 2.6
50
51
*/
51
52
class FetchableFluentQueryByPredicate <S , R > extends FluentQuerySupport <R > implements FetchableFluentQuery <R > {
52
53
53
54
private final Predicate predicate ;
54
- private final Function <Sort , JPQLQuery < S >> finder ;
55
- private final BiFunction <Sort , Pageable , JPQLQuery < S >> pagedFinder ;
55
+ private final Function <Sort , AbstractJPAQuery <?, ? >> finder ;
56
+ private final BiFunction <Sort , Pageable , AbstractJPAQuery <?, ? >> pagedFinder ;
56
57
private final Function <Predicate , Long > countOperation ;
57
58
private final Function <Predicate , Boolean > existsOperation ;
58
59
private final Class <S > entityType ;
60
+ private final Projector projector ;
59
61
60
- public FetchableFluentQueryByPredicate (Predicate predicate , Class <R > resultType , Function < Sort , JPQLQuery < S >> finder ,
61
- BiFunction <Sort , Pageable , JPQLQuery < S >> pagedFinder , Function < Predicate , Long > countOperation ,
62
- Function <Predicate , Boolean > existsOperation , Class <S > entityType ,
63
- MappingContext <? extends PersistentEntity <?, ?>, ? extends PersistentProperty <?>> context ) {
62
+ public FetchableFluentQueryByPredicate (Predicate predicate , Class <R > resultType ,
63
+ Function <Sort , AbstractJPAQuery <?, ? >> finder , BiFunction < Sort , Pageable , AbstractJPAQuery <?, ?>> pagedFinder ,
64
+ Function <Predicate , Long > countOperation , Function < Predicate , Boolean > existsOperation , Class <S > entityType ,
65
+ MappingContext <? extends PersistentEntity <?, ?>, ? extends PersistentProperty <?>> context , Projector projector ) {
64
66
this (predicate , resultType , Sort .unsorted (), null , finder , pagedFinder , countOperation , existsOperation , entityType ,
65
- context );
67
+ context , projector );
66
68
}
67
69
68
70
private FetchableFluentQueryByPredicate (Predicate predicate , Class <R > resultType , Sort sort ,
69
- @ Nullable Collection <String > properties , Function <Sort , JPQLQuery < S >> finder ,
70
- BiFunction <Sort , Pageable , JPQLQuery < S >> pagedFinder , Function <Predicate , Long > countOperation ,
71
+ @ Nullable Collection <String > properties , Function <Sort , AbstractJPAQuery <?, ? >> finder ,
72
+ BiFunction <Sort , Pageable , AbstractJPAQuery <?, ? >> pagedFinder , Function <Predicate , Long > countOperation ,
71
73
Function <Predicate , Boolean > existsOperation , Class <S > entityType ,
72
- MappingContext <? extends PersistentEntity <?, ?>, ? extends PersistentProperty <?>> context ) {
74
+ MappingContext <? extends PersistentEntity <?, ?>, ? extends PersistentProperty <?>> context , Projector projector ) {
73
75
74
76
super (resultType , sort , properties , context );
75
77
this .predicate = predicate ;
@@ -78,6 +80,7 @@ private FetchableFluentQueryByPredicate(Predicate predicate, Class<R> resultType
78
80
this .countOperation = countOperation ;
79
81
this .existsOperation = existsOperation ;
80
82
this .entityType = entityType ;
83
+ this .projector = projector ;
81
84
}
82
85
83
86
/*
@@ -90,7 +93,8 @@ public FetchableFluentQuery<R> sortBy(Sort sort) {
90
93
Assert .notNull (sort , "Sort must not be null!" );
91
94
92
95
return new FetchableFluentQueryByPredicate <>(this .predicate , this .resultType , this .sort .and (sort ), this .properties ,
93
- this .finder , this .pagedFinder , this .countOperation , this .existsOperation , this .entityType , this .context );
96
+ this .finder , this .pagedFinder , this .countOperation , this .existsOperation , this .entityType , this .context ,
97
+ this .projector );
94
98
}
95
99
96
100
/*
@@ -106,7 +110,7 @@ public <NR> FetchableFluentQuery<NR> as(Class<NR> resultType) {
106
110
}
107
111
108
112
return new FetchableFluentQueryByPredicate <>(this .predicate , resultType , this .sort , this .properties , this .finder ,
109
- this .pagedFinder , this .countOperation , this .existsOperation , this .entityType , this .context );
113
+ this .pagedFinder , this .countOperation , this .existsOperation , this .entityType , this .context , this . projector );
110
114
}
111
115
112
116
/*
@@ -118,7 +122,7 @@ public FetchableFluentQuery<R> project(Collection<String> properties) {
118
122
119
123
return new FetchableFluentQueryByPredicate <>(this .predicate , this .resultType , this .sort ,
120
124
mergeProperties (properties ), this .finder , this .pagedFinder , this .countOperation , this .existsOperation ,
121
- this .entityType , this .context );
125
+ this .entityType , this .context , this . projector );
122
126
}
123
127
124
128
/*
@@ -128,7 +132,7 @@ public FetchableFluentQuery<R> project(Collection<String> properties) {
128
132
@ Override
129
133
public R oneValue () {
130
134
131
- List <S > results = this . finder . apply ( this . sort ) //
135
+ List <? > results = createSortedAndProjectedQuery ( ) //
132
136
.limit (2 ) // Never need more than 2 values
133
137
.fetch ();
134
138
@@ -146,7 +150,7 @@ public R oneValue() {
146
150
@ Override
147
151
public R firstValue () {
148
152
149
- List <S > results = this . finder . apply ( this . sort ) //
153
+ List <? > results = createSortedAndProjectedQuery ( ) //
150
154
.limit (1 ) // Never need more than 1 value
151
155
.fetch ();
152
156
@@ -159,9 +163,7 @@ public R firstValue() {
159
163
*/
160
164
@ Override
161
165
public List <R > all () {
162
-
163
- JPQLQuery <S > query = this .finder .apply (this .sort );
164
- return convert (query .fetch ());
166
+ return convert (createSortedAndProjectedQuery ().fetch ());
165
167
}
166
168
167
169
/*
@@ -180,11 +182,17 @@ public Page<R> page(Pageable pageable) {
180
182
@ Override
181
183
public Stream <R > stream () {
182
184
183
- return this . finder . apply ( this . sort ) //
185
+ return createSortedAndProjectedQuery ( ) //
184
186
.stream () //
185
187
.map (getConversionFunction ());
186
188
}
187
189
190
+ private AbstractJPAQuery <?, ?> createSortedAndProjectedQuery () {
191
+
192
+ final AbstractJPAQuery <?, ?> query = this .finder .apply (this .sort );
193
+ return projector .apply (entityType , query , properties );
194
+ }
195
+
188
196
/*
189
197
* (non-Javadoc)
190
198
* @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#count()
@@ -205,19 +213,19 @@ public boolean exists() {
205
213
206
214
private Page <R > readPage (Pageable pageable ) {
207
215
208
- JPQLQuery < S > pagedQuery = this .pagedFinder .apply (this .sort , pageable );
216
+ AbstractJPAQuery <?, ? > pagedQuery = this .pagedFinder .apply (this .sort , pageable );
209
217
List <R > paginatedResults = convert (pagedQuery .fetch ());
210
218
211
219
return PageableExecutionUtils .getPage (paginatedResults , pageable , () -> this .countOperation .apply (this .predicate ));
212
220
}
213
221
214
- private List <R > convert (List <S > resultList ) {
222
+ private List <R > convert (List <? > resultList ) {
215
223
216
224
Function <Object , R > conversionFunction = getConversionFunction ();
217
225
List <R > mapped = new ArrayList <>(resultList .size ());
218
226
219
- for (S s : resultList ) {
220
- mapped .add (conversionFunction .apply (s ));
227
+ for (Object o : resultList ) {
228
+ mapped .add (conversionFunction .apply (o ));
221
229
}
222
230
223
231
return mapped ;
0 commit comments