Skip to content

Commit a31c39d

Browse files
committed
Polishing.
Fix version reference to Spring Data Commons. Avoid stream creation when fetching all/one/first element. Move off deprecated API. Add override comments. Add null guargs. See #2294 Original pull request: #2326.
1 parent ea430f3 commit a31c39d

File tree

5 files changed

+162
-42
lines changed

5 files changed

+162
-42
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<hibernate>5.5.3.Final</hibernate>
2626
<mysql-connector-java>8.0.23</mysql-connector-java>
2727
<postgresql>42.2.19</postgresql>
28-
<springdata.commons>2.6.0-2228-SNAPSHOT</springdata.commons>
28+
<springdata.commons>2.6.0-SNAPSHOT</springdata.commons>
2929
<vavr>0.10.3</vavr>
3030

3131
<hibernate.groupId>org.hibernate</hibernate.groupId>

src/main/java/org/springframework/data/jpa/repository/support/FetchableFluentQueryByExample.java

+74-19
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
*/
1616
package org.springframework.data.jpa.repository.support;
1717

18+
import java.util.ArrayList;
1819
import java.util.Collection;
1920
import java.util.List;
2021
import java.util.function.Function;
21-
import java.util.stream.Collectors;
2222
import java.util.stream.Stream;
2323

2424
import javax.persistence.EntityManager;
@@ -37,6 +37,7 @@
3737
import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery;
3838
import org.springframework.data.support.PageableExecutionUtils;
3939
import 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
@@ -45,6 +46,7 @@
4546
* @param <S> Domain type
4647
* @param <R> Result type
4748
* @author Greg Turnquist
49+
* @author Mark Paluch
4850
* @since 2.6
4951
*/
5052
class 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

Comments
 (0)