1515 */
1616package org .springframework .data .jpa .repository .support ;
1717
18+ import java .util .ArrayList ;
1819import java .util .Collection ;
1920import java .util .List ;
2021import java .util .function .Function ;
21- import java .util .stream .Collectors ;
2222import java .util .stream .Stream ;
2323
2424import javax .persistence .EntityManager ;
3737import org .springframework .data .repository .query .FluentQuery .FetchableFluentQuery ;
3838import org .springframework .data .support .PageableExecutionUtils ;
3939import org .springframework .lang .Nullable ;
40+ import org .springframework .util .Assert ;
4041
4142/**
4243 * Immutable implementation of {@link FetchableFluentQuery} based on Query by {@link Example}. All methods that return a
4546 * @param <S> Domain type
4647 * @param <R> Result type
4748 * @author Greg Turnquist
49+ * @author Mark Paluch
4850 * @since 2.6
4951 */
5052class FetchableFluentQueryByExample <S , R > extends FluentQuerySupport <R > implements FetchableFluentQuery <R > {
@@ -79,87 +81,126 @@ private FetchableFluentQueryByExample(Example<S> example, Class<R> returnType, S
7981 this .escapeCharacter = escapeCharacter ;
8082 }
8183
84+ /*
85+ * (non-Javadoc)
86+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#sortBy(org.springframework.data.domain.Sort)
87+ */
8288 @ Override
8389 public FetchableFluentQuery <R > sortBy (Sort sort ) {
8490
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 ,
8694 this .finder , this .countOperation , this .existsOperation , this .context , this .entityManager , this .escapeCharacter );
8795 }
8896
97+ /*
98+ * (non-Javadoc)
99+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#as(java.lang.Class)
100+ */
89101 @ Override
90102 public <NR > FetchableFluentQuery <NR > as (Class <NR > resultType ) {
91103
104+ Assert .notNull (resultType , "Projection target type must not be null!" );
92105 if (!resultType .isInterface ()) {
93106 throw new UnsupportedOperationException ("Class-based DTOs are not yet supported." );
94107 }
95108
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 ,
97110 this .countOperation , this .existsOperation , this .context , this .entityManager , this .escapeCharacter );
98111 }
99112
113+ /*
114+ * (non-Javadoc)
115+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#project(java.util.Collection)
116+ */
100117 @ Override
101118 public FetchableFluentQuery <R > project (Collection <String > properties ) {
102119
103120 return new FetchableFluentQueryByExample <>(this .example , this .resultType , this .sort , mergeProperties (properties ),
104121 this .finder , this .countOperation , this .existsOperation , this .context , this .entityManager , this .escapeCharacter );
105122 }
106123
124+ /*
125+ * (non-Javadoc)
126+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#oneValue()
127+ */
107128 @ Override
108129 public R oneValue () {
109130
110131 TypedQuery <S > limitedQuery = this .finder .apply (this .sort );
111132 limitedQuery .setMaxResults (2 ); // Never need more than 2 values
112133
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 ();
118135
119136 if (results .size () > 1 ) {
120137 throw new IncorrectResultSizeDataAccessException (1 );
121138 }
122139
123- return results .isEmpty () ? null : results .get (0 );
140+ return results .isEmpty () ? null : getConversionFunction (). apply ( results .get (0 ) );
124141 }
125142
143+ /*
144+ * (non-Javadoc)
145+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#firstValue()
146+ */
126147 @ Override
127148 public R firstValue () {
128149
129150 TypedQuery <S > limitedQuery = this .finder .apply (this .sort );
130151 limitedQuery .setMaxResults (1 ); // Never need more than 1 value
131152
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 ();
136154
137- return results .isEmpty () ? null : results .get (0 );
155+ return results .isEmpty () ? null : getConversionFunction (). apply ( results .get (0 ) );
138156 }
139157
158+ /*
159+ * (non-Javadoc)
160+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#all()
161+ */
140162 @ Override
141163 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 );
143168 }
144169
170+ /*
171+ * (non-Javadoc)
172+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#page(org.springframework.data.domain.Pageable)
173+ */
145174 @ Override
146175 public Page <R > page (Pageable pageable ) {
147176 return pageable .isUnpaged () ? new PageImpl <>(all ()) : readPage (pageable );
148177 }
149178
179+ /*
180+ * (non-Javadoc)
181+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#stream()
182+ */
150183 @ Override
151184 public Stream <R > stream () {
152185
153186 return this .finder .apply (this .sort ) //
154187 .getResultStream () //
155- .map (getConversionFunction (this . example . getProbeType (), this . resultType ));
188+ .map (getConversionFunction ());
156189 }
157190
191+ /*
192+ * (non-Javadoc)
193+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#count()
194+ */
158195 @ Override
159196 public long count () {
160197 return this .countOperation .apply (example );
161198 }
162199
200+ /*
201+ * (non-Javadoc)
202+ * @see org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery#exists()
203+ */
163204 @ Override
164205 public boolean exists () {
165206 return this .existsOperation .apply (example );
@@ -174,10 +215,24 @@ private Page<R> readPage(Pageable pageable) {
174215 pagedQuery .setMaxResults (pageable .getPageSize ());
175216 }
176217
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 ());
180219
181220 return PageableExecutionUtils .getPage (paginatedResults , pageable , () -> this .countOperation .apply (this .example ));
182221 }
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+
183238}
0 commit comments