Skip to content

Commit bd5815d

Browse files
DATAMONGO-1827 - Polishing.
Allow open/close projection on return type for findAndReplace. Use default methods for delegation and remove collation from FindAndRemoveOption in favor of the collation set on the query itself. Update Javadoc and reference documentation. Original Pull Request: spring-projects#569
1 parent ac89ce1 commit bd5815d

16 files changed

+753
-270
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableUpdateOperation.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
import com.mongodb.client.result.UpdateResult;
2525

2626
/**
27-
* {@link ExecutableUpdateOperation} allows creation and execution of MongoDB update / findAndModify / findAndReplace operations in a
28-
* fluent API style. <br />
27+
* {@link ExecutableUpdateOperation} allows creation and execution of MongoDB update / findAndModify / findAndReplace
28+
* operations in a fluent API style. <br />
2929
* The starting {@literal domainType} is used for mapping the {@link Query} provided via {@code matching}, as well as
3030
* the {@link Update} via {@code apply} into the MongoDB specific representations. The collection to operate on is by
3131
* default derived from the initial {@literal domainType} and can be defined there via
@@ -59,6 +59,10 @@ public interface ExecutableUpdateOperation {
5959

6060
/**
6161
* Trigger findAndModify execution by calling one of the terminating methods.
62+
*
63+
* @author Christoph Strobl
64+
* @author Mark Paluch
65+
* @since 2.0
6266
*/
6367
interface TerminatingFindAndModify<T> {
6468

@@ -81,7 +85,12 @@ default Optional<T> findAndModify() {
8185
}
8286

8387
/**
84-
* Trigger findAndReplace execution by calling one of the terminating methods.
88+
* Trigger
89+
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
90+
* execution by calling one of the terminating methods.
91+
*
92+
* @author Mark Paluch
93+
* @since 2.1
8594
*/
8695
interface TerminatingFindAndReplace<T> {
8796

@@ -158,7 +167,7 @@ interface UpdateWithUpdate<T> {
158167
* @throws IllegalArgumentException if options is {@literal null}.
159168
* @since 2.1
160169
*/
161-
FindAndReplaceWithOptions<T> replaceWith(T replacement);
170+
FindAndReplaceWithProjection<T> replaceWith(T replacement);
162171
}
163172

164173
/**
@@ -220,6 +229,7 @@ interface FindAndModifyWithOptions<T> {
220229
* Define {@link FindAndReplaceOptions}.
221230
*
222231
* @author Mark Paluch
232+
* @author Christoph Strobl
223233
* @since 2.1
224234
*/
225235
interface FindAndReplaceWithOptions<T> extends TerminatingFindAndReplace<T> {
@@ -231,7 +241,28 @@ interface FindAndReplaceWithOptions<T> extends TerminatingFindAndReplace<T> {
231241
* @return new instance of {@link FindAndReplaceOptions}.
232242
* @throws IllegalArgumentException if options is {@literal null}.
233243
*/
234-
TerminatingFindAndReplace<T> withOptions(FindAndReplaceOptions options);
244+
FindAndReplaceWithProjection<T> withOptions(FindAndReplaceOptions options);
245+
}
246+
247+
/**
248+
* Result type override (Optional).
249+
*
250+
* @author Christoph Strobl
251+
* @since 2.1
252+
*/
253+
interface FindAndReplaceWithProjection<T> extends FindAndReplaceWithOptions<T> {
254+
255+
/**
256+
* Define the target type fields should be mapped to. <br />
257+
* Skip this step if you are anyway only interested in the original domain type.
258+
*
259+
* @param resultType must not be {@literal null}.
260+
* @param <R> result type.
261+
* @return new instance of {@link FindAndReplaceWithProjection}.
262+
* @throws IllegalArgumentException if resultType is {@literal null}.
263+
*/
264+
<R> FindAndReplaceWithOptions<R> as(Class<R> resultType);
265+
235266
}
236267

237268
/**

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableUpdateOperationSupport.java

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public <T> ExecutableUpdate<T> update(Class<T> domainType) {
5151

5252
Assert.notNull(domainType, "DomainType must not be null!");
5353

54-
return new ExecutableUpdateSupport<>(template, domainType, ALL_QUERY, null, null, null, null, null);
54+
return new ExecutableUpdateSupport<>(template, domainType, ALL_QUERY, null, null, null, null, null, domainType);
5555
}
5656

5757
/**
@@ -60,17 +60,19 @@ public <T> ExecutableUpdate<T> update(Class<T> domainType) {
6060
*/
6161
@RequiredArgsConstructor
6262
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
63-
static class ExecutableUpdateSupport<T> implements ExecutableUpdate<T>, UpdateWithCollection<T>, UpdateWithQuery<T>,
64-
TerminatingUpdate<T>, FindAndReplaceWithOptions<T>, TerminatingFindAndReplace<T> {
63+
static class ExecutableUpdateSupport<T>
64+
implements ExecutableUpdate<T>, UpdateWithCollection<T>, UpdateWithQuery<T>, TerminatingUpdate<T>,
65+
FindAndReplaceWithOptions<T>, TerminatingFindAndReplace<T>, FindAndReplaceWithProjection<T> {
6566

6667
@NonNull MongoTemplate template;
67-
@NonNull Class<T> domainType;
68+
@NonNull Class domainType;
6869
Query query;
6970
@Nullable Update update;
7071
@Nullable String collection;
7172
@Nullable FindAndModifyOptions findAndModifyOptions;
7273
@Nullable FindAndReplaceOptions findAndReplaceOptions;
73-
@Nullable T replacement;
74+
@Nullable Object replacement;
75+
@NonNull Class<T> targetType;
7476

7577
/*
7678
* (non-Javadoc)
@@ -82,7 +84,7 @@ public TerminatingUpdate<T> apply(Update update) {
8284
Assert.notNull(update, "Update must not be null!");
8385

8486
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
85-
findAndReplaceOptions, replacement);
87+
findAndReplaceOptions, replacement, targetType);
8688
}
8789

8890
/*
@@ -95,7 +97,7 @@ public UpdateWithQuery<T> inCollection(String collection) {
9597
Assert.hasText(collection, "Collection must not be null nor empty!");
9698

9799
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
98-
findAndReplaceOptions, replacement);
100+
findAndReplaceOptions, replacement, targetType);
99101
}
100102

101103
/*
@@ -108,33 +110,33 @@ public TerminatingFindAndModify<T> withOptions(FindAndModifyOptions options) {
108110
Assert.notNull(options, "Options must not be null!");
109111

110112
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, options,
111-
findAndReplaceOptions, replacement);
113+
findAndReplaceOptions, replacement, targetType);
112114
}
113115

114116
/*
115117
* (non-Javadoc)
116118
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.UpdateWithUpdate#replaceWith(Object)
117119
*/
118120
@Override
119-
public FindAndReplaceWithOptions<T> replaceWith(T replacement) {
121+
public FindAndReplaceWithProjection<T> replaceWith(T replacement) {
120122

121123
Assert.notNull(replacement, "Replacement must not be null!");
122124

123125
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
124-
findAndReplaceOptions, replacement);
126+
findAndReplaceOptions, replacement, targetType);
125127
}
126128

127129
/*
128130
* (non-Javadoc)
129131
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.FindAndReplaceWithOptions#withOptions(org.springframework.data.mongodb.core.FindAndReplaceOptions)
130132
*/
131133
@Override
132-
public TerminatingFindAndReplace<T> withOptions(FindAndReplaceOptions options) {
134+
public FindAndReplaceWithProjection<T> withOptions(FindAndReplaceOptions options) {
133135

134136
Assert.notNull(options, "Options must not be null!");
135137

136138
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
137-
options, replacement);
139+
options, replacement, targetType);
138140
}
139141

140142
/*
@@ -147,7 +149,20 @@ public UpdateWithUpdate<T> matching(Query query) {
147149
Assert.notNull(query, "Query must not be null!");
148150

149151
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
150-
findAndReplaceOptions, replacement);
152+
findAndReplaceOptions, replacement, targetType);
153+
}
154+
155+
/*
156+
* (non-Javadoc)
157+
* @see org.springframework.data.mongodb.core.ReactiveUpdateOperation.FindAndReplaceWithProjection#as(java.lang.Class)
158+
*/
159+
@Override
160+
public <R> FindAndReplaceWithOptions<R> as(Class<R> resultType) {
161+
162+
Assert.notNull(resultType, "ResultType must not be null!");
163+
164+
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
165+
findAndReplaceOptions, replacement, resultType);
151166
}
152167

153168
/*
@@ -183,8 +198,9 @@ public UpdateResult upsert() {
183198
*/
184199
@Override
185200
public @Nullable T findAndModifyValue() {
201+
186202
return template.findAndModify(query, update,
187-
findAndModifyOptions != null ? findAndModifyOptions : new FindAndModifyOptions(), domainType,
203+
findAndModifyOptions != null ? findAndModifyOptions : new FindAndModifyOptions(), targetType,
188204
getCollectionName());
189205
}
190206

@@ -194,9 +210,10 @@ public UpdateResult upsert() {
194210
*/
195211
@Override
196212
public @Nullable T findAndReplaceValue() {
197-
return template.findAndReplace(query, replacement,
198-
findAndReplaceOptions != null ? findAndReplaceOptions : new FindAndReplaceOptions(), domainType,
199-
getCollectionName());
213+
214+
return (T) template.findAndReplace(query, replacement,
215+
findAndReplaceOptions != null ? findAndReplaceOptions : FindAndReplaceOptions.empty(), domainType,
216+
getCollectionName(), targetType);
200217
}
201218

202219
private UpdateResult doUpdate(boolean multi, boolean upsert) {

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndModifyOptions.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,17 @@ public class FindAndModifyOptions {
3636
/**
3737
* Static factory method to create a FindAndModifyOptions instance
3838
*
39-
* @return a new instance
39+
* @return new instance of {@link FindAndModifyOptions}.
4040
*/
4141
public static FindAndModifyOptions options() {
4242
return new FindAndModifyOptions();
4343
}
4444

4545
/**
46-
* @param options
47-
* @return
46+
* Create new {@link FindAndModifyOptions} based on option of given {@litearl source}.
47+
*
48+
* @param source can be {@literal null}.
49+
* @return new instance of {@link FindAndModifyOptions}.
4850
* @since 2.0
4951
*/
5052
public static FindAndModifyOptions of(@Nullable FindAndModifyOptions source) {

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/FindAndReplaceOptions.java

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,90 +15,95 @@
1515
*/
1616
package org.springframework.data.mongodb.core;
1717

18-
import java.util.Optional;
19-
20-
import org.springframework.data.mongodb.core.query.Collation;
21-
import org.springframework.lang.Nullable;
22-
2318
/**
2419
* Options for
2520
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>.
21+
* <br />
22+
* Defaults to
23+
* <dl>
24+
* <dt>returnNew</dt>
25+
* <dd>false</dd>
26+
* <dt>upsert</dt>
27+
* <dd>false</dd>
28+
* </dl>
2629
*
2730
* @author Mark Paluch
31+
* @author Christoph Strobl
2832
* @since 2.1
2933
*/
3034
public class FindAndReplaceOptions {
3135

3236
private boolean returnNew;
3337
private boolean upsert;
3438

35-
private @Nullable Collation collation;
36-
3739
/**
3840
* Static factory method to create a {@link FindAndReplaceOptions} instance.
41+
* <dl>
42+
* <dt>returnNew</dt>
43+
* <dd>false</dd>
44+
* <dt>upsert</dt>
45+
* <dd>false</dd>
46+
* </dl>
3947
*
40-
* @return a new instance
48+
* @return new instance of {@link FindAndReplaceOptions}.
4149
*/
4250
public static FindAndReplaceOptions options() {
4351
return new FindAndReplaceOptions();
4452
}
4553

4654
/**
47-
* @param options
48-
* @return
55+
* Static factory method to create a {@link FindAndReplaceOptions} instance with
56+
* <dl>
57+
* <dt>returnNew</dt>
58+
* <dd>false</dd>
59+
* <dt>upsert</dt>
60+
* <dd>false</dd>
61+
* </dl>
62+
*
63+
* @return new instance of {@link FindAndReplaceOptions}.
4964
*/
50-
public static FindAndReplaceOptions of(@Nullable FindAndReplaceOptions source) {
51-
52-
FindAndReplaceOptions options = new FindAndReplaceOptions();
53-
54-
if (source == null) {
55-
return options;
56-
}
57-
58-
options.returnNew = source.returnNew;
59-
options.upsert = source.upsert;
60-
options.collation = source.collation;
61-
62-
return options;
65+
public static FindAndReplaceOptions empty() {
66+
return new FindAndReplaceOptions();
6367
}
6468

65-
public FindAndReplaceOptions returnNew(boolean returnNew) {
66-
this.returnNew = returnNew;
67-
return this;
68-
}
69+
/**
70+
* Return the replacement document.
71+
*
72+
* @return this.
73+
*/
74+
public FindAndReplaceOptions returnNew() {
6975

70-
public FindAndReplaceOptions upsert(boolean upsert) {
71-
this.upsert = upsert;
76+
this.returnNew = true;
7277
return this;
7378
}
7479

7580
/**
76-
* Define the {@link Collation} specifying language-specific rules for string comparison.
81+
* Insert a new document if not exists.
7782
*
78-
* @param collation
79-
* @return
83+
* @return this.
8084
*/
81-
public FindAndReplaceOptions collation(@Nullable Collation collation) {
85+
public FindAndReplaceOptions upsert() {
8286

83-
this.collation = collation;
87+
this.upsert = true;
8488
return this;
8589
}
8690

91+
/**
92+
* Get the bit indicating to return the replacement document.
93+
*
94+
* @return
95+
*/
8796
public boolean isReturnNew() {
8897
return returnNew;
8998
}
9099

91-
public boolean isUpsert() {
92-
return upsert;
93-
}
94-
95100
/**
96-
* Get the {@link Collation} specifying language-specific rules for string comparison.
101+
* Get the bit indicating if to create a new document if not exists.
97102
*
98103
* @return
99104
*/
100-
public Optional<Collation> getCollation() {
101-
return Optional.ofNullable(collation);
105+
public boolean isUpsert() {
106+
return upsert;
102107
}
103108

104109
}

0 commit comments

Comments
 (0)