15
15
*/
16
16
package org .springframework .data .jpa .repository .support ;
17
17
18
+ import java .util .ArrayList ;
18
19
import java .util .Collection ;
19
20
import java .util .List ;
20
21
import java .util .function .Function ;
21
- import java .util .stream .Collectors ;
22
22
import java .util .stream .Stream ;
23
23
24
24
import javax .persistence .EntityManager ;
37
37
import org .springframework .data .repository .query .FluentQuery .FetchableFluentQuery ;
38
38
import org .springframework .data .support .PageableExecutionUtils ;
39
39
import org .springframework .lang .Nullable ;
40
+ import org .springframework .util .Assert ;
40
41
41
42
/**
42
43
* Immutable implementation of {@link FetchableFluentQuery} based on Query by {@link Example}. All methods that return a
45
46
* @param <S> Domain type
46
47
* @param <R> Result type
47
48
* @author Greg Turnquist
49
+ * @author Mark Paluch
48
50
* @since 2.6
49
51
*/
50
52
class FetchableFluentQueryByExample <S , R > extends FluentQuerySupport <R > implements FetchableFluentQuery <R > {
@@ -79,87 +81,126 @@ private FetchableFluentQueryByExample(Example<S> example, Class<R> returnType, S
79
81
this .escapeCharacter = escapeCharacter ;
80
82
}
81
83
84
+ /*
85
+ * (non-Javadoc)
86
+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#sortBy(org.springframework.data.domain.Sort)
87
+ */
82
88
@ Override
83
89
public FetchableFluentQuery <R > sortBy (Sort sort ) {
84
90
85
- return new FetchableFluentQueryByExample <S , R >(this .example , this .resultType , this .sort .and (sort ), this .properties ,
91
+ Assert .notNull (sort , "Sort must not be null!" );
92
+
93
+ return new FetchableFluentQueryByExample <>(this .example , this .resultType , this .sort .and (sort ), this .properties ,
86
94
this .finder , this .countOperation , this .existsOperation , this .context , this .entityManager , this .escapeCharacter );
87
95
}
88
96
97
+ /*
98
+ * (non-Javadoc)
99
+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#as(java.lang.Class)
100
+ */
89
101
@ Override
90
102
public <NR > FetchableFluentQuery <NR > as (Class <NR > resultType ) {
91
103
104
+ Assert .notNull (resultType , "Projection target type must not be null!" );
92
105
if (!resultType .isInterface ()) {
93
106
throw new UnsupportedOperationException ("Class-based DTOs are not yet supported." );
94
107
}
95
108
96
- return new FetchableFluentQueryByExample <S , NR >(this .example , resultType , this .sort , this .properties , this .finder ,
109
+ return new FetchableFluentQueryByExample <>(this .example , resultType , this .sort , this .properties , this .finder ,
97
110
this .countOperation , this .existsOperation , this .context , this .entityManager , this .escapeCharacter );
98
111
}
99
112
113
+ /*
114
+ * (non-Javadoc)
115
+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#project(java.util.Collection)
116
+ */
100
117
@ Override
101
118
public FetchableFluentQuery <R > project (Collection <String > properties ) {
102
119
103
120
return new FetchableFluentQueryByExample <>(this .example , this .resultType , this .sort , mergeProperties (properties ),
104
121
this .finder , this .countOperation , this .existsOperation , this .context , this .entityManager , this .escapeCharacter );
105
122
}
106
123
124
+ /*
125
+ * (non-Javadoc)
126
+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#oneValue()
127
+ */
107
128
@ Override
108
129
public R oneValue () {
109
130
110
131
TypedQuery <S > limitedQuery = this .finder .apply (this .sort );
111
132
limitedQuery .setMaxResults (2 ); // Never need more than 2 values
112
133
113
- List <R > results = limitedQuery //
114
- .getResultStream () //
115
- .map (getConversionFunction (this .example .getProbeType (), this .resultType )) //
116
- .collect (Collectors .toList ());
117
- ;
134
+ List <S > results = limitedQuery .getResultList ();
118
135
119
136
if (results .size () > 1 ) {
120
137
throw new IncorrectResultSizeDataAccessException (1 );
121
138
}
122
139
123
- return results .isEmpty () ? null : results .get (0 );
140
+ return results .isEmpty () ? null : getConversionFunction (). apply ( results .get (0 ) );
124
141
}
125
142
143
+ /*
144
+ * (non-Javadoc)
145
+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#firstValue()
146
+ */
126
147
@ Override
127
148
public R firstValue () {
128
149
129
150
TypedQuery <S > limitedQuery = this .finder .apply (this .sort );
130
151
limitedQuery .setMaxResults (1 ); // Never need more than 1 value
131
152
132
- List <R > results = limitedQuery //
133
- .getResultStream () //
134
- .map (getConversionFunction (this .example .getProbeType (), this .resultType )) //
135
- .collect (Collectors .toList ());
153
+ List <S > results = limitedQuery .getResultList ();
136
154
137
- return results .isEmpty () ? null : results .get (0 );
155
+ return results .isEmpty () ? null : getConversionFunction (). apply ( results .get (0 ) );
138
156
}
139
157
158
+ /*
159
+ * (non-Javadoc)
160
+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#all()
161
+ */
140
162
@ Override
141
163
public List <R > all () {
142
- return stream ().collect (Collectors .toList ());
164
+
165
+ List <S > resultList = this .finder .apply (this .sort ).getResultList ();
166
+
167
+ return convert (resultList );
143
168
}
144
169
170
+ /*
171
+ * (non-Javadoc)
172
+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#page(org.springframework.data.domain.Pageable)
173
+ */
145
174
@ Override
146
175
public Page <R > page (Pageable pageable ) {
147
176
return pageable .isUnpaged () ? new PageImpl <>(all ()) : readPage (pageable );
148
177
}
149
178
179
+ /*
180
+ * (non-Javadoc)
181
+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#stream()
182
+ */
150
183
@ Override
151
184
public Stream <R > stream () {
152
185
153
186
return this .finder .apply (this .sort ) //
154
187
.getResultStream () //
155
- .map (getConversionFunction (this . example . getProbeType (), this . resultType ));
188
+ .map (getConversionFunction ());
156
189
}
157
190
191
+ /*
192
+ * (non-Javadoc)
193
+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#count()
194
+ */
158
195
@ Override
159
196
public long count () {
160
197
return this .countOperation .apply (example );
161
198
}
162
199
200
+ /*
201
+ * (non-Javadoc)
202
+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#exists()
203
+ */
163
204
@ Override
164
205
public boolean exists () {
165
206
return this .existsOperation .apply (example );
@@ -174,10 +215,24 @@ private Page<R> readPage(Pageable pageable) {
174
215
pagedQuery .setMaxResults (pageable .getPageSize ());
175
216
}
176
217
177
- List <R > paginatedResults = pagedQuery .getResultStream () //
178
- .map (getConversionFunction (this .example .getProbeType (), this .resultType )) //
179
- .collect (Collectors .toList ());
218
+ List <R > paginatedResults = convert (pagedQuery .getResultList ());
180
219
181
220
return PageableExecutionUtils .getPage (paginatedResults , pageable , () -> this .countOperation .apply (this .example ));
182
221
}
222
+
223
+ private List <R > convert (List <S > resultList ) {
224
+
225
+ Function <Object , R > conversionFunction = getConversionFunction ();
226
+ List <R > mapped = new ArrayList <>(resultList .size ());
227
+
228
+ for (S s : resultList ) {
229
+ mapped .add (conversionFunction .apply (s ));
230
+ }
231
+ return mapped ;
232
+ }
233
+
234
+ private Function <Object , R > getConversionFunction () {
235
+ return getConversionFunction (this .example .getProbeType (), this .resultType );
236
+ }
237
+
183
238
}
0 commit comments