Skip to content

Commit e0a12d7

Browse files
DATAMONGO-2182 - Polishing.
Introduce base class for common Querydsl query execution tasks that can be used for imperative and reactive implementation. Fix test issues due to context caching where indices are not recreated when dropping the collection during test setup. Update reference documentation. Original Pull Request: #635
1 parent 1605110 commit e0a12d7

File tree

8 files changed

+270
-141
lines changed

8 files changed

+270
-141
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QuerydslMongoPredicateExecutor.java

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,18 @@
2222
import org.springframework.data.domain.Page;
2323
import org.springframework.data.domain.Pageable;
2424
import org.springframework.data.domain.Sort;
25-
import org.springframework.data.domain.Sort.Order;
2625
import org.springframework.data.mongodb.core.MongoOperations;
2726
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
2827
import org.springframework.data.querydsl.EntityPathResolver;
29-
import org.springframework.data.querydsl.QSort;
3028
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
3129
import org.springframework.data.querydsl.SimpleEntityPathResolver;
32-
import org.springframework.data.repository.core.EntityInformation;
3330
import org.springframework.data.repository.support.PageableExecutionUtils;
3431
import org.springframework.util.Assert;
3532

3633
import com.querydsl.core.NonUniqueResultException;
3734
import com.querydsl.core.types.EntityPath;
38-
import com.querydsl.core.types.Expression;
3935
import com.querydsl.core.types.OrderSpecifier;
4036
import com.querydsl.core.types.Predicate;
41-
import com.querydsl.core.types.dsl.PathBuilder;
4237

4338
/**
4439
* MongoDB-specific {@link QuerydslPredicateExecutor} that allows execution {@link Predicate}s in various forms.
@@ -50,10 +45,9 @@
5045
* @author Mark Paluch
5146
* @since 2.0
5247
*/
53-
public class QuerydslMongoPredicateExecutor<T> implements QuerydslPredicateExecutor<T> {
48+
public class QuerydslMongoPredicateExecutor<T> extends QuerydslPredicateExecutorSupport<T>
49+
implements QuerydslPredicateExecutor<T> {
5450

55-
private final PathBuilder<T> builder;
56-
private final EntityInformation<T, ?> entityInformation;
5751
private final MongoOperations mongoOperations;
5852

5953
/**
@@ -80,12 +74,8 @@ public QuerydslMongoPredicateExecutor(MongoEntityInformation<T, ?> entityInforma
8074
public QuerydslMongoPredicateExecutor(MongoEntityInformation<T, ?> entityInformation, MongoOperations mongoOperations,
8175
EntityPathResolver resolver) {
8276

83-
Assert.notNull(resolver, "EntityPathResolver must not be null!");
84-
85-
EntityPath<T> path = resolver.createPath(entityInformation.getJavaType());
86-
87-
this.builder = new PathBuilder<T>(path.getType(), path.getMetadata());
88-
this.entityInformation = entityInformation;
77+
super(mongoOperations.getConverter(), pathBuilderFor(resolver.createPath(entityInformation.getJavaType())),
78+
entityInformation);
8979
this.mongoOperations = mongoOperations;
9080
}
9181

@@ -210,7 +200,7 @@ private SpringDataMongodbQuery<T> createQueryFor(Predicate predicate) {
210200
* @return
211201
*/
212202
private SpringDataMongodbQuery<T> createQuery() {
213-
return new SpringDataMongodbQuery<>(mongoOperations, entityInformation.getJavaType());
203+
return new SpringDataMongodbQuery<>(mongoOperations, typeInformation().getJavaType());
214204
}
215205

216206
/**
@@ -235,32 +225,7 @@ private SpringDataMongodbQuery<T> applyPagination(SpringDataMongodbQuery<T> quer
235225
*/
236226
private SpringDataMongodbQuery<T> applySorting(SpringDataMongodbQuery<T> query, Sort sort) {
237227

238-
// TODO: find better solution than instanceof check
239-
if (sort instanceof QSort) {
240-
241-
List<OrderSpecifier<?>> orderSpecifiers = ((QSort) sort).getOrderSpecifiers();
242-
query.orderBy(orderSpecifiers.toArray(new OrderSpecifier<?>[orderSpecifiers.size()]));
243-
244-
return query;
245-
}
246-
247-
sort.stream().map(this::toOrder).forEach(query::orderBy);
248-
228+
toOrderSpecifiers(sort).forEach(query::orderBy);
249229
return query;
250230
}
251-
252-
/**
253-
* Transforms a plain {@link Order} into a Querydsl specific {@link OrderSpecifier}.
254-
*
255-
* @param order
256-
* @return
257-
*/
258-
@SuppressWarnings({ "rawtypes", "unchecked" })
259-
private OrderSpecifier<?> toOrder(Order order) {
260-
261-
Expression<Object> property = builder.get(order.getProperty());
262-
263-
return new OrderSpecifier(
264-
order.isAscending() ? com.querydsl.core.types.Order.ASC : com.querydsl.core.types.Order.DESC, property);
265-
}
266231
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright 2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mongodb.repository.support;
17+
18+
import java.util.List;
19+
import java.util.stream.Collectors;
20+
21+
import org.springframework.data.domain.Sort;
22+
import org.springframework.data.domain.Sort.Order;
23+
import org.springframework.data.mongodb.core.convert.MongoConverter;
24+
import org.springframework.data.querydsl.QSort;
25+
import org.springframework.data.repository.core.EntityInformation;
26+
27+
import com.querydsl.core.types.EntityPath;
28+
import com.querydsl.core.types.Expression;
29+
import com.querydsl.core.types.OrderSpecifier;
30+
import com.querydsl.core.types.dsl.PathBuilder;
31+
32+
/**
33+
* @author Christoph Strobl
34+
* @since 2.2
35+
*/
36+
abstract class QuerydslPredicateExecutorSupport<T> {
37+
38+
private final SpringDataMongodbSerializer serializer;
39+
private final PathBuilder<T> builder;
40+
private final EntityInformation<T, ?> entityInformation;
41+
42+
QuerydslPredicateExecutorSupport(MongoConverter converter, PathBuilder<T> builder,
43+
EntityInformation<T, ?> entityInformation) {
44+
45+
this.serializer = new SpringDataMongodbSerializer(converter);
46+
this.builder = builder;
47+
this.entityInformation = entityInformation;
48+
}
49+
50+
protected static <E> PathBuilder<E> pathBuilderFor(EntityPath<E> path) {
51+
return new PathBuilder<>(path.getType(), path.getMetadata());
52+
}
53+
54+
protected EntityInformation<T, ?> typeInformation() {
55+
return entityInformation;
56+
}
57+
58+
protected SpringDataMongodbSerializer mongodbSerializer() {
59+
return serializer;
60+
}
61+
62+
/**
63+
* Transforms a plain {@link Order} into a Querydsl specific {@link OrderSpecifier}.
64+
*
65+
* @param order
66+
* @return
67+
*/
68+
@SuppressWarnings({ "rawtypes", "unchecked" })
69+
protected OrderSpecifier<?> toOrder(Order order) {
70+
71+
Expression<Object> property = builder.get(order.getProperty());
72+
73+
return new OrderSpecifier(
74+
order.isAscending() ? com.querydsl.core.types.Order.ASC : com.querydsl.core.types.Order.DESC, property);
75+
}
76+
77+
/**
78+
* Converts the given {@link Sort} to {@link OrderSpecifier}.
79+
*
80+
* @param sort
81+
* @return
82+
*/
83+
protected List<OrderSpecifier<?>> toOrderSpecifiers(Sort sort) {
84+
85+
if (sort instanceof QSort) {
86+
return ((QSort) sort).getOrderSpecifiers();
87+
}
88+
89+
return sort.stream().map(this::toOrder).collect(Collectors.toList());
90+
}
91+
92+
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveQuerydslMongoPredicateExecutor.java

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,29 @@
1818
import reactor.core.publisher.Flux;
1919
import reactor.core.publisher.Mono;
2020

21-
import java.util.List;
22-
2321
import org.springframework.data.domain.Sort;
24-
import org.springframework.data.domain.Sort.Order;
2522
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
2623
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
2724
import org.springframework.data.querydsl.EntityPathResolver;
28-
import org.springframework.data.querydsl.QSort;
2925
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
3026
import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor;
3127
import org.springframework.data.querydsl.SimpleEntityPathResolver;
32-
import org.springframework.data.repository.core.EntityInformation;
3328
import org.springframework.util.Assert;
3429

3530
import com.querydsl.core.types.EntityPath;
36-
import com.querydsl.core.types.Expression;
3731
import com.querydsl.core.types.OrderSpecifier;
3832
import com.querydsl.core.types.Predicate;
39-
import com.querydsl.core.types.dsl.PathBuilder;
4033

4134
/**
4235
* MongoDB-specific {@link QuerydslPredicateExecutor} that allows execution {@link Predicate}s in various forms.
4336
*
4437
* @author Mark Paluch
38+
* @author Christoph Strobl
4539
* @since 2.2
4640
*/
47-
public class ReactiveQuerydslMongoPredicateExecutor<T> implements ReactiveQuerydslPredicateExecutor<T> {
41+
public class ReactiveQuerydslMongoPredicateExecutor<T> extends QuerydslPredicateExecutorSupport<T>
42+
implements ReactiveQuerydslPredicateExecutor<T> {
4843

49-
private final PathBuilder<T> builder;
50-
private final EntityInformation<T, ?> entityInformation;
5144
private final ReactiveMongoOperations mongoOperations;
5245

5346
/**
@@ -60,6 +53,7 @@ public class ReactiveQuerydslMongoPredicateExecutor<T> implements ReactiveQueryd
6053
*/
6154
public ReactiveQuerydslMongoPredicateExecutor(MongoEntityInformation<T, ?> entityInformation,
6255
ReactiveMongoOperations mongoOperations) {
56+
6357
this(entityInformation, mongoOperations, SimpleEntityPathResolver.INSTANCE);
6458
}
6559

@@ -74,12 +68,8 @@ public ReactiveQuerydslMongoPredicateExecutor(MongoEntityInformation<T, ?> entit
7468
public ReactiveQuerydslMongoPredicateExecutor(MongoEntityInformation<T, ?> entityInformation,
7569
ReactiveMongoOperations mongoOperations, EntityPathResolver resolver) {
7670

77-
Assert.notNull(resolver, "EntityPathResolver must not be null!");
78-
79-
EntityPath<T> path = resolver.createPath(entityInformation.getJavaType());
80-
81-
this.builder = new PathBuilder<T>(path.getType(), path.getMetadata());
82-
this.entityInformation = entityInformation;
71+
super(mongoOperations.getConverter(), pathBuilderFor(resolver.createPath(entityInformation.getJavaType())),
72+
entityInformation);
8373
this.mongoOperations = mongoOperations;
8474
}
8575

@@ -185,10 +175,9 @@ private ReactiveSpringDataMongodbQuery<T> createQueryFor(Predicate predicate) {
185175
* @return
186176
*/
187177
private ReactiveSpringDataMongodbQuery<T> createQuery() {
188-
SpringDataMongodbSerializer serializer = new SpringDataMongodbSerializer(mongoOperations.getConverter());
189178

190-
Class<T> javaType = entityInformation.getJavaType();
191-
return new ReactiveSpringDataMongodbQuery<>(serializer, mongoOperations, javaType,
179+
Class<T> javaType = typeInformation().getJavaType();
180+
return new ReactiveSpringDataMongodbQuery<>(mongodbSerializer(), mongoOperations, javaType,
192181
mongoOperations.getCollectionName(javaType));
193182
}
194183

@@ -201,32 +190,8 @@ private ReactiveSpringDataMongodbQuery<T> createQuery() {
201190
*/
202191
private ReactiveSpringDataMongodbQuery<T> applySorting(ReactiveSpringDataMongodbQuery<T> query, Sort sort) {
203192

204-
// TODO: find better solution than instanceof check
205-
if (sort instanceof QSort) {
206-
207-
List<OrderSpecifier<?>> orderSpecifiers = ((QSort) sort).getOrderSpecifiers();
208-
query.orderBy(orderSpecifiers.toArray(new OrderSpecifier<?>[orderSpecifiers.size()]));
209-
210-
return query;
211-
}
212-
213-
sort.stream().map(this::toOrder).forEach(query::orderBy);
214-
193+
toOrderSpecifiers(sort).forEach(query::orderBy);
215194
return query;
216195
}
217196

218-
/**
219-
* Transforms a plain {@link Order} into a Querydsl specific {@link OrderSpecifier}.
220-
*
221-
* @param order
222-
* @return
223-
*/
224-
@SuppressWarnings({ "rawtypes", "unchecked" })
225-
private OrderSpecifier<?> toOrder(Order order) {
226-
227-
Expression<Object> property = builder.get(order.getProperty());
228-
229-
return new OrderSpecifier(
230-
order.isAscending() ? com.querydsl.core.types.Order.ASC : com.querydsl.core.types.Order.DESC, property);
231-
}
232197
}

0 commit comments

Comments
 (0)