Compare commits

...

457 Commits

Author SHA1 Message Date
Mark Paluch
008ca72888 Release version 3.1.13 (2020.0.13).
See #3768
2021-09-17 08:53:37 +02:00
Mark Paluch
c50dfba2cf Prepare 3.1.13 (2020.0.13).
See #3768
2021-09-17 08:53:09 +02:00
Christoph Strobl
701153ac8f Fix slice argument in query fields projection.
We now use a Collection instead of an Array to pass on $slice projection values for offset and limit.

Closes: #3811
Original pull request: #3812.
2021-09-08 14:47:48 +02:00
Mark Paluch
6b394e4da6 Avoid nested Document conversion to primitive types for fields with an explicit write target.
We now no longer attempt to convert query Documents into primitive types to avoid e.g. Document to String conversion.

Closes: #3783
Original Pull Request: #3797
2021-09-02 12:18:56 +02:00
Mark Paluch
7007f484a8 Polishing.
Fix typo in reference docs.

See #3758
2021-08-25 10:15:23 +02:00
Ryan Gibb
72a24a923d Fix a typo in MongoConverter javadoc.
Original pull request: #3758.
2021-08-25 10:15:23 +02:00
Mark Paluch
7f5591c20c Polishing.
Fix asterisk callouts.

See #3786
2021-08-24 11:19:06 +02:00
Mark Paluch
bf3b5dee70 Extract Aggregation Framework and GridFS docs in own source files.
Closes #3786
2021-08-24 11:09:47 +02:00
Jens Schauder
11838839cf After release cleanups.
See #3734
2021-08-12 10:36:57 +02:00
Jens Schauder
116d384bc5 Prepare next development iteration.
See #3734
2021-08-12 10:36:56 +02:00
Jens Schauder
6ce5a26dc6 Release version 3.1.12 (2020.0.12).
See #3734
2021-08-12 10:25:55 +02:00
Jens Schauder
2716d1d503 Prepare 3.1.12 (2020.0.12).
See #3734
2021-08-12 10:25:34 +02:00
Mark Paluch
32223fc00a Run unpaged query using Pageable.unpaged() through QuerydslMongoPredicateExecutor.findAll(…).
We now correctly consider unpaged queries if the Pageable is unpaged.

Closes: #3751
Original Pull Request: #3754
2021-07-26 15:23:42 +02:00
Jens Schauder
1884b7a97a After release cleanups.
See #3681
2021-07-16 10:45:19 +02:00
Jens Schauder
1f670bb5ed Prepare next development iteration.
See #3681
2021-07-16 10:45:17 +02:00
Jens Schauder
3e97d47248 Release version 3.1.11 (2020.0.11).
See #3681
2021-07-16 10:19:52 +02:00
Jens Schauder
c02840ca30 Prepare 3.1.11 (2020.0.11).
See #3681
2021-07-16 10:18:57 +02:00
Jens Schauder
975768c0d6 Updated changelog.
See #3681
2021-07-16 10:18:49 +02:00
Christoph Strobl
323ec3f1d6 Polishing.
Simplify KeyMapper current property/index setup.

Original Pull Request: #3689
2021-07-06 12:32:08 +02:00
David Julia
e480ceb2b7 Fix Regression in generating queries with nested maps with numeric keys.
While maps that have numeric keys work if there is only one map with an integer key, when there are multiple maps with numeric keys in a given query, it fails.

Take the following example for a map called outer with numeric keys holding reference to another object with a map called inner with numeric keys: Updates that are meant to generate {"$set": {"outerMap.1234.inner.5678": "hello"}} are instead generating {"$set": {"outerMap.1234.inner.inner": "hello"}}, repeating the later map property name instead of using the integer key value.

This commit adds unit tests both for the UpdateMapper and QueryMapper, which check multiple consecutive maps with numeric keys, and adds a fix in the KeyMapper. Because we cannot easily change the path parsing to somehow parse path parts corresponding to map keys differently, we address the issue in the KeyMapper. We keep track of the partial path corresponding to the current property and use it to skip adding the duplicated property name for the map to the query, and instead add the key.

This is a bit redundant in that we now have both an iterator and an index-based way of accessing the path parts, but it gets the tests passing and fixes the issue without making a large change to the current approach.

Fixes: #3688
Original Pull Request: #3689
2021-07-06 12:12:46 +02:00
Mark Paluch
9fedd8d8c3 Updated changelog.
See #3650
2021-06-22 16:07:27 +02:00
Mark Paluch
baddae25da After release cleanups.
See #3649
2021-06-22 15:28:51 +02:00
Mark Paluch
5064cf3e9a Prepare next development iteration.
See #3649
2021-06-22 15:28:47 +02:00
Mark Paluch
81271a4f2f Release version 3.1.10 (2020.0.10).
See #3649
2021-06-22 15:18:22 +02:00
Mark Paluch
c36f9988c7 Prepare 3.1.10 (2020.0.10).
See #3649
2021-06-22 15:17:54 +02:00
Mark Paluch
b49beb08b6 Updated changelog.
See #3649
2021-06-22 15:17:49 +02:00
Mark Paluch
18b0946879 Update reference docs to use correct MongoClient.
Closes #3666
2021-06-22 14:36:58 +02:00
larsw
cf3681f7c2 Add closing quote to GeoJson javadoc.
Closes #3677
2021-06-21 13:58:44 +02:00
Christoph Strobl
49ef3fbc74 Polishing.
Fix typo in class name and make sure MongoTestTemplate uses the configured simple types.

See: #3659
Original pull request: #3661.
2021-06-18 14:22:08 +02:00
Christoph Strobl
01141502a0 Fix query mapper path resolution for types considered simple ones.
spring-projects/spring-data-commons#2293 changed how PersistentProperty paths get resolved and considers potentially registered converters for those, which made the path resolution fail in during the query mapping process.
This commit makes sure to capture the according exception and continue with the given user input.

Fixes: #3659
Original pull request: #3661.
2021-06-18 14:14:45 +02:00
Christoph Strobl
5d8f3d5c8b Fix $or / $nor keyword mapping in query mapper.
This commit fixes an issue with the pattern used for detecting $or / $nor which also matched other keywords like $floor.

Closes: #3635
Original pull request: #3637.
2021-06-18 13:55:46 +02:00
Mark Paluch
5cf801ff8e Polishing.
Add nullability annotation. Return early on null value conversion.

See #3633
Original pull request: #3643.
2021-06-09 14:20:46 +02:00
Christoph Strobl
2f3fb4aea9 Fix NPE in QueryMapper when trying to apply target type on null value.
Closes #3633
Original pull request: #3643.
2021-06-09 14:20:45 +02:00
Mark Paluch
82e05e7e8e Updated changelog.
See #3629
2021-05-14 12:36:39 +02:00
Mark Paluch
5be2e3eea2 After release cleanups.
See #3628
2021-05-14 12:05:20 +02:00
Mark Paluch
54f55e04de Prepare next development iteration.
See #3628
2021-05-14 12:05:16 +02:00
Mark Paluch
9ef1386784 Release version 3.1.9 (2020.0.9).
See #3628
2021-05-14 11:52:23 +02:00
Mark Paluch
696fd725c3 Prepare 3.1.9 (2020.0.9).
See #3628
2021-05-14 11:51:53 +02:00
Mark Paluch
e6fda2ccdd Updated changelog.
See #3628
2021-05-14 11:51:46 +02:00
Greg L. Turnquist
7a24bab9a2 Authenticate with artifactory.
See #3616.
2021-04-22 15:04:01 -05:00
Mark Paluch
38b7fb7105 Updated changelog.
See #3616
2021-04-14 14:40:02 +02:00
Mark Paluch
d42d06e058 After release cleanups.
See #3617
2021-04-14 11:42:08 +02:00
Mark Paluch
e2709abfe0 Prepare next development iteration.
See #3617
2021-04-14 11:42:04 +02:00
Mark Paluch
12b4aab834 Release version 3.1.8 (2020.0.8).
See #3617
2021-04-14 11:33:25 +02:00
Mark Paluch
db06756c8f Prepare 3.1.8 (2020.0.8).
See #3617
2021-04-14 11:32:47 +02:00
Mark Paluch
b319b8a589 Updated changelog.
See #3617
2021-04-14 11:32:42 +02:00
Mark Paluch
a516795759 Updated changelog.
See #3597
2021-04-14 11:17:41 +02:00
Mark Paluch
bab08502a5 Polishing.
Fix nullability annotations for isEqual(…) parameters. Fix generics. Reformat code.

Add tests.

See #3414
Original pull request: #3615.
2021-04-13 09:40:00 +02:00
Clement Petit
3e1f95bc94 Handle nested Pattern and Document in Criteria.equals(…).
Closes #3414
Original pull request: #3615.
2021-04-13 09:39:59 +02:00
Mark Paluch
5c153dc76e Polishing.
Use ObjectUtils for empty check.

See #3623
Original pull request: #3625.
2021-04-13 09:09:42 +02:00
Christoph Strobl
8f4e207d97 Fix NPE in declarative aggregation execution.
This commit fixes an issue where using a simple return type leads to NPE when the actual aggregation result does not contain any values.

Closes: #3623
Original pull request: #3625.
2021-04-13 09:09:42 +02:00
Christoph Strobl
5000a40d72 Fix query mapping resolution of properties using underscore within field name.
Closes: #3601
Original pull request: #3607.
2021-04-09 12:27:08 +02:00
Mark Paluch
fb59f49dae After release cleanups.
See #3598
2021-03-31 18:29:41 +02:00
Mark Paluch
f3c1e014e9 Prepare next development iteration.
See #3598
2021-03-31 18:29:38 +02:00
Mark Paluch
f52cc3be1f Release version 3.1.7 (2020.0.7).
See #3598
2021-03-31 18:19:52 +02:00
Mark Paluch
1bda93858c Prepare 3.1.7 (2020.0.7).
See #3598
2021-03-31 18:19:19 +02:00
Mark Paluch
1808970daf Updated changelog.
See #3598
2021-03-31 18:19:13 +02:00
Mark Paluch
558fc28cce Updated changelog.
See #3595
2021-03-31 17:26:09 +02:00
Mark Paluch
16bef54f11 Use StringUtils.replace(…) instead of String.replaceAll(…) for mapKeyDotReplacement.
We now use StringUtils.replace(…) to replace the map key dot in MappingMongoConverter. StringUtils perform a plain search instead of using Regex which improves the overall performance.

Closes #3613
2021-03-30 14:29:50 +02:00
Mark Paluch
d68a812e1b Polishing.
Omit StreamUtils usage if input is a collection. Remove superfluous Flux.from(…). Simplify test and migrate test to JUnit 5.

See #3609.
Original pull request: #3611.
2021-03-29 11:02:34 +02:00
Clément Petit
ccb9f111d9 Return saved entity reference instead of original reference.
Make SimpleReactiveMongoRepository#saveAll(Publisher<S>) return the saved entity references instead of the original references.

Closes #3609
Original pull request: #3611.
2021-03-29 10:55:36 +02:00
Mark Paluch
f64b177c8f Updated changelog.
See #3558
2021-03-17 11:31:32 +01:00
Mark Paluch
c0c7ba767f After release cleanups.
See #3561
2021-03-17 11:02:15 +01:00
Mark Paluch
7639701f3f Prepare next development iteration.
See #3561
2021-03-17 11:02:13 +01:00
Mark Paluch
b39b2591b6 Release version 3.1.6 (2020.0.6).
See #3561
2021-03-17 10:54:12 +01:00
Mark Paluch
65c8317e38 Prepare 3.1.6 (2020.0.6).
See #3561
2021-03-17 10:53:43 +01:00
Mark Paluch
9d0f7bac6a Updated changelog.
See #3561
2021-03-17 10:53:41 +01:00
Mark Paluch
6f50747d21 Updated changelog.
See #3556
2021-03-17 10:35:15 +01:00
Mark Paluch
5cf1578ad3 Polishing.
Move hasValue(…) from DocumentAccessor to BsonUtils. Fix typo in tests.

See: #3590
Original pull request: #3591.
2021-03-15 14:03:33 +01:00
Christoph Strobl
78a59c45ca Fix ShardKey lookup for nested paths.
This commit fixes the lookup of shard key values for nested paths using the dot (.) notation.

Closes: #3590
Original pull request: #3591.
2021-03-15 14:02:49 +01:00
Christoph Strobl
dccdfc8b4d Upgrade MongoDB drivers to 4.1.2
Closes #3589
2021-03-15 09:17:52 +01:00
Mark Paluch
e48239eb8f Remove @Persistent from entity-scan include filters.
We now only scan for entities annotated with `@Document` to avoid inclusion of non-MongoDB entities. Previously, types annotated (or meta-annotated) with `@Persistent` were included as MongoDB entity which could lead to mapping rule violations.

Closes #3592
2021-03-11 15:08:05 +01:00
Christoph Strobl
c3b4f61d29 Preserve class keyword as Map key during update mapping.
This commit makes sure to skip the class property ob Object when mapping maps and their keys inside an Update.

Closes #3566
Original pull request: #3577.
2021-03-02 11:38:20 +01:00
Mark Paluch
22ed860b4a Polishing.
Reformat code. Reduce method visibility in JUnit 5 tests. Add Nullable annotations to address warnings.

See #3568
Original pull request: #3569.
2021-03-02 11:30:26 +01:00
Brice Vandeputte
bf642ad3f7 Translate MongoSocketException subclasses to DataAccessResourceFailureException.
Closes #3568
Original pull request: #3569.
2021-03-02 11:30:26 +01:00
Christoph Strobl
fcd48539ea Remove duplicate JSON Schema section from reference documentation.
Closes: #3573
Original pull request: #3574.
2021-03-01 14:42:33 +01:00
Mark Paluch
bf10f72a57 Polishing.
Simplify assertions.

See #3552.
Original pull request: #3565.
2021-02-22 09:57:03 +01:00
Christoph Strobl
1c652cce1c Preserve numeric keys that exceed Long range when mapping Updates.
This commit makes sure we preserve map keys no matter what.

Closes #3552.
Original pull request: #3565.
2021-02-22 09:57:02 +01:00
Mark Paluch
dc2de878bc Polishing.
Reformat code. Add since tags.

See #3395
Original pull request: #3554.
2021-02-18 15:08:49 +01:00
Christoph Strobl
00cacc02ac Fix case insensitive derived in queries on String properties.
We now consider the IgnoreCase part of a derived query when used along with In. Strings will be quoted to avoid malicious strings from being handed over to the server as a regular expression to evaluate.

See #3395
Original pull request: #3554.
2021-02-18 15:08:49 +01:00
Christoph Strobl
811c2e5d7b Updated changelog.
See #3560
2021-02-18 11:37:47 +01:00
Christoph Strobl
200f3006bd After release cleanups.
See #3557
2021-02-18 11:12:46 +01:00
Christoph Strobl
1d6bea51ec Prepare next development iteration.
See #3557
2021-02-18 11:12:44 +01:00
Christoph Strobl
7779ded45c Release version 3.1.5 (2020.0.5).
See #3557
2021-02-18 10:59:16 +01:00
Christoph Strobl
918bf7c138 Prepare 3.1.5 (2020.0.5).
See #3557
2021-02-18 10:58:49 +01:00
Christoph Strobl
abe3b9f6d7 Updated changelog.
See #3557
2021-02-18 10:58:42 +01:00
Christoph Strobl
41c453cc83 Updated changelog.
See #3537
2021-02-17 14:20:39 +01:00
Christoph Strobl
77784d88c7 After release cleanups.
See #3536
2021-02-17 13:41:54 +01:00
Christoph Strobl
263c62c880 Prepare next development iteration.
See #3536
2021-02-17 13:41:53 +01:00
Christoph Strobl
24ab8f67bb Release version 3.1.4 (2020.0.4).
See #3536
2021-02-17 12:00:24 +01:00
Christoph Strobl
572ceb867e Prepare 3.1.4 (2020.0.4).
See #3536
2021-02-17 11:59:37 +01:00
Christoph Strobl
b7caea8602 Updated changelog.
See #3536
2021-02-17 11:59:32 +01:00
Christoph Strobl
3696f2144f Updated changelog.
See #3520
2021-02-17 11:34:25 +01:00
Christoph Strobl
b25c8acca6 Updated changelog.
See #3519
2021-02-17 10:58:24 +01:00
Christoph Strobl
00d6271468 Fix DocumentToStringConverter UUID representation when calling toJson.
This commit makes sure to use an Encoder having UuidRepresentation set when calling org.bson.Document#toJson, preventing CodecConfigurationException from being raised.

Future versions will make sure the UUID string representation matches the Java default one.

Closes #3546.
Original pull request: #3551.
2021-02-17 07:47:49 +01:00
Christoph Strobl
bb603ba7b9 Updated reference documentation regarding GeoJsonModule.
Original pull request: #3539.
Closes #3517
2021-02-02 14:50:54 +01:00
Christoph Strobl
02eaa4cbd2 Allow access to mongoDatabaseFactory used in ReactiveMongoTemplate.
By offering a getter method for the ReactiveMongoDatabaseFactory users subclassing ReactiveMongoTemplate could evaluate the current transaction state via ReactiveMongoDatabaseUtils.isTransactionActive(getDatabaseFactory()).
This change also aligns the reactive and imperative template implementation in that regard.

Closes #3540
Original pull request: #3541.
2021-02-02 14:22:15 +01:00
Christoph Strobl
7429503c63 Update count vs. estimatedCount documentation.
Closes #3055
Original pull request: #3541.
2021-02-02 14:22:15 +01:00
Christoph Strobl
82f4e2276b Fix Criteria chaining for Criteria.alike().
This commit fixes an issue where an Example probe would not be added to the criteria chain.

Closes #3544
Original pull request: #3549.
2021-02-01 09:14:52 +01:00
Mark Paluch
e1bce7d942 Polishing.
Align type variable naming with imperative extensions(I, O). Add extension without accepting KClass. Update since tags and tests.

See #3508.
Original pull request: #893.
2021-01-27 09:57:39 +01:00
wonwoo
8bf3d395be Add missing ReactiveMongoOperations.aggregate Kotlin extension.
See #3508.
Original pull request: #893.
2021-01-27 09:57:39 +01:00
Christoph Strobl
d3c00a93c0 Update QBE Documentation section.
This commit adds a note explaining scenarios suitable for an UntypedExampleMatcher.

Closes: #3474
Original pull request: #3538.
2021-01-26 15:04:10 +01:00
Christoph Strobl
0aa805e1a2 Fix method names in full text query documentation.
Closes #3525
2021-01-20 08:29:52 +01:00
Christoph Strobl
9dc1df3deb Updated changelog.
See #3521
2021-01-13 15:49:50 +01:00
Christoph Strobl
92a73a5cc0 After release cleanups.
See #3477
2021-01-13 15:01:50 +01:00
Christoph Strobl
910d66afb0 Prepare next development iteration.
See #3477
2021-01-13 15:01:46 +01:00
Christoph Strobl
1b60eae771 Release version 3.1.3 (2020.0.3).
See #3477
2021-01-13 14:18:34 +01:00
Christoph Strobl
60dfdd7de6 Prepare 3.1.3 (2020.0.3).
See #3477
2021-01-13 14:17:43 +01:00
Christoph Strobl
4ec48c376d Updated changelog.
See #3477
2021-01-13 14:17:35 +01:00
Christoph Strobl
dee2ba15a4 Update issue tracker references after GitHub issues migration.
See: #3529
2021-01-12 13:57:14 +01:00
Mark Paluch
c3596a503c Update copyright year to 2021.
Closes #3534
2021-01-12 11:50:08 +01:00
Mark Paluch
7dca5a2218 DATAMONGO-2671 - Polishing.
Fix copyright header.

Original pull request: #897.
2021-01-11 12:15:15 +01:00
Mark Paluch
f493006ec9 DATAMONGO-2671 - Polishing.
Fix copyright header. Add since tags.

Original pull request: #897.
2021-01-11 12:15:15 +01:00
Christoph Strobl
a0d5c2bded DATAMONGO-2671 - Fix dateFromParts millisecond field name.
Use millisecond instead of milliseconds field name.

Related to: https://jira.mongodb.org/browse/DOCS-10652
Original pull request: #897.
2021-01-11 12:14:37 +01:00
Greg L. Turnquist
c697fe57c9 DATAMONGO-2665 - Use Docker hub credentials for all CI jobs, 2020-12-15 15:22:42 -06:00
Mark Paluch
8a23452fdc DATAMONGO-2653 - After release cleanups. 2020-12-09 16:46:53 +01:00
Mark Paluch
bec7023a43 DATAMONGO-2653 - Prepare next development iteration. 2020-12-09 16:46:46 +01:00
Mark Paluch
89a7309707 DATAMONGO-2653 - Release version 3.1.2 (2020.0.2). 2020-12-09 16:01:24 +01:00
Mark Paluch
55ec9c5e5b DATAMONGO-2653 - Prepare 3.1.2 (2020.0.2). 2020-12-09 16:00:53 +01:00
Mark Paluch
cbb4dcb025 DATAMONGO-2653 - Updated changelog. 2020-12-09 16:00:49 +01:00
Mark Paluch
a0bad13505 DATAMONGO-2649 - Updated changelog. 2020-12-09 15:33:27 +01:00
Mark Paluch
d13521ae5d DATAMONGO-2647 - Updated changelog. 2020-12-09 12:42:29 +01:00
Mark Paluch
51f1526214 DATAMONGO-2646 - Updated changelog. 2020-12-09 09:59:14 +01:00
Mark Paluch
d049d96952 DATAMONGO-2663 - Document Spring Data to MongoDB compatibility.
Original Pull Request: #895
2020-12-07 14:39:32 +01:00
Mark Paluch
885bf0eae9 DATAMONGO-2661 - Polishing.
Add ticket reference.

Original pull request: #894.
2020-11-26 11:46:31 +01:00
Yoann de Martino
2a8ffd53d8 DATAMONGO-2661 - Handle nullable types for KPropertyPath.
Original pull request: #894.
2020-11-26 11:46:24 +01:00
Mark Paluch
d54ed61581 DATAMONGO-2648 - After release cleanups. 2020-11-11 12:14:53 +01:00
Mark Paluch
9e76da91a9 DATAMONGO-2648 - Prepare next development iteration. 2020-11-11 12:14:50 +01:00
Mark Paluch
595fde7b04 DATAMONGO-2648 - Release version 3.1.1 (2020.0.1). 2020-11-11 11:58:58 +01:00
Mark Paluch
01f4e73b48 DATAMONGO-2648 - Prepare 3.1.1 (2020.0.1). 2020-11-11 11:58:35 +01:00
Mark Paluch
2934c4886b DATAMONGO-2648 - Updated changelog. 2020-11-11 11:58:18 +01:00
Christoph Strobl
080c798721 DATAMONGO-2644 - ProjectOperation no longer errors on inclusion of default _id field.
Original pull request: #890.
2020-11-10 09:40:49 +01:00
Christoph Strobl
7cfb68e6be DATAMONGO-2635 - Enforce aggregation pipeline mapping.
Avoid using the Aggregation.DEFAULT_CONTEXT which does not map contained values to the according MongoDB representation. We now use a relaxed aggregation context, preserving given field names, where possible.

Original pull request: #890.
2020-11-10 09:40:49 +01:00
Mark Paluch
1e24abe8e5 DATAMONGO-2639 - Enable maintenance branch build. 2020-10-29 09:43:58 +01:00
Mark Paluch
a316d156dc DATAMONGO-2639 - After release cleanups. 2020-10-28 16:10:54 +01:00
Mark Paluch
6563b125eb DATAMONGO-2639 - Prepare next development iteration. 2020-10-28 16:10:50 +01:00
Mark Paluch
c9251b1b29 DATAMONGO-2639 - Release version 3.1 GA (2020.0.0). 2020-10-28 15:46:54 +01:00
Mark Paluch
373f07e176 DATAMONGO-2639 - Prepare 3.1 GA (2020.0.0). 2020-10-28 15:46:31 +01:00
Mark Paluch
f5e2bdc7ef DATAMONGO-2639 - Updated changelog. 2020-10-28 15:46:17 +01:00
Mark Paluch
30e63fffe2 DATAMONGO-2625 - Updated changelog. 2020-10-28 15:03:01 +01:00
Mark Paluch
83136b4e60 DATAMONGO-2624 - Updated changelog. 2020-10-28 12:15:04 +01:00
Mark Paluch
56697545a3 DATAMONGO-2641 - Updated changelog. 2020-10-28 11:32:27 +01:00
Robin Dupret
76eecc443e DATAMONGO-2638 - Fix list item rendering in reference documentation.
Original Pull Request: #885
2020-10-27 13:31:45 +01:00
LiangYong
1f81806809 DATAMONGO-2638 - Fix aggregation input parameter syntax in reference documentation.
Original Pull Request: #881
2020-10-27 13:31:35 +01:00
Greg L. Turnquist
2d348be5b2 DATAMONGO-2629 - Use JDK 15 for next CI jobs. 2020-10-26 13:26:11 -05:00
Christoph Strobl
bbbe369093 DATAMONGO-2642 - Upgrade MongoDB drivers to 4.1.1. 2020-10-26 12:46:07 +01:00
Christoph Strobl
5aa29fc7b8 DATAMONGO-2626 - After release cleanups. 2020-10-14 14:48:47 +02:00
Christoph Strobl
05fc6546ff DATAMONGO-2626 - Prepare next development iteration. 2020-10-14 14:48:45 +02:00
Christoph Strobl
2c6e645a3d DATAMONGO-2626 - Release version 3.1 RC2 (2020.0.0). 2020-10-14 14:28:55 +02:00
Christoph Strobl
20f702512b DATAMONGO-2626 - Prepare 3.1 RC2 (2020.0.0). 2020-10-14 14:27:37 +02:00
Christoph Strobl
ad77f23364 DATAMONGO-2626 - Updated changelog. 2020-10-14 14:27:30 +02:00
Mark Paluch
9af8a73290 DATAMONGO-2616 - Polishing.
Reformat code. Merge if-statements.

Original pull request: #889.
2020-10-07 11:35:47 +02:00
Christoph Strobl
aaa4557887 DATAMONGO-2616 - Short circuit id value assignment in MongoConverter.
Original pull request: #889.
2020-10-07 11:35:40 +02:00
Mark Paluch
217be64a77 DATAMONGO-2623 - Polishing.
Avoid nullable method arguments and add assertions. Introduce build() method to AccumulatorFinalizeBuilder to build Accumulator without specifying a finalize function.

Original pull request: #887.
2020-10-07 09:51:08 +02:00
Christoph Strobl
0ef852a8fc DATAMONGO-2623 - Add support for $function and $accumulator aggregation operators.
Original pull request: #887.
2020-10-07 09:50:51 +02:00
Mark Paluch
26f0a1c7f9 DATAMONGO-2622 - Polishing.
Rename AggregationPipeline.requiresRelaxedChecking() to containsUnionWith() to avoid the concept of field validation leaking into AggregationPipeline.

Refactor AggregationOperation to consistently check their type and fallback to the operator check to allow for consistent checks when using custo AggregationOperations.

Original pull request: #886.
2020-10-06 12:09:18 +02:00
Christoph Strobl
230c32041a DATAMONGO-2622 - Add support for $unionWith aggregation stage.
We now support the $unionWith aggregation stage via the UnionWithOperation that performs a union of two collections by combining pipeline results, potentially containing duplicates, into a single result set that is handed over to the next stage.
In order to remove duplicates it is possible to append a GroupOperation right after UnionWithOperation.
If the UnionWithOperation uses a pipeline to process documents, field names within the pipeline will be treated as is. In order to map domain type property names to actual field names (considering potential org.springframework.data.mongodb.core.mapping.Field annotations) make sure the enclosing aggregation is a TypedAggregation and provide the target type for the $unionWith stage via mapFieldsTo(Class).

Original pull request: #886.
2020-10-06 12:09:12 +02:00
Mark Paluch
4548d07826 DATAMONGO-2596 - Polishing.
Refactor KPropertyPath.toString() into KProperty.asPath() extension function to allow rendering simple properties and property paths into a String property path.

Original pull request: #880.
2020-10-06 10:18:52 +02:00
Yoann de Martino
b879ec8c0f DATAMONGO-2596 - Introduce extension to render KProperty/KPropertyPath as property path.
Original pull request: #880.
2020-10-06 10:18:19 +02:00
Mark Paluch
c0581c4943 DATAMONGO-2294 - Polishing.
Reorganize imports after Delomboking. Use for-loop instead of Stream.forEach(…). Add Javadoc to methods. Add since tags.

Simplify tests.

Original pull request: #761.
2020-10-05 17:00:58 +02:00
owen-q
85022d24f3 DATAMONGO-2294 - Support query projections with collection types.
Query include/exclude now accepts a vararg array of fields to specify multiple fields at once.

Original pull request: #761.
2020-10-05 17:00:37 +02:00
Christoph Strobl
b2927ab419 DATAMONGO-2633 - Fix json parsing of nested arrays in ParameterBindingDocumentCodec.
Original pull request: #888.
2020-10-05 15:34:50 +02:00
Mark Paluch
91c39e2825 DATAMONGO-2630 - Add support for suspend repository query methods returning List<T>. 2020-09-22 15:01:09 +02:00
Greg L. Turnquist
965a34efd3 DATAMONGO-2629 - Only test other versions for local changes on main branch. 2020-09-18 11:08:38 -05:00
Mark Paluch
046cbb52a1 DATAMONGO-2608 - After release cleanups. 2020-09-16 14:05:28 +02:00
Mark Paluch
edfd07a3d0 DATAMONGO-2608 - Prepare next development iteration. 2020-09-16 14:05:24 +02:00
Mark Paluch
b4befc36c0 DATAMONGO-2608 - Release version 3.1 RC1 (2020.0.0). 2020-09-16 13:57:41 +02:00
Mark Paluch
6034fc1cbd DATAMONGO-2608 - Prepare 3.1 RC1 (2020.0.0). 2020-09-16 13:57:08 +02:00
Mark Paluch
61f4770b4a DATAMONGO-2608 - Updated changelog. 2020-09-16 13:56:57 +02:00
Mark Paluch
c9cfe7acd6 DATAMONGO-2609 - Updated changelog. 2020-09-16 12:16:30 +02:00
Mark Paluch
415ceeef63 DATAMONGO-2593 - Updated changelog. 2020-09-16 11:20:07 +02:00
Mark Paluch
1bdcb88430 DATAMONGO-2592 - Updated changelog. 2020-09-16 10:38:57 +02:00
Christoph Strobl
1a134aa444 DATAMONGO-2618 - Fix visibility of ReplaceRootDocumentOperation. 2020-09-14 13:43:56 +02:00
Mark Paluch
c1da95f5dc DATAMONGO-2621 - Adapt to changed array assertions in AssertJ. 2020-09-09 15:55:48 +02:00
Christoph Strobl
c9c005400c DATAMONGO-2613 - Polishing.
Use the opportunity to remove public modifiers from touched test class.

Original Pull Request: #883
2020-08-20 09:00:21 +02:00
Michal Kurcius
b388659c3f DATAMONGO-2613 - Fix single element ArrayJsonSchemaObject to document mapping.
Now toDocument calls toDocument on items correctly.

Original Pull Request: #883
2020-08-20 08:59:46 +02:00
Mark Paluch
90aa7b8f89 DATAMONGO-2594 - Updated changelog. 2020-08-12 13:25:47 +02:00
Mark Paluch
542de64711 DATAMONGO-2579 - After release cleanups. 2020-08-12 12:00:22 +02:00
Mark Paluch
88b1f9fcb3 DATAMONGO-2579 - Prepare next development iteration. 2020-08-12 12:00:19 +02:00
Mark Paluch
450365992a DATAMONGO-2579 - Release version 3.1 M2 (2020.0.0). 2020-08-12 11:52:05 +02:00
Mark Paluch
fd25f39236 DATAMONGO-2579 - Prepare 3.1 M2 (2020.0.0). 2020-08-12 11:51:40 +02:00
Mark Paluch
a7e3ed2e37 DATAMONGO-2579 - Updated changelog. 2020-08-12 11:51:28 +02:00
Mark Paluch
5795a507bd DATAMONGO-1836 - Polishing.
Revert constructor change of AggregationOptions to not break existing code. Update since tags. Reformat code.

Align visibility of AggregationOptionsTests with JUnit 5 rules. Update documentation.

Original pull request: #878.
2020-08-06 11:25:41 +02:00
Yadhukrishna S Pai
22bd3e64be DATAMONGO-1836 - Add support to hint in aggregation options.
Original pull request: #878.
2020-08-06 11:25:36 +02:00
Mark Paluch
6e47d5c76e DATAMONGO-2603 - Polishing.
Add missing Deprecated annotation.
2020-08-04 13:35:26 +02:00
Mark Paluch
bfab233d2f DATAMONGO-2603 - Adopt to Reactor 3.4 changes.
Align with ContextView and changes in other operators.
2020-08-04 13:35:26 +02:00
Christoph Strobl
c6f12ef0e2 DATAMONGO-2602 - Upgrade MongoDB drivers to 4.1.0 2020-08-03 17:14:24 +02:00
Mark Paluch
707ad8e232 DATAMONGO-1894 - Polishing.
Preinitialize EvaluationContextProvider with ReactiveQueryMethodEvaluationContextProvider to not require setting properties on vanilla ReactiveMongoRepositoryFactory objects.
2020-07-31 11:44:07 +02:00
Mark Paluch
b1f5717d63 DATAMONGO-2601 - Suppress results for suspended query methods returning kotlin.Unit.
We now discard results for suspended query methods if the return type is kotlin.Unit.

Related ticket: DATACMNS-1779
2020-07-31 11:44:07 +02:00
Mark Paluch
95c9789f43 DATAMONGO-2599 - Eagerly consider enum types as simple types.
MongoSimpleTypes now eagerly checks if a type is a simple one to avoid PersistentEntity registration for ChronoUnit.
2020-07-30 16:19:10 +02:00
Mark Paluch
8e84d397e2 DATAMONGO-2564 - Fix link to code of conduct. 2020-07-28 15:40:26 +02:00
Mark Paluch
2ea3ceda2d DATAMONGO-2598 - Polishing.
Original pull request: #872.
2020-07-28 15:21:05 +02:00
Jay Bryant
6a43f28466 DATAMONGO-2598 - Wording changes.
Removed the language of oppression and violence
and replaced it with more neutral language.

Note that problematic words in the code have
to remain in the docs until the code changes.

Original pull request: #872.
2020-07-28 15:20:55 +02:00
Mark Paluch
a44a0034b7 DATAMONGO-2557 - Polishing.
Inline methods.

Original pull request: #879.
2020-07-27 09:02:05 +02:00
Christoph Strobl
0085c8063a DATAMONGO-2557 - Use configured CodecRegistry when parsing String based queries instead of default one.
Original pull request: #879.
2020-07-27 09:01:58 +02:00
Christoph Strobl
873fffa202 DATAMONGO-1894 - Polishing.
Remove superfluous Optional wrappers and unify SpEL dependency resolution.

Original Pull Request: #874
2020-07-22 14:02:12 +02:00
Mark Paluch
41607b10d0 DATAMONGO-1894 - Introduce cached ExpressionParser.
Original Pull Request: #874
2020-07-22 14:01:47 +02:00
Mark Paluch
66fae82798 DATAMONGO-1894 - Use reactive SpEL extensions for SpEL evaluation in query execution.
Original Pull Request: #874
2020-07-22 14:01:20 +02:00
Christoph Strobl
00aaf2145b DATAMONGO-2591 - Upgrade MongoDB drivers to 4.1.0-rc0. 2020-07-22 13:27:51 +02:00
Mark Paluch
430c166a2b DATAMONGO-2568 - Updated changelog. 2020-07-22 10:37:57 +02:00
Mark Paluch
79c647a4d8 DATAMONGO-2567 - Updated changelog. 2020-07-22 10:08:43 +02:00
Mark Paluch
1b5a22730b DATAMONGO-2566 - Updated changelog. 2020-07-22 09:44:28 +02:00
Christoph Strobl
a8a364c2de DATAMONGO-2586 - Polishing.
Add tests to ensure no reactive auditing callback is registered when using imperative configuration and vice versa.
Update wording and minor code style tweaks.

Original Pull Request: #877
2020-07-17 11:09:35 +02:00
Mark Paluch
6bafcea539 DATAMONGO-2586 - Add support for reactive auditing.
We now provide a fully reactive variant for auditing with EnableReactiveMongoAuditing.

Original Pull Request: #877
2020-07-17 10:42:41 +02:00
Mark Paluch
2c1a3cf03e DATAMONGO-2536 - Polishing.
Encapsulate skipResults in AggregationOptions. Reformat code. Add override Javadoc.

Original pull request: #876.
2020-07-16 09:42:42 +02:00
Christoph Strobl
6cb89d7452 DATAMONGO-2536 - Add option to skip reading aggregation result.
Introduce dedicated AggregationPipeline to encapsulate pipeline stages.

Original pull request: #876.
2020-07-16 09:42:26 +02:00
Mark Paluch
2026f8729e DATAMONGO-2571 - Polishing.
Reduce test method visibility for JUnit 5.

Original pull request: #873.
2020-07-15 15:33:38 +02:00
Christoph Strobl
bf89400182 DATAMONGO-2571 - Fix regular expression parameter binding for String-based queries.
Original pull request: #873.
2020-07-15 15:33:30 +02:00
Mark Paluch
6c8cb9eb85 DATAMONGO-2490 - Polishing.
Remove unnecessary code. Reuse session-associated collection when logging to avoid unqualified calls to MongoDbFactory.getMongoDatabase(). Create collection before transaction in test for compatibility with older MongoDB servers.

Original pull request: #875.
2020-07-15 15:13:58 +02:00
Christoph Strobl
966504dfa6 DATAMONGO-2490 - Fix dbref fetching during ongoing transaction.
Original pull request: #875.
2020-07-15 15:13:50 +02:00
Mark Paluch
b266bd6feb DATAMONGO-2544 - After release cleanups. 2020-06-25 11:58:22 +02:00
Mark Paluch
a6a4a0b3b6 DATAMONGO-2544 - Prepare next development iteration. 2020-06-25 11:58:19 +02:00
Mark Paluch
2a66cadaa6 DATAMONGO-2544 - Release version 3.1 M1 (2020.0.0). 2020-06-25 11:48:49 +02:00
Mark Paluch
a70629697b DATAMONGO-2544 - Prepare 3.1 M1 (2020.0.0). 2020-06-25 11:48:19 +02:00
Mark Paluch
d52785533d DATAMONGO-2544 - Updated changelog. 2020-06-25 11:48:10 +02:00
Christoph Strobl
cee1d976de DATAMONGO-2285 - Polishing.
Preserve existing logic translating com.mongodb.MongoBulkWriteException that might be thrown by calling MongoOperations.insertAll(Collection), and move bulk operation translation to DefaultBulkOperations.
Along the lines remove the no longer used PersistenceExceptionTranslator from DefaultBulkOperations.

Original Pull Request: #862
2020-06-23 13:22:03 +02:00
Jacob Botuck
f907dbc559 DATAMONGO-2285 - Throw BulkOperationException instead of translated one when running bulk operations.
Return BulkOperationException unless it is a writeConcernError in which case use existing behavior.

Original Pull Request: #862
2020-06-23 13:21:24 +02:00
Christoph Strobl
613d085bb7 DATAMONGO-1569 - Polishing.
Update Javadoc and avoid unrelated index creation during tests due to class path scanning.

Original Pull Request: #738
2020-06-22 13:32:03 +02:00
Christoph Strobl
94a64a156f DATAMONGO-1569 - Add partialFilter to Indexed annotation.
Original Pull Request: #738
2020-06-22 13:32:03 +02:00
Dave Perryman
41e60e5c25 DATAMONGO-1569 - Add support for partial filter expressions in compound index annotations
Original Pull Request: #738
2020-06-22 13:32:03 +02:00
Christoph Strobl
a254576a6e DATAMONGO-2574 - Polishing.
Fix issue in reactive API and add unit tests.

Original Pull Request: #868
2020-06-22 13:32:03 +02:00
konradend
390b5e7b7e DATAMONGO-2574 - Do not overwrite contentType for GridFsFile.
Original Pull Request: #868
2020-06-22 13:32:03 +02:00
Mark Paluch
66dcb8f662 DATAMONGO-2576 - Upgrade to Hibernate Validator 5.4.3.
Add also javax.el to avoid failures in early expression language initialization.
2020-06-22 13:21:32 +02:00
Christoph Strobl
2eaa2d38af DATAMONGO-2556 - Polishing.
Original pull request: #867.
2020-06-22 13:02:14 +02:00
Christoph Strobl
1290898c2b DATAMONGO-2556 - Add estimatedCount for collections.
The newly introduced methods delegate to the drivers MongoCollection.estimatedDocumentCount.

Original pull request: #867.
2020-06-22 13:02:06 +02:00
Mark Paluch
c4ae269b14 DATAMONGO-2570 - Polishing.
Add assertions. Use method references where possible.

Original pull request: #871.
2020-06-22 10:39:44 +02:00
Mehran Behnam
a4ef46d641 DATAMONGO-2570 - Change type of count variable to primitive.
Avoiding unintentional unboxing.

Original pull request: #871.
2020-06-22 10:39:25 +02:00
Mark Paluch
a27939808b DATAMONGO-2558 - Polishing.
Fixed issue number in tests.

Original pull request: #866.
2020-06-21 20:04:09 +02:00
Mark Paluch
da7fc927fa DATAMONGO-2558 - Add integration test for RxJava 3 repositories.
Update Javadoc and reference documentation.

Original pull request: #866.
2020-06-21 20:03:30 +02:00
Christoph Strobl
f768906684 DATAMONGO-2572 - Remove trailing whitespaces from xsd files.
Original Pull Request: #870
2020-06-17 13:07:00 +02:00
Mark Paluch
61a228f8ac DATAMONGO-2572 - Remove usage of Oppressive Language.
Replaced blacklist with denylist and introduce meta keyword SECONDARY_READS as we no longer use MongoDB API with the initial replication concept.

Original Pull Request: #870
2020-06-17 13:05:45 +02:00
Mark Paluch
837b333d7a DATAMONGO-2543 - Updated changelog. 2020-06-10 14:30:55 +02:00
Mark Paluch
ffd4166b65 DATAMONGO-2533 - Updated changelog. 2020-06-10 12:29:55 +02:00
Mark Paluch
083050fc3c DATAMONGO-2532 - Updated changelog. 2020-06-10 11:48:52 +02:00
Mark Paluch
efbf9c8305 DATAMONGO-2565 - Polishing.
Add unit test to verify behavior. Cleanup code.

Original pull request: #869.
2020-06-10 10:25:25 +02:00
BraveLeeLee
4fdf171f7d DATAMONGO-2565 - Evaluate correct expression when obtaining collation from MongoPersistentEntity.
Original pull request: #869.
2020-06-10 10:25:25 +02:00
Mark Paluch
76990f4915 DATAMONGO-2564 - Use standard Spring code of conduct.
Using https://github.com/spring-projects/.github/blob/master/CODE_OF_CONDUCT.md.
2020-06-09 16:10:27 +02:00
Mark Paluch
4defad57c9 DATAMONGO-2562 - Polishing.
Fix typo in exception message.
2020-06-09 11:18:25 +02:00
Mark Paluch
431f7e6b78 DATAMONGO-2562 - Fix return type detection for suspended Kotlin methods.
See DATACMNS-1738 for further reference.
2020-06-09 11:18:25 +02:00
Mark Paluch
e5157f1c17 DATAMONGO-2560 - Upgrade MongoDB drivers to 4.0.4. 2020-06-08 15:54:53 +02:00
Mark Paluch
af091bf6be DATAMONGO-2542 - Polishing.
Fix nullable annotation.

Original pull request: #863.
2020-05-26 10:32:03 +02:00
Christoph Strobl
84ac0e8a85 DATAMONGO-2542 - Shortcut PersistentPropertyPath resolution during query mapping.
By shortcutting the path resolution we avoid checking keywords like $in against a potential path expression.

Original pull request: #863.
2020-05-26 10:31:57 +02:00
Mark Paluch
2a150adc40 DATAMONGO-2545 - Polishing.
Fix warnings and typos.

Original pull request: #864.
2020-05-26 10:14:18 +02:00
Christoph Strobl
feb3018d19 DATAMONGO-2545 - Fix full Query Document binding resulting from SpEL.
We reenabled annotated queries using a SpEL expression resulting in the actual query document.

Original pull request: #864.
2020-05-26 10:14:14 +02:00
Christoph Strobl
3af7269dbb DATAMONGO-2545 - Fix regression in String query SpEL parameter binding.
We reenabled parameter binding within SpEL using query parameter placeholders ?0, ?1,... instead of their array index [0],[1],...

Original pull request: #864.
2020-05-26 10:14:08 +02:00
Christoph Strobl
af39b422b6 DATAMONGO-2547 - Use target class ClassLoader instead of default CL when creating proxy instances.
Original pull request: #865.
2020-05-26 08:50:01 +02:00
Mark Paluch
8b50778350 DATAMONGO-2553 - Fix reference documentation links.
Remove links to removed documentations sections.
2020-05-19 11:36:37 +02:00
Mark Paluch
ce2f8a7bf5 DATAMONGO-2538 - Polishing.
Reformat code. Convert utility classes to abstract ones.

Original pull request: #861.
2020-05-14 11:02:38 +02:00
Christoph Strobl
26fa0c8285 DATAMONGO-2538 - Delombok source files.
Original pull request: #861.
2020-05-14 11:02:20 +02:00
Mark Paluch
3fda554f81 DATAMONGO-2534 - After release cleanups. 2020-05-12 12:40:30 +02:00
Mark Paluch
c6a86226e0 DATAMONGO-2534 - Prepare next development iteration. 2020-05-12 12:40:28 +02:00
Mark Paluch
f88d1de068 DATAMONGO-2534 - Release version 3.0 GA (Neumann). 2020-05-12 12:28:23 +02:00
Mark Paluch
62bfde2b6b DATAMONGO-2534 - Prepare 3.0 GA (Neumann). 2020-05-12 12:27:59 +02:00
Mark Paluch
93a27f80a3 DATAMONGO-2534 - Updated changelog. 2020-05-12 12:27:47 +02:00
Christoph Strobl
c2b0090ff1 DATAMONGO-2541 - Upgrade to MongoDB 4.0.3 Drivers. 2020-05-11 17:00:39 +02:00
Florian Bernard
0345abb5f8 DATAMONGO-2509 - Add missing Query constructor in reference documentation.
Original pull request: #846.
2020-05-06 11:52:16 +02:00
Mark Paluch
35196e3129 DATAMONGO-2509 - Polishing.
Fix typos, improve wording. Reworks documentation specific to MongoDB 3 and 4.

Original pull request: #853.
2020-05-06 11:46:29 +02:00
Christoph Strobl
37d99c4948 DATAMONGO-2509 - Update Javadoc.
Original pull request: #853.
2020-05-06 11:21:11 +02:00
Christoph Strobl
288e04b2d3 DATAMONGO-2509 - Update Reference Documentation.
Related to: DATAMONGO-365, DATAMONGO-384, DATAMONGO-2192, DATAMONGO-2407

Original pull request: #853.
2020-05-06 11:21:02 +02:00
Greg Turnquist
689c1480bd DATAMONGO-2535 - Remove Travis CI. 2020-05-04 15:09:00 -05:00
Mark Paluch
09fbe6060e DATAMONGO-2503 - After release cleanups. 2020-04-28 15:11:43 +02:00
Mark Paluch
d5cf3dfc22 DATAMONGO-2503 - Prepare next development iteration. 2020-04-28 15:11:42 +02:00
Mark Paluch
0f987f44ef DATAMONGO-2503 - Release version 3.0 RC2 (Neumann). 2020-04-28 15:03:53 +02:00
Mark Paluch
5df22233d8 DATAMONGO-2503 - Prepare 3.0 RC2 (Neumann). 2020-04-28 15:03:33 +02:00
Mark Paluch
9751c6bc8b DATAMONGO-2503 - Updated changelog. 2020-04-28 15:03:26 +02:00
Mark Paluch
7dc509953a DATAMONGO-2500 - Updated changelog. 2020-04-28 14:46:50 +02:00
Mark Paluch
2f4f1e524d DATAMONGO-2484 - Updated changelog. 2020-04-28 11:59:01 +02:00
Christoph Strobl
26ddf9d59f DATAMONGO-2531 - Fix MongoClientSettings UUID configuration hook in MongoConfigurationSupport.
Client code overriding configureClientSettings does not automatically remove the default UUidRepresentation settings.
2020-04-27 09:30:37 +02:00
Mark Paluch
96ff4e1d14 DATAMONGO-2461 - Polishing.
Remove superfluous Test annotation as RepeatFailedTest acts as a TestTemplate so adding the Test annotation causes the test to run twice.
2020-04-24 09:03:18 +02:00
Mark Paluch
2af13c27a7 DATAMONGO-2529 - Ensure that MappingMongoConverter.read(…) is never called with null.
Previously, various methods attempted to pass a null argument as source for the converter. The API is non-null and implementations relying on these constraints were easily breakable.

We now make sure that the source is never null.
2020-04-23 14:57:52 +02:00
Mark Paluch
f4d2fc6231 DATAMONGO-2504 - Polishing.
Update equals/hashCode implementation to use the Spring Data form. Make fields final where possible. Use diamond syntax. Reorder methods. Reformat code. Extend tests.

Original pull request: #848.
2020-04-23 12:24:26 +02:00
ddebray
3ab679bcc7 DATAMONGO-2504 - Add hashCode and equals to TextCriteria and Term.
Original pull request: #848.
2020-04-23 12:24:10 +02:00
Mark Paluch
318d552797 DATAMONGO-2505 - Polishing.
Simplify operators. Remove Lombok usage from newly introduced code. Update reference documentation. Reformat code.

Original pull request: #854.
2020-04-23 12:02:46 +02:00
Mathieu Ouellet
8cfbd39c7e DATAMONGO-2505 - Deferred Database retrieval from ReactiveMongoDatabaseFactory.
Change ReactiveMongoDatabaseFactory#getMongoDatabase() methods return Mono to enable access to the subscriber context.

Original pull request: #854.
2020-04-23 12:02:15 +02:00
Christoph Strobl
3a14af5485 DATAMONGO-2513 - Fix Eq aggregation operator comparing collection values.
Original pull request: #855.
2020-04-22 11:46:49 +02:00
Mark Paluch
00034d899a DATAMONGO-2516 - Polishing.
Reflect nullability change in TextScore Javadoc. Update documentation.

Original pull request: #856.
2020-04-22 11:12:50 +02:00
Christoph Strobl
fba6d7d8be DATAMONGO-2516 - Assert compatibility with MongoDB 4.4-rc0.
Fixes:
- Fields list must not contain text search score property when no $text criteria present.
- Sort must not be an empty document when running map reduce.
- Timeout in tests creating indexes.

Changes:
- score property might now be null when not having a $text criteria present. Was zero before.

Original pull request: #856.
2020-04-22 11:12:29 +02:00
Mark Paluch
95c4707902 DATAMONGO-2523 - Polishing.
Reformat code.

Original pull request: #859.
2020-04-22 10:14:50 +02:00
Christoph Strobl
32f3e60c9f DATAMONGO-2523 - Fix Json binding of SpEL expressions in arrays.
The closing bracket must not have a leading whitespace.

Original pull request: #859.
2020-04-22 10:08:57 +02:00
Mark Paluch
b57e571033 DATAMONGO-2517 - Polishing.
Reformat code.

Original pull request: #857.
2020-04-21 16:02:09 +02:00
Christoph Strobl
6604c507dd DATAMONGO-2517 - Fix invalid entity creation for text queries.
Fix a glitch in the MappingMongoConverter that uses the single String argument constructor (since it matches in type and parameter count to the given input string) to falsely instantiate an Entity when it should not.

Original pull request: #857.
2020-04-21 16:02:04 +02:00
Christoph Strobl
e1df28797a DATAMONGO-2507 - Polishing.
Add 'matching' default method also to imperative variant (ExecutableFindOperation), fix & add tests using 'distinct'.
Update Javadoc and rename input arg 'criteriaDefinition' to 'criteria'.

Original Pull Request: #852
2020-04-14 10:22:01 +02:00
Juergen Zimmermann
c6630aa279 DATAMONGO-2507 - Add default method matching(CriteriaDefinition) to ReactiveFindOperation.DistinctWithQuery.
Original Pull Request: #852
2020-04-14 09:51:23 +02:00
Greg Turnquist
bf921cdbd7 DATAMONGO-2510 - Use JDK 14 for Java.NEXT CI testing. 2020-04-09 14:29:16 -05:00
Christoph Strobl
a1b4e6df59 DATAMONGO-2508 - Upgrade to MongoDB 4.0.2 Drivers. 2020-04-08 11:38:19 +02:00
Christoph Strobl
4b3312998a DATAMONGO-2506 - Provide meaningful error message when using unsupported return type in repository aggregation method.
We improved the error message for unsupported return types instead of running into an IllegalArgumentException for unique results.

Original pull request: #851.
2020-04-07 14:58:38 +02:00
Mark Paluch
c5501db577 DATAMONGO-2502 - Polishing.
Extend tests. Fix generics. Consistently use compiled patterns for positional placeholder removal.

Original pull request: #847.
2020-04-07 14:10:20 +02:00
Christoph Strobl
936a0d35f7 DATAMONGO-2502 - Fix nested array path mapping for updates.
Original pull request: #847.
2020-04-07 14:10:09 +02:00
Christoph Strobl
5dd91d0b6d DATAMONGO-1677 - Polishing.
Switch tests to JUnit Jupiter.

Original Pull Request: #849
2020-04-06 08:51:30 +02:00
Jens Schauder
28510de6c8 DATAMONGO-1677 - Adds a test to confirm a query with more than 10 arguments works just fine.
Original Pull Request: #849
2020-04-06 08:50:56 +02:00
Mark Paluch
4bbf4cd5cf DATAMONGO-2492 - After release cleanups. 2020-03-31 15:08:05 +02:00
Mark Paluch
90bd3f0f18 DATAMONGO-2492 - Prepare next development iteration. 2020-03-31 15:08:04 +02:00
Mark Paluch
1e35116419 DATAMONGO-2492 - Release version 3.0 RC1 (Neumann). 2020-03-31 14:59:41 +02:00
Mark Paluch
dd336f0ecb DATAMONGO-2492 - Prepare 3.0 RC1 (Neumann). 2020-03-31 14:59:20 +02:00
Mark Paluch
d020219ded DATAMONGO-2492 - Updated changelog. 2020-03-31 14:59:15 +02:00
Mark Paluch
0345eff69a DATAMONGO-2477 - Polishing.
Make sure that indexes get created where needed.
2020-03-30 14:37:42 +02:00
Mark Paluch
55fee27fb6 DATAMONGO-625 - Polishing.
Introduce default interface methods where possible. Rename save(…) to store(…) to align with method naming. Reduce constructor visibility to avoid invalid API usage. Replace mutable object in builder with fields to avoid mutation of already built objects when reusing the builder.
Remove Options.chunked(…) factory method to avoid confusion with chunkSize method.

Reformat code, strip trailing whitespaces.

Original pull request: #842.
2020-03-30 14:19:45 +02:00
Christoph Strobl
ffba352e15 DATAMONGO-625 - Add support for GridFS with predefined id.
We now support storing GridFS content with predefined id, which allows to replace an existing resource instead of having to delete and reupload it.

Original pull request: #842.
2020-03-30 14:19:26 +02:00
Mark Paluch
1118df5550 DATAMONGO-2477 - Polishing.
Remove warn log for auto-index creation. Remove unused fields. Document index creation in reference documentation.

Original pull request: #845.
2020-03-26 15:14:03 +01:00
Christoph Strobl
29f05af733 DATAMONGO-2477 - Disable auto index creation by default.
Original pull request: #845.
2020-03-26 15:14:03 +01:00
Oliver Drotbohm
7bac739146 DATAMONGO-2501 - Upgrade to Querydsl 4.3.
Adapted to changes in the APT APIs.
2020-03-26 14:38:51 +01:00
Mark Paluch
6366d3cec1 DATAMONGO-2485 - Updated changelog. 2020-03-25 10:59:47 +01:00
Christoph Strobl
44913abd80 DATAMONGO-2300 - Polishing.
Move null check to event publishing logic.

Original Pull Request: #763
2020-03-23 09:29:49 +01:00
Heesu Jung
7a7f7c942d DATAMONGO-2300 - Add check rawType is null in readMap.
Original Pull Request: #763
2020-03-23 09:29:19 +01:00
Christoph Strobl
e9c9938016 DATAMONGO-2498 - Upgrade to MongoDB 4.0.1 Drivers. 2020-03-23 09:18:07 +01:00
Mark Paluch
c9da0a75ff DATAMONGO-931 - Polishing.
Reformat code. Add private constructor to prevent unwanted instantiation.

Original pull request: #844.
2020-03-20 14:45:11 +01:00
Christoph Strobl
581961e79a DATAMONGO-931 - Add support for $redact aggregation.
We now support $redact via Aggregation.redact.

Aggregation.redact(ConditionalOperators.when(Criteria.where("level").is(5))
    .then(RedactOperation.PRUNE)
    .otherwise(RedactOperation.DESCEND));

Original pull request: #844.
2020-03-20 14:40:16 +01:00
Christoph Strobl
0e0d726457 DATAMONGO-2475 - Polishing.
Fix reduction of $and/$or operations with more than two arguments.

Original Pull Request: #834
2020-03-20 10:15:10 +01:00
Enrique León Molina
7b5fea960f DATAMONGO-2475 - MongodbDocumentSerializer: reduce nested ANDs and ORs.
Reduce the number of nested $and / $or clauses by combining them into a single document where possible. This allows to simplify the following statement

{
  "$or": [
    {
      "$or": [
        {
          "$or": [
            {
              "$or": [
                { "firstname": "Hencxjo" },
                { "lastname": "Leon" }
              ]
            },
            { "age": { "$lte": 30 } }
          ]
        },
        { "age": { "$gte": 20 } }
      ]
    },
    { "uniqueId": { "$exists": false } }
  ]
}

to just

{
 "$or": [
   { "firstname": "Hencxjo" },
   { "lastname": "Leon" },
   { "age": { "$lte": 30 } },
   { "age": { "$gte": 20 } },
   { "uniqueId": { "$exists": false } }
 ]
}

Original Pull Request: #834
2020-03-20 10:13:37 +01:00
Mark Paluch
a04821ff90 DATAMONGO-2497 - Update documentation regarding @Transient properties usage in the persistence constructor. 2020-03-19 15:37:30 +01:00
Mark Paluch
a6bd41bcf2 DATAMONGO-2416 - Polishing.
Reduce visibility of JUnit 5 test classes/methods.

Original Pull Request: #840
2020-03-17 11:41:39 +01:00
Mark Paluch
6387eb9762 DATAMONGO-2416 - Add convenience methods accepting CriteriaDefinition on Fluent API.
The fluent API now exposes default interface methods accepting CriteriaDefinition for a more concise expression of queries that do not require a Query object.

template.query(Person.class).matching(where("firstname").is("luke")).all()

instead of

template.query(Person.class).matching(query(where("firstname").is("luke"))).all()

Original Pull Request: #840
2020-03-17 11:41:14 +01:00
Mark Paluch
5fb4b036bb DATAMONGO-1026 - Include documentation about custom conversions.
We now include the documentations partial about custom conversions that explains default converter registrations, overrides and system setting timezone-sensitivity.
2020-03-17 10:57:15 +01:00
Mark Paluch
4f0dc04a81 DATAMONGO-2479 - Polishing.
Tweak Javadoc. Update reference documentation. Slightly refactor reactive flows to reduce operator count.

Simplify test fixtures and remove Google Guava usage. Reformat code.

Original pull request: #839.
2020-03-16 11:34:27 +01:00
Roman Puchkovskiy
ee59c6b774 DATAMONGO-2479 - Add AfterConvertCallback and AfterSaveCallback (and their reactive versions).
Previously, only BeforeConvertCallback and BeforeSaveCallback were supported (and their reactive counterparts). This commit adds support for 'after-convert' and 'after-save' events using entity callbacks feature.

Original pull request: #839.
2020-03-16 11:34:13 +01:00
Mark Paluch
b0b905ddb7 DATAMONGO-2488 - Polishing.
Simplify conditional entity check. Reduce test method visibility for JUnit 5.

Original pull request: #841.
2020-03-11 14:51:03 +01:00
Christoph Strobl
7f7be5e47d DATAMONGO-2488 - Fix nested array path field name mapping.
Original pull request: #841.
2020-03-11 14:37:36 +01:00
Jens Schauder
5a49aa6519 DATAMONGO-2473 - After release cleanups. 2020-03-11 09:57:42 +01:00
Jens Schauder
b68079c421 DATAMONGO-2473 - Prepare next development iteration. 2020-03-11 09:57:41 +01:00
Jens Schauder
fde49f2a5a DATAMONGO-2473 - Release version 3.0 M4 (Neumann). 2020-03-11 09:47:07 +01:00
Jens Schauder
4d73d76b9f DATAMONGO-2473 - Prepare 3.0 M4 (Neumann). 2020-03-11 09:46:29 +01:00
Jens Schauder
8f2c806403 DATAMONGO-2473 - Updated changelog. 2020-03-11 09:46:17 +01:00
Mark Paluch
d0eb76946e DATAMONGO-2491 - Adapt to Mockito 3.3 changes.
Mockito reports falsely unnecessary stubbings so we're switching to the silent runner for these cases.
2020-03-11 09:14:53 +01:00
Mark Paluch
df43d7fcdb DATAMONGO-2355 - Refactor Abstract…Configuration classes to avoid need for cglib proxies.
Configuration methods now use parameter injections to avoid the need for cglib subclassing.
2020-03-10 14:17:37 +01:00
Mark Paluch
7b34a602ed DATAMONGO-2355 - Declare concrete Template API class type on AbstractReactiveMongoConfiguration.
We now declare bean methods returning Template API types with their concrete implementation to allow for improved introspection of bean definitions.
2020-03-10 13:55:41 +01:00
Mark Paluch
c829387c82 DATAMONGO-2363 - Polishing.
Introduce support for SpEL aggregation expressions for AddFields and Set operations.

Rearrange methods. Make fields final where possible.

Original pull request: #801.
2020-03-09 14:09:00 +01:00
Christoph Strobl
a4e12a96c9 DATAMONGO-2363 - Add support for $merge and $addFields aggregation stage.
MergeOperation.builder().intoCollection("monthlytotals")
    .whenDocumentsMatchApply(
        newAggregation(
            AddFieldsOperation.builder()
                .addField("thumbsup").withValueOf(sumOf("thumbsup").and("$$new.thumbsup"))
                .addField("thumbsdown").withValueOf(sumOf("thumbsdown").and("$$new.thumbsdown"))
                .build()
        )
    )
    .whenDocumentsDontMatch(insertNewDocument())
    .build()

Original pull request: #801.
2020-03-09 14:08:53 +01:00
Mark Paluch
7e3f7bd861 DATAMONGO-2481 - Polishing.
Add since tag.

Original pull request: #838.
2020-03-06 12:20:29 +01:00
Mark Paluch
46ab6b4c94 DATAMONGO-2481 - Polishing.
Migrate more tests to JUnit 5. Rearrange methods. Reduce method visibility according to JUnit 5 requirements.

Remove Java 11 build and only use Java 8 and 13.

Original pull request: #838.
2020-03-06 12:20:26 +01:00
Christoph Strobl
8029acb3fb DATAMONGO-2481 - Improve build time.
Introduce Junit Jupiter extensions.
Flush collections instead of dropping them.
Apply cursor timeout to change stream and capped collections in tests.

Original pull request: #838.
2020-03-06 12:20:20 +01:00
Christoph Strobl
96ffb0b7f4 DATAMONGO-2489 - Upgrade to MongoDB 4.0 Drivers. 2020-03-06 09:20:55 +01:00
Mark Paluch
7849b5333b DATAMONGO-2453 - Updated changelog. 2020-02-26 11:55:05 +01:00
Mark Paluch
fb45b4eb2a DATAMONGO-2452 - Updated changelog. 2020-02-26 11:31:48 +01:00
Mark Paluch
a6a84421b4 DATAMONGO-2478 - Polishing.
Convert test to JUnit 5.

Original pull request: #836.
2020-02-24 11:34:26 +01:00
Christoph Strobl
c4dcc7d0f5 DATAMONGO-2478 - Fix NPE in Query.of when given a proxied source.
Original pull request: #836.
2020-02-24 11:32:09 +01:00
Mark Paluch
c25a1a9e53 DATAMONGO-2476 - Polishing.
Convert test to JUnit 5.

Original pull request: #835.
2020-02-24 11:29:10 +01:00
Christoph Strobl
81c68955fe DATAMONGO-2476 - Fix Json parsing for unquoted placeholders in arrays.
Original pull request: #835.
2020-02-24 11:07:16 +01:00
Mark Paluch
22ca597fca DATAMONGO-2341 - Polishing.
Inline MongoPersistentEntity.idPropertyIsShardKey() into UpdateContext. Move mapped shard key cache to QueryOperations level. Simplify conditionals. Tweak documentation.

Original pull request: #833.
2020-02-17 10:17:35 +01:00
Christoph Strobl
6259cd2c3b DATAMONGO-2341 - Support shard key derivation in save operations via @Sharded annotation.
Spring Data MongoDB uses the @Sharded annotation to identify entities stored in sharded collections.
The shard key consists of a single or multiple properties present in every document within the target collection, and is used to distribute them across shards.

Spring Data MongoDB will do best effort optimisations for sharded scenarios when using repositories by adding required shard key information, if not already present, to replaceOne filter queries when upserting entities. This may require an additional server round trip to determine the actual value of the current shard key.

By setting @Sharded(immutableKey = true) no attempt will be made to check if an entities shard key changed.

Please see the MongoDB Documentation for further details and the list below for which operations are eligible to auto include the shard key.

* Reactive/CrudRepository.save(...)
* Reactive/CrudRepository.saveAll(...)
* Reactive/MongoTemplate.save(...)

Original pull request: #833.
2020-02-17 10:17:20 +01:00
Christoph Strobl
f153399c3b DATAMONGO-2474 - Upgrade to MongoDB driver 4.0.0-rc0. 2020-02-14 07:44:03 +01:00
Mark Paluch
65508eb01b DATAMONGO-2456 - After release cleanups. 2020-02-12 15:04:22 +01:00
Mark Paluch
a7c25c8524 DATAMONGO-2456 - Prepare next development iteration. 2020-02-12 15:04:21 +01:00
Mark Paluch
087f8f78b5 DATAMONGO-2456 - Release version 3.0 M3 (Neumann). 2020-02-12 14:47:16 +01:00
Mark Paluch
534ce2e5f5 DATAMONGO-2456 - Prepare 3.0 M3 (Neumann). 2020-02-12 14:46:56 +01:00
Mark Paluch
0f4f745d3c DATAMONGO-2456 - Updated changelog. 2020-02-12 14:46:51 +01:00
Mark Paluch
ca802c7ca4 DATAMONGO-2470 - Adapt tests to AssertJ 3.15.0. 2020-02-11 10:57:52 +01:00
Mark Paluch
e9d14f41a5 DATAMONGO-2400 - Polishing.
Adapt to changes in commons. Add functional create method to MongoCustomConversions. Update Javadoc and reference documentation. Truncate precision for Java 11 build compatibility in tests.

Original pull request: #810.
2020-02-07 14:16:53 +01:00
Christoph Strobl
3b6880edfd DATAMONGO-2400 - Consider java.time.Instant a store supported native type and add configuration options for other java.time types.
We now use the MongoDB Java driver InstantCodec instead of a dedicated converter. Other java.time types like LocalDate use a different zone offset when writing values which can lead to unexpected behavior. Therefore we added configuration options to MongoCustomConversions that allow to tell the conversion sub system which approach to use when writing those kind of types.

Original pull request: #810.
2020-02-07 12:32:58 +01:00
Mark Paluch
0b77906a83 DATAMONGO-2461 - Polishing.
Extend Javadoc. Reformat code. Reduce log level to info. Refactor resource disposal to use Store.CloseableResource.

Original pull request: #831.
2020-02-05 10:35:58 +01:00
Christoph Strobl
993018feb1 DATAMONGO-2461 - Efficient resource usage and ci related improvments.
- Give the server a little time to think on ci system.
- Reuse and Close MongoClients in tests.
- Use WriteConcern majority in setup.
- Use longer transaction timeout on server
- Use junit-pioneer to repeatable tests known to fail due to network errors.

Original pull request: #831.
2020-02-05 10:35:51 +01:00
Mark Paluch
dd15bbc5c1 DATAMONGO-2079 - Reduce visibility of MappingMongoConverter.getValueInternal.
Do not expose a method that is used internally.

Original Pull Request: #832
2020-02-04 14:21:46 +01:00
Mark Paluch
f6c62d6e2f DATAMONGO-2079 - MappingMongoConverter no longer implements ValueResolver.
MappingMongoConverter no longer implements a package-private interface so that converter instances can be proxied.

Original Pull Request: #832
2020-02-04 14:21:19 +01:00
Christoph Strobl
632c499cf1 DATAMONGO-2417 - Update Copyright headers of Kotlin extensions and test.
Original Pull Request: #809
2020-02-04 08:55:12 +01:00
Mark Paluch
2c9956723e DATAMONGO-2417 - Typesafe Kotlin Extension for distinct queries.
We now provide extensions for imperative and reactive distinct queries accepting Kotlin's KProperty and KProperty1 to express type-safe queries:

mongo.query<Customer>().distinct(Customer::name)

mongo.distinct(Customer::name)

Original Pull Request: #809
2020-02-04 08:54:37 +01:00
Mark Paluch
d0c2c820d7 DATAMONGO-2464 - Polishing.
Apply fix also to reactive MongoDB repository documentation.

Original pull request: #816.
2020-02-03 11:34:00 +01:00
LiangYong
f69ddb6c61 DATAMONGO-2464 - Fix code examples in reference documentation.
fixed repository miss "{" issue.

Original pull request: #816.
2020-02-03 11:34:00 +01:00
Mark Paluch
073668b1d1 DATAMONGO-2460 - Polishing.
Reformat code. Use diamond syntax.

Original pull request: #830.
2020-02-03 11:25:25 +01:00
Christoph Strobl
291d84591c DATAMONGO-2460 - Fix target type computation for complex id properties with @Field annotation.
We now set the target type to org.bson.Document for id properties annotated with @Field having the implicit target type derived from the annotation. Along the lines we fixed warn message when an id property with explicit (unsupported) field name is detected.

Original pull request: #830.
2020-02-03 11:25:11 +01:00
Mark Paluch
46806a5606 DATAMONGO-2449 - Polishing.
Reformat code. Tweak Javadoc.

Original pull request: #827.
2020-02-03 11:02:50 +01:00
Christoph Strobl
85519eb84d DATAMONGO-2449 - Evaluate allowDiskUse added to Meta annotation when executing derived Aggregation.
@Meta(allowDiskUse...) allows to set the according aggregation option when executing a String based annotation via a repository definition.

Original pull request: #827.
2020-02-03 11:02:32 +01:00
Mark Paluch
f8ee9648da DATAMONGO-2365 - Polishing.
Reformat code. Fix method name and generics. Whitespaces.

Original pull request: #828.
2020-01-29 13:40:42 +01:00
Christoph Strobl
c7f9274480 DATAMONGO-2365 - Extract common functionality to centralized component.
Share common code paths between reactive and imperative implementation.

Original pull request: #828.
2020-01-29 13:40:39 +01:00
Christoph Strobl
0bc0fff24e DATAMONGO-2365 - Pass on index name to query hint.
Original pull request: #828.
2020-01-29 13:40:28 +01:00
Mark Paluch
c21b35973d DATAMONGO-2462 - Move off deprecated EntityInstantiators.
We now use the newly introduced EntityInstantiator at o.s.d.mapping.model and moved off the deprecated one in o.s.d.convert.
2020-01-29 10:36:45 +01:00
Mark Paluch
44017485fc DATAMONGO-1997 - Polishing.
Tweak documentation. Reformat code. Remove commented code.

Original pull request: #826.
2020-01-29 10:26:25 +01:00
Christoph Strobl
c56a13ad00 DATAMONGO-1997 - Add support to return the single deleted item for a deleteBy query method.
Added support for:

@Nullable
Person deleteSingleByLastname(String lastname);

Optional<Person> deleteByBirthdate(Date birthdate);

Mono<Person> deleteSinglePersonByLastname(String lastname);

Original pull request: #826.
2020-01-29 10:26:19 +01:00
Mark Paluch
0a2ea88f3c DATAMONGO-2406 - Polishing.
Add optimization for Mono.

Original pull request: #825.
2020-01-29 09:57:42 +01:00
Christoph Strobl
80da9e21ed DATAMONGO-2406 - Derived reactive deleteBy query execution should allow Mono<Void> result.
Mono<Void> is now a supported return type of derived reactive deleteBy queries like:

    Mono<Void> deleteByLastname(String lastname);

Original pull request: #825.
2020-01-29 09:57:34 +01:00
Mark Paluch
708466b323 DATAMONGO-2459 - Polishing.
Slightly tweak wording.

Original pull request: #829
2020-01-29 09:52:38 +01:00
Christoph Strobl
2905315452 DATAMONGO-2459 - Add sample for passing on limit and offset using reactive repositories.
Original pull request: #829.
2020-01-29 09:46:20 +01:00
Christoph Strobl
ecc9f3fd60 DATAMONGO-2457 - Fix id type explanation in repository documentation.
Original pull request: #829.
2020-01-29 09:46:15 +01:00
Mark Paluch
c83929c2a3 DATAMONGO-2427 - Simplify docker setup.
Original pull request: #823.
2020-01-27 11:44:02 +01:00
Mark Paluch
9abf098bdb DATAMONGO-2427 - Polishing.
Guard tests.

Original pull request: #823.
2020-01-27 11:43:52 +01:00
Mark Paluch
f688cca400 DATAMONGO-2427 - Switch to MongoDB Driver 4.0.0-beta1.
Enable disabled tests. Adapt to ReactiveGridFS changes.

Use WriteConcern.MAJORITY in tests.

Original pull request: #823.
2020-01-27 11:43:52 +01:00
Christoph Strobl
f09c622b2f DATAMONGO-2427 - Update GridFS API to use MongoDB native ByteBuffer Publisher API and introduce UUID format configuration options.
Move from AsyncInputStream handling to Publisher for GridFS.
UUID types require additional configuration setup to prevent errors while processing legacy (type 3) binary types. We still use type 3 as default but allow codec configuration for type 4 via Java and XML configuration.
Updated migration guide.

Original pull request: #823.
2020-01-27 11:43:52 +01:00
Mark Paluch
6049541d0a DATAMONGO-2427 - Polishing.
Replace leftovers to Mongo 2.x API with Document and MongoDatabase references and tweak Javadoc. Reorder field declarations to class header. Reflect 3.0 versions in schema configuration. Add TODO markers to disabled tests.
Reflect changes in documentation.

Enable disabled test.

Original pull request: #823.
2020-01-27 11:43:52 +01:00
Mark Paluch
2a3f862703 DATAMONGO-2427 - Rename MongoDbFactory to MongoDatabaseFactory.
Rename to follow MongoDB's naming scheme. Re-introduce deprecated MongoDbFactory to aid migration.

Original pull request: #823.
2020-01-27 11:43:51 +01:00
Christoph Strobl
8b97e932a2 DATAMONGO-2427 - Upgrade to MongoDB 4.0 Driver.
This change switches to the MongoDB 4.0 driver and introduces configuration options for com.mongodb.client.MongoClient.
The XML namespace changed from client-options to client-settings and removed already deprecated elements and attributes.

Imports are switched from single artifact uber jar to split imports for driver-core, -sync and -reactivestreams.
Deprecations have been removed.

Original pull request: #823.
2020-01-27 11:43:51 +01:00
Mark Paluch
5f29bee6c9 DATAMONGO-2419 - Enable JDK 11+ builds. 2020-01-22 21:19:55 -06:00
Mark Paluch
5b8037a0ad DATAMONGO-2454 - After release cleanups. 2020-01-17 09:47:50 +01:00
Mark Paluch
1a19e140ee DATAMONGO-2454 - Prepare next development iteration. 2020-01-17 09:47:49 +01:00
Mark Paluch
83307c424f DATAMONGO-2454 - Release version 3.0 M2 (Neumann). 2020-01-17 09:39:03 +01:00
Mark Paluch
8394523645 DATAMONGO-2454 - Prepare 3.0 M2 (Neumann). 2020-01-17 09:38:43 +01:00
Mark Paluch
62be436569 DATAMONGO-2454 - Updated changelog. 2020-01-17 09:38:37 +01:00
Mark Paluch
44e6f5fa3f DATAMONGO-2383 - After release cleanups. 2020-01-16 16:11:55 +01:00
Mark Paluch
f2fb05662f DATAMONGO-2383 - Prepare next development iteration. 2020-01-16 16:11:54 +01:00
Mark Paluch
a1fbe31551 DATAMONGO-2383 - Release version 3.0 M1 (Neumann). 2020-01-16 16:05:23 +01:00
Mark Paluch
fca1a79f81 DATAMONGO-2383 - Prepare 3.0 M1 (Neumann). 2020-01-16 16:05:03 +01:00
Mark Paluch
cbf87e6e49 DATAMONGO-2383 - Updated changelog. 2020-01-16 16:04:59 +01:00
Mark Paluch
af133c26d0 DATAMONGO-2432 - Updated changelog. 2020-01-15 12:51:13 +01:00
Christoph Strobl
ab5b1f0140 DATAMONGO-2451 - Fix value conversion for id properties used in sort expression.
Previously we falsely converted the sort value (1/-1) into the id types target value when a Field annotation had been present.

Original pull request: #822.
2020-01-15 11:51:42 +01:00
Mark Paluch
3a5876537b DATAMONGO-2431 - Updated changelog. 2020-01-15 10:36:36 +01:00
Mark Paluch
48f51d0fb0 DATAMONGO-2450 - Polishing.
Replace stream with for-loop.

Original pull request: #820.
2020-01-15 10:15:14 +01:00
Christoph Strobl
fb499f8c69 DATAMONGO-2450 - Apply array filters to bulk write.
Original pull request: #820.
2020-01-15 10:15:06 +01:00
Mark Paluch
bcc2c94e03 DATAMONGO-2440 - Polishing.
Replace SpringJUnit4ClassRunner with SpringRunner.

Original pull request: #821.
2020-01-15 09:30:12 +01:00
Mark Paluch
284f547e99 DATAMONGO-2437 - Polishing.
Mention changes in Aggregation _id handling in what's new. Reformat code.

Original pull request: #821.
2020-01-15 09:30:09 +01:00
Christoph Strobl
d824f3b8b2 DATAMONGO-2437 - Fix complex id handling when reading aggregation results.
Removed Unwrapping complex id values.
Template.aggregate now behaves like aggregateStream or its reactive counterpart.

Original pull request: #821.
2020-01-15 09:30:07 +01:00
Christoph Strobl
7b1a96f4a9 DATAMONGO-2448 - Bump version to 3.0 SNAPSHOT.
In preparation for the upcoming breaking changes when switching to the MongoDB Java Driver 4.0 and the breaking changes required for that update (expected for Milestone 2), we eagerly bump the version number to 3.0.

Original pull request: #819.
2020-01-13 14:29:09 +01:00
Christoph Strobl
4f75fec5c5 DATAMONGO-2447 - Upgrade MongoDB Drivers to 3.12.0 (sync) and 1.13.0 (reactive). 2020-01-10 11:22:49 +01:00
Mark Paluch
61bd56dd74 DATAMONGO-2442 - Polishing.
Reduce visibility of test methods for JUnit 5 tests.

Original pull request: #818.
2020-01-08 15:12:47 +01:00
Christoph Strobl
b4222c5646 DATAMONGO-2442 - Polishing.
Transition touched test classes to JUnit Jupiter.

Original pull request: #818.
2020-01-08 15:12:44 +01:00
Christoph Strobl
4a45928aee DATAMONGO-2442 - Fix thenValueOf in $cond builder.
We now create a field reference when calling the builder instead of using the value as is.

Original pull request: #818.
2020-01-08 15:12:23 +01:00
Mark Paluch
e2200eccf7 DATAMONGO-2440 - Polishing.
Iterate over List instead of using the Stream API.

Reduce visibility of JUnit 5 test methods. Consolidate assertions.

Original pull request: #817.
2020-01-08 15:01:57 +01:00
Christoph Strobl
96c4901e7f DATAMONGO-2440 - Fix field target type conversion for collection values.
We now preserve the collection nature of the source type when applying custom target type conversions. Prior to this change collection values had been changed to single element causing query errors in MongoDB when using $in queries.

Original pull request: #817.
2020-01-08 15:01:44 +01:00
Christoph Strobl
1393f23f3b DATAMONGO-2423 - Polishing.
Update nullability annotations and reduce visibility in tests.

Original pull request: #815.
2020-01-08 13:24:10 +01:00
Christoph Strobl
9bbe1f2a26 DATAMONGO-2423 - Nullability refinements for Update.
Ease non null restrictions for operators that may use null values like $set.

Original pull request: #815.
2020-01-08 13:23:53 +01:00
Mark Paluch
eacfe2b8f7 DATAMONGO-2444 - Update copyright years to 2020. 2020-01-07 08:59:27 +01:00
Jens Schauder
674f0cca2b DATAMONGO-2422 - Updated changelog. 2019-12-04 14:32:45 +01:00
Jens Schauder
da7b51a51e DATAMONGO-2421 - Updated changelog. 2019-12-04 12:09:46 +01:00
Mark Paluch
a1b5175299 DATAMONGO-2430 - Upgrade to mongo-java-driver 3.11.2. 2019-12-04 11:43:07 +01:00
Mark Paluch
56fff286aa DATAMONGO-2418 - Polishing.
Reformat code.

Original pull request: #814.
2019-12-04 10:32:04 +01:00
Christoph Strobl
60112b4d14 DATAMONGO-2418 - Obtain EvaluationContextExtensions lazily when parsing Bson queries.
An eager evaluation of the context extension can lead to errors when e.g. the security context was not present.

Original pull request: #814.
2019-12-04 10:32:04 +01:00
Mark Paluch
277b7a1c7c DATAMONGO-2410 - Polishing.
Simplify cast. Extend test with DBObject interface.

Original pull request: #813.
2019-12-04 08:56:43 +01:00
Christoph Strobl
c5b892f03b DATAMONGO-2410 - Fix Document to BasicDBObject conversion.
Original pull request: #813.
2019-12-04 08:56:35 +01:00
Mark Paluch
dbf43941be DATAMONGO-765 - Polishing.
Reformat code. Update ticket references.

Original pull request: #806.
2019-11-26 15:21:29 +01:00
Denis Zavedeev
1d98b77f3d DATAMONGO-765 - Support skip and limit parameters in GridFsTemplate and ReactiveGridFsTemplate.
Leverage `skip` and `limit` methods exposed in `GridFSFindIterable` to support limiting and skipping results.
In particular these changes allow the `find(Query)` method to correctly consider parameters of a page request.

Original pull request: #806.
2019-11-26 15:21:04 +01:00
Mark Paluch
cd4e4065ff DATAMONGO-2370 - Polishing.
Align since version to 2.3 until we have an indication for a major version bump. Tweak docs.

Original pull request: #803.
2019-11-20 10:12:34 +01:00
Christoph Strobl
9f4872de4f DATAMONGO-2370 - Polishing.
Use JUnit Jupiter api for tests of touched classes and fix parsing errors in disabled ones.

Original pull request: #803.
2019-11-20 10:12:30 +01:00
Christoph Strobl
7abf69e575 DATAMONGO-2370 - Add support for $round aggregation operator.
Original pull request: #803.
2019-11-20 10:12:27 +01:00
Mark Paluch
588ed2b0e2 DATAMONGO-2402 - Updated changelog. 2019-11-18 12:43:26 +01:00
Mark Paluch
8a228f22cd DATAMONGO-2401 - Updated changelog. 2019-11-18 12:16:26 +01:00
Christoph Strobl
d652b2bdb4 DATAMONGO-2414 - Introduce MongoServerCondition to replace JUnit 4 TestRules.
MongoServerCondition replaces the JUnit 4 TestRules (MongoVersionRule & ReplicaSet) with a JUnit Jupiter ExecutionCondition.

Original Pull Request: #807
2019-11-14 11:10:20 +01:00
Mark Paluch
f7e527e45c DATAMONGO-2414 - Polishing.
Use longer timeout to cater for slower CI environments.

Original Pull Request: #807
2019-11-14 11:09:58 +01:00
Mark Paluch
aede7c9cad DATAMONGO-2414 - Guard drain loop in AsyncInputStreamHandler with state switch.
We now use a non-blocking state switch to determine whether to invoke drainLoop(…) from Subscriber completion.

Previously, we relied on same thread identification assuming if the subscription thread and the completion thread were the same, that we're already running inside the drain loop.
It turns out that a I/O thread could also run in event-loop mode where subscription and completion happens on the same thread but in between there's some processing and so the the call to completion is a delayed signal and not being called on the same stack as drainLoop(…).
The same-thread assumption was in place to avoid StackOverflow caused by infinite recursions.

We now use a state lock to enter the drain loop. Any concurrent attempts to re-enter the drain loop in Subscriber completion is now prevented to make sure that we continue draining while not causing stack recursions.

Original Pull Request: #807
2019-11-14 11:09:19 +01:00
Mark Paluch
1a5de2e1db DATAMONGO-2331 - Polishing.
Remove deprecated methods accepting Update in favor of methods accepting UpdateDefinition in Template APIs.
Hide AggregationUpdate constructor.

Tweak Javadoc and reference documentation.

Original pull request: #789.
2019-11-13 09:51:46 +01:00
Christoph Strobl
cc07a1bbb4 DATAMONGO-2331 - Guard test execution.
Original pull request: #789.
2019-11-13 09:51:39 +01:00
Christoph Strobl
32cbae0e5f DATAMONGO-2331 - Add support for Update with an aggregation pipeline.
Now the update methods exposed by (Reactive)MongoOperations also accept an Aggregation Pipeline via AggregationUpdate.

The update can consist of the following stages:

* AggregationUpdate.set(...).toValue(...) -> $set : { ... }
* AggregationUpdate.unset(...) -> $unset : [ ... ]
* AggregationUpdate.replaceWith(...) -> $replaceWith : { ... }

AggregationUpdate update = Aggregation.newUpdate()
    .set("average").toValue(ArithmeticOperators.valueOf("tests").avg())
    .set("grade").toValue(ConditionalOperators.switchCases(
        when(valueOf("average").greaterThanEqualToValue(90)).then("A"),
        when(valueOf("average").greaterThanEqualToValue(80)).then("B"),
        when(valueOf("average").greaterThanEqualToValue(70)).then("C"),
        when(valueOf("average").greaterThanEqualToValue(60)).then("D"))
        .defaultTo("F")
    );

template.update(Student.class)
    .apply(update)
    .all();

Original pull request: #789.
2019-11-13 09:51:22 +01:00
Mark Paluch
9eaf67148d DATAMONGO-2385 - Polishing.
Remove null checks for arguments known to be not-null. Remove Nullable annotations from methods that never return null.

Original pull request: #802.
2019-11-11 14:17:01 +01:00
Christoph Strobl
ff60149166 DATAMONGO-2385 - Remove unnecessary null checks in MongoConverters.
Original pull request: #802.
2019-11-11 14:10:00 +01:00
Mark Paluch
f7a010827d DATAMONGO-2409 - Polishing.
Adapt also ExecutableFindOperation.DistinctWithProjection.asType() to return the appropriate TerminatingDistinct.

Original pull request: #805.
2019-11-11 10:22:27 +01:00
Christoph Strobl
1e8c4cec5b DATAMONGO-2409 - Fix return type of Kotlin extension function for ReactiveFindOperation.DistinctWithProjection.asType().
Original pull request: #805.
2019-11-11 10:22:22 +01:00
Mark Paluch
0e0b45597b DATAMONGO-2403 - Polishing.
Use handle(…) to skip values instead of flatMap(…) to reduce overhead.

Original pull request: #804.
2019-11-08 13:51:41 +01:00
Christoph Strobl
b014fe4c7c DATAMONGO-2403 - Fix aggregation simple type result retrieval from empty document.
Projections used within an aggregation pipeline can result in empty documents emitted by the driver. We now guarded those cases and skip those documents within a Flux or simply return an empty Mono depending on the methods signature.

Original pull request: #804.
2019-11-08 13:47:56 +01:00
Christoph Strobl
ead7679f21 DATAMONGO-2382 - Updated changelog. 2019-11-04 15:39:54 +01:00
Christoph Strobl
18cf94dc34 DATAMONGO-2381 - Updated changelog. 2019-11-04 10:34:50 +01:00
Christoph Strobl
30d99445e2 DATAMONGO-2393 - Remove capturing lambdas and extract methods.
Original Pull Request: #799
2019-10-31 12:50:33 +01:00
Mark Paluch
839aecee84 DATAMONGO-2393 - Support configurable chunk size.
We now allow consuming GridFS files using a configurable chunk size. The default chunk size is now 256kb.

Original Pull Request: #799
2019-10-31 12:50:09 +01:00
Mark Paluch
c6592b01b0 DATAMONGO-2393 - Polishing.
Extract read requests into inner class.

Original Pull Request: #799
2019-10-31 12:49:45 +01:00
Mark Paluch
48176a833c DATAMONGO-2393 - Fix BufferOverflow in GridFS upload.
AsyncInputStreamAdapter now properly splits and buffers incoming DataBuffers according the read requests of AsyncInputStream.read(…) calls.
Previously, the adapter used the input buffer size to be used as the output buffer size. A larger DataBuffer than the transfer buffer handed in through read(…) caused a BufferOverflow.

Original Pull Request: #799
2019-10-31 12:49:18 +01:00
Mark Paluch
0facdcfa98 DATAMONGO-2393 - Use drain loop for same-thread processing in GridFS download stream.
We now rely on an outer drain-loop when GridFS reads complete on the same thread instead of using recursive subscriptions to avoid StackOverflow. Previously, we recursively invoked subscriptions that lead to an increased stack size.

Original Pull Request: #799
2019-10-31 12:48:55 +01:00
Christoph Strobl
837a9885f2 DATAMONGO-2399 - Upgrade to MongoDB Java Driver 3.11.1 2019-10-30 10:47:47 +01:00
Mark Paluch
6cc5bc627a DATAMONGO-2388 - Polishing.
Use StringJoiner to create comma-delimited String. Add nullability annotations.

Original pull request: #797.
2019-10-28 10:58:17 +01:00
Christoph Strobl
84f7f433f7 DATAMONGO-2388 - Fix CodecConfigurationException when reading index info that contains DbRef.
Provide the default CodecRegistry when converting partial index data to its String representation used in IndexInfo.

Original pull request: #797.
2019-10-28 10:47:22 +01:00
Mark Paluch
7df9e932f7 DATAMONGO-2390 - Polishing.
Reformat code.

Original pull request: #800.
2019-10-28 10:10:26 +01:00
Christoph Strobl
5308e6c37f DATAMONGO-2390 - Polishing.
Switch touched test files to JUnit Jupiter.

Original pull request: #800.
2019-10-28 10:07:16 +01:00
Christoph Strobl
bc1c6c9a64 DATAMONGO-2390 - Add support for maxTimeMS to AggregationOptions.
maxTimeMs defines the time limit for the aggregation operations. If not specified or set to zero, operations will not time out.

Original pull request: #800.
2019-10-28 10:07:08 +01:00
Mark Paluch
62006129ca DATAMONGO-2394 - Polishing.
Reformat code.

Original pull request: #798.
2019-10-28 09:31:53 +01:00
Christoph Strobl
5c2370399f DATAMONGO-2394 - Polishing.
Move tests to JUnit Jupiter.

Original pull request: #798.
2019-10-28 09:31:52 +01:00
Christoph Strobl
3bffe402c0 DATAMONGO-2394 - Fix test issues related to JUnit5 upgrade.
Execution time and test order changed by using JUnit5. This commit fixes some of the issues related to index creation where actually not needed.

Original pull request: #798.
2019-10-28 09:31:50 +01:00
Christoph Strobl
6959c56df6 DATAMONGO-2394 - Fix distance conversion for derived finder using near along with GeoJSON.
GeoJson requries the distance to be in meters instead of radians, so we now make sure to convert it correctly

Original pull request: #798.
2019-10-28 09:31:43 +01:00
Mark Paluch
b5bc4320aa DATAMONGO-2059 - Polishing.
Move query rewriting into CountQuery. Consider existing $and items during query rewrite.

Original pull request: #604.
2019-10-25 09:11:35 +02:00
Christoph Strobl
909c51d00a DATAMONGO-2059 - Replace usage of deprecated collection.count() with collection.countDocuments().
This commit switches from simple collection.count(), operating on potentially false collection statistic,  to countDocuments() using an aggregation for accurate results.
The transition required query modifications at some points because $match does not support $near and $nearSphere but require $geoWithin along with $center or $centerSphere which does not support $minDistance (see https://jira.mongodb.org/browse/SERVER-37043).
$geoWithin further more does not sort results by distance, but this fact can be ignored when just counting matches.

Examples:

{ location : { $near : [-73.99171, 40.738868], $maxDistance : 1.1 } }
{ location : { $geoWithin : { $center: [ [-73.99171, 40.738868], 1.1] } } }

{ location : { $near : [-73.99171, 40.738868], $minDistance : 0.1, $maxDistance : 1.1 } }
{$and :[ { $nor :[ { location :{ $geoWithin :{ $center :[ [-73.99171, 40.738868 ], 0.01] } } } ]}, { location :{ $geoWithin :{ $center :[ [-73.99171, 40.738868 ], 1.1] } } } ] }

Original pull request: #604.
2019-10-25 09:01:12 +02:00
Mark Paluch
4a04e82e86 DATAMONGO-2392 - Polishing.
Add author tags. Move integration tests to existing test class.
Apply more appropriate in existing tests assertions. Use diamond syntax.

Original pull request: #796.
2019-10-16 13:55:00 +02:00
Mark Paluch
1370653c93 DATAMONGO-2392 - Consistently use GridFS file Id instead of ObjectId.
We now consistently use GridFSFile.getId() to allow custom Id usage instead of enforcing the Id to be an ObjectId. Using the native Id allows interaction with files that use a custom Id type.

Original pull request: #796.
2019-10-16 13:54:57 +02:00
Nick Stolwijk
ebfcfb3834 DATAMONGO-2392 - Fix handling in ReactiveGridFsTemplate of GridFS files with custom id type.
Original pull request: #796.
2019-10-16 13:54:29 +02:00
Mark Paluch
77aafc597b DATAMONGO-2334 - After release cleanups. 2019-09-30 16:17:29 +02:00
Mark Paluch
a4503812bd DATAMONGO-2334 - Prepare next development iteration. 2019-09-30 16:17:28 +02:00
1038 changed files with 32939 additions and 13808 deletions

View File

@@ -1,38 +0,0 @@
language: java
jdk:
- oraclejdk8
before_install:
- mkdir -p downloads
- mkdir -p var/db var/log
- if [[ ! -d downloads/mongodb-linux-x86_64-ubuntu1604-${MONGO_VERSION} ]] ; then cd downloads && wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-${MONGO_VERSION}.tgz && tar xzf mongodb-linux-x86_64-ubuntu1604-${MONGO_VERSION}.tgz && cd ..; fi
- downloads/mongodb-linux-x86_64-ubuntu1604-${MONGO_VERSION}/bin/mongod --version
- downloads/mongodb-linux-x86_64-ubuntu1604-${MONGO_VERSION}/bin/mongod --dbpath var/db --replSet rs0 --fork --logpath var/log/mongod.log
- sleep 10
- |-
downloads/mongodb-linux-x86_64-ubuntu1604-${MONGO_VERSION}/bin/mongo --eval "rs.initiate({_id: 'rs0', members:[{_id: 0, host: '127.0.0.1:27017'}]});"
sleep 15
env:
matrix:
- MONGO_VERSION=4.1.10
- MONGO_VERSION=4.0.4
- MONGO_VERSION=3.6.12
- MONGO_VERSION=3.4.20
global:
- PROFILE=ci
addons:
apt:
packages:
- oracle-java8-installer
sudo: false
cache:
directories:
- $HOME/.m2
- downloads
script: "mvn clean dependency:list test -P${PROFILE} -Dsort"

View File

@@ -1,27 +0,0 @@
= Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses,
without explicit permission
* Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at spring-code-of-conduct@pivotal.io.
All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident.
This Code of Conduct is adapted from the https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/].

216
Jenkinsfile vendored
View File

@@ -3,7 +3,7 @@ pipeline {
triggers {
pollSCM 'H/10 * * * *'
upstream(upstreamProjects: "spring-data-commons/master", threshold: hudson.model.Result.SUCCESS)
upstream(upstreamProjects: "spring-data-commons/2.4.x", threshold: hudson.model.Result.SUCCESS)
}
options {
@@ -30,111 +30,148 @@ pipeline {
}
}
}
stage('Publish JDK 8 + MongoDB 4.1') {
stage('Publish JDK 8 + MongoDB 4.2') {
when {
changeset "ci/openjdk8-mongodb-4.1/**"
changeset "ci/openjdk8-mongodb-4.2/**"
}
agent { label 'data' }
options { timeout(time: 30, unit: 'MINUTES') }
steps {
script {
def image = docker.build("springci/spring-data-openjdk8-with-mongodb-4.1", "ci/openjdk8-mongodb-4.1/")
def image = docker.build("springci/spring-data-openjdk8-with-mongodb-4.2.0", "ci/openjdk8-mongodb-4.2/")
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
image.push()
}
}
}
}
stage('Publish JDK 8 + MongoDB 4.2') {
when {
changeset "ci/openjdk8-mongodb-4.2/**"
}
agent { label 'data' }
options { timeout(time: 30, unit: 'MINUTES') }
stage('Publish JDK 15 + MongoDB 4.2') {
when {
changeset "ci/openjdk15-mongodb-4.2/**"
}
agent { label 'data' }
options { timeout(time: 30, unit: 'MINUTES') }
steps {
script {
def image = docker.build("springci/spring-data-openjdk8-with-mongodb-4.2", "ci/openjdk8-mongodb-4.2/")
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
image.push()
}
}
}
}
steps {
script {
def image = docker.build("springci/spring-data-openjdk15-with-mongodb-4.2.0", "ci/openjdk15-mongodb-4.2/")
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
image.push()
}
}
}
}
}
}
stage("test: baseline") {
stage("test: baseline (jdk8)") {
when {
anyOf {
branch 'master'
branch '3.1.x'
not { triggeredBy 'UpstreamCause' }
}
}
agent {
docker {
image 'springci/spring-data-openjdk8-with-mongodb-4.2:latest'
label 'data'
args '-v $HOME:/tmp/jenkins-home'
}
label 'data'
}
options { timeout(time: 30, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
}
steps {
sh 'rm -rf ?'
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B'
script {
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
docker.image('springci/spring-data-openjdk8-with-mongodb-4.2.0:latest').inside('-v $HOME:/tmp/jenkins-home') {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
}
}
}
stage("Test other configurations") {
when {
anyOf {
branch 'master'
allOf {
branch '3.1.x'
not { triggeredBy 'UpstreamCause' }
}
}
parallel {
stage("test: mongodb 4.0") {
stage("test: mongodb 4.0 (jdk8)") {
agent {
docker {
image 'springci/spring-data-openjdk8-with-mongodb-4.0:latest'
label 'data'
args '-v $HOME:/tmp/jenkins-home'
}
label 'data'
}
options { timeout(time: 30, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
}
steps {
sh 'rm -rf ?'
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B'
script {
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
docker.image('springci/spring-data-openjdk8-with-mongodb-4.0:latest').inside('-v $HOME:/tmp/jenkins-home') {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
}
}
}
stage("test: mongodb 4.1") {
stage("test: mongodb 4.2 (jdk8)") {
agent {
docker {
image 'springci/spring-data-openjdk8-with-mongodb-4.1:latest'
label 'data'
args '-v $HOME:/tmp/jenkins-home'
}
label 'data'
}
options { timeout(time: 30, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
}
steps {
sh 'rm -rf ?'
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B'
script {
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
docker.image('springci/spring-data-openjdk8-with-mongodb-4.2.0:latest').inside('-v $HOME:/tmp/jenkins-home') {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
}
}
}
stage("test: baseline (jdk15)") {
agent {
label 'data'
}
options { timeout(time: 30, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
}
steps {
script {
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
docker.image('springci/spring-data-openjdk15-with-mongodb-4.2.0:latest').inside('-v $HOME:/tmp/jenkins-home') {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pjava11 clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
}
}
}
}
@@ -143,16 +180,12 @@ pipeline {
stage('Release to artifactory') {
when {
anyOf {
branch 'master'
branch '3.1.x'
not { triggeredBy 'UpstreamCause' }
}
}
agent {
docker {
image 'adoptopenjdk/openjdk8:latest'
label 'data'
args '-v $HOME:/tmp/jenkins-home'
}
label 'data'
}
options { timeout(time: 20, unit: 'MINUTES') }
@@ -161,28 +194,29 @@ pipeline {
}
steps {
sh 'rm -rf ?'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pci,artifactory ' +
'-Dartifactory.server=https://repo.spring.io ' +
"-Dartifactory.username=${ARTIFACTORY_USR} " +
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
"-Dartifactory.staging-repository=libs-snapshot-local " +
"-Dartifactory.build-name=spring-data-mongodb " +
"-Dartifactory.build-number=${BUILD_NUMBER} " +
'-Dmaven.test.skip=true clean deploy -U -B'
script {
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
docker.image('adoptopenjdk/openjdk8:latest').inside('-v $HOME:/tmp/jenkins-home') {
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory ' +
'-Dartifactory.server=https://repo.spring.io ' +
"-Dartifactory.username=${ARTIFACTORY_USR} " +
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
"-Dartifactory.staging-repository=libs-snapshot-local " +
"-Dartifactory.build-name=spring-data-mongodb " +
"-Dartifactory.build-number=${BUILD_NUMBER} " +
'-Dmaven.test.skip=true clean deploy -U -B'
}
}
}
}
}
stage('Publish documentation') {
when {
branch 'master'
branch '3.1.x'
}
agent {
docker {
image 'adoptopenjdk/openjdk8:latest'
label 'data'
args '-v $HOME:/tmp/jenkins-home'
}
label 'data'
}
options { timeout(time: 20, unit: 'MINUTES') }
@@ -191,12 +225,18 @@ pipeline {
}
steps {
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pci,distribute ' +
'-Dartifactory.server=https://repo.spring.io ' +
"-Dartifactory.username=${ARTIFACTORY_USR} " +
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
"-Dartifactory.distribution-repository=temp-private-local " +
'-Dmaven.test.skip=true clean deploy -U -B'
script {
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
docker.image('adoptopenjdk/openjdk8:latest').inside('-v $HOME:/tmp/jenkins-home') {
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,distribute ' +
'-Dartifactory.server=https://repo.spring.io ' +
"-Dartifactory.username=${ARTIFACTORY_USR} " +
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
"-Dartifactory.distribution-repository=temp-private-local " +
'-Dmaven.test.skip=true clean deploy -U -B'
}
}
}
}
}
}

202
LICENSE.txt Normal file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -10,7 +10,7 @@ Key functional areas of Spring Data MongoDB are a POJO centric model for interac
== Code of Conduct
This project is governed by the link:CODE_OF_CONDUCT.adoc[Spring Code of Conduct]. By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
This project is governed by the https://github.com/spring-projects/.github/blob/e3cc2ff230d8f1dca06535aa6b5a4a23815861d4/CODE_OF_CONDUCT.md[Spring Code of Conduct]. By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
== Getting Started
@@ -50,12 +50,7 @@ public class MyService {
@Configuration
@EnableMongoRepositories
class ApplicationConfig extends AbstractMongoConfiguration {
@Override
public MongoClient mongoClient() {
return new MongoClient();
}
class ApplicationConfig extends AbstractMongoClientConfiguration {
@Override
protected String getDatabaseName() {
@@ -94,6 +89,143 @@ If you'd rather like the latest snapshots of the upcoming major version, use our
</repository>
----
== Upgrading from 2.x
The 4.0 MongoDB Java Driver does no longer support certain features that have already been deprecated in one of the last minor versions.
Some of the changes affect the initial setup configuration as well as compile/runtime features. We summarized the most typical changes one might encounter.
=== XML Namespace
.Changed XML Namespace Elements and Attributes:
|===
Element / Attribute | 2.x | 3.x
| `<mongo:mongo-client />`
| Used to create a `com.mongodb.MongoClient`
| Now exposes a `com.mongodb.client.MongoClient`
| `<mongo:mongo-client replica-set="..." />`
| Was a comma delimited list of replica set members (host/port)
| Now defines the replica set name. +
Use `<mongo:client-settings cluster-hosts="..." />` instead
| `<mongo:db-factory writeConcern="..." />`
| NONE, NORMAL, SAFE, FSYNC_SAFE, REPLICAS_SAFE, MAJORITY
| W1, W2, W3, UNAKNOWLEDGED, AKNOWLEDGED, JOURNALED, MAJORITY
|===
.Removed XML Namespace Elements and Attributes:
|===
Element / Attribute | Replacement in 3.x | Comment
| `<mongo:db-factory mongo-ref="..." />`
| `<mongo:db-factory mongo-client-ref="..." />`
| Referencing a `com.mongodb.client.MongoClient`.
| `<mongo:mongo-client credentials="..." />`
| `<mongo:mongo-client credential="..." />`
| Single authentication data instead of list.
| `<mongo:client-options />`
| `<mongo:client-settings />`
| See `com.mongodb.MongoClientSettings` for details.
|===
.New XML Namespace Elements and Attributes:
|===
Element | Comment
| `<mongo:db-factory mongo-client-ref="..." />`
| Replacement for `<mongo:db-factory mongo-ref="..." />`
| `<mongo:db-factory connection-string="..." />`
| Replacement for `uri` and `client-uri`.
| `<mongo:mongo-client connection-string="..." />`
| Replacement for `uri` and `client-uri`.
| `<mongo:client-settings />`
| Namespace element for `com.mongodb.MongoClientSettings`.
|===
=== Java Configuration
.Java API changes
|===
Type | Comment
| `MongoClientFactoryBean`
| Creates `com.mongodb.client.MongoClient` instead of `com.mongodb.MongoClient` +
Uses `MongoClientSettings` instead of `MongoClientOptions`.
| `MongoDataIntegrityViolationException`
| Uses `WriteConcernResult` instead of `WriteResult`.
| `BulkOperationException`
| Uses `MongoBulkWriteException` and `com.mongodb.bulk.BulkWriteError` instead of `BulkWriteException` and `com.mongodb.BulkWriteError`
| `ReactiveMongoClientFactoryBean`
| Uses `com.mongodb.MongoClientSettings` instead of `com.mongodb.async.client.MongoClientSettings`
| `ReactiveMongoClientSettingsFactoryBean`
| Now produces `com.mongodb.MongoClientSettings` instead of `com.mongodb.async.client.MongoClientSettings`
|===
.Removed Java API:
|===
2.x | Replacement in 3.x | Comment
| `MongoClientOptionsFactoryBean`
| `MongoClientSettingsFactoryBean`
| Creating a `com.mongodb.MongoClientSettings`.
| `AbstractMongoConfiguration`
| `AbstractMongoClientConfiguration` +
(Available since 2.1)
| Using `com.mongodb.client.MongoClient`.
| `MongoDbFactory#getLegacyDb()`
| -
| -
| `SimpleMongoDbFactory`
| `SimpleMongoClientDbFactory` +
(Available since 2.1)
|
| `MapReduceOptions#getOutputType()`
| `MapReduceOptions#getMapReduceAction()`
| Returns `MapReduceAction` instead of `MapReduceCommand.OutputType`.
| `Meta\|Query` maxScan & snapshot
|
|
|===
=== Other Changes
==== UUID Types
The MongoDB UUID representation can now be configured with different formats.
This has to be done via `MongoClientSettings` as shown in the snippet below.
.UUID Codec Configuration
====
[source,java]
----
static class Config extends AbstractMongoClientConfiguration {
@Override
public void configureClientSettings(MongoClientSettings.Builder builder) {
builder.uuidRepresentation(UuidRepresentation.STANDARD);
}
// ...
}
----
====
== Getting Help
Having trouble with Spring Data? Wed love to help!
@@ -105,18 +237,17 @@ If you are just starting out with Spring, try one of the https://spring.io/guide
* If you are upgrading, check out the https://docs.spring.io/spring-data/mongodb/docs/current/changelog.txt[changelog] for "`new and noteworthy`" features.
* Ask a question - we monitor https://stackoverflow.com[stackoverflow.com] for questions tagged with https://stackoverflow.com/tags/spring-data[`spring-data-mongodb`].
You can also chat with the community on https://gitter.im/spring-projects/spring-data[Gitter].
* Report bugs with Spring Data MongoDB at https://jira.spring.io/browse/DATAMONGO[jira.spring.io/browse/DATAMONGO].
* Report bugs with Spring Data MongoDB at https://github.com/spring-projects/spring-data-mongodb/issues[github.com/spring-projects/spring-data-mongodb/issues].
== Reporting Issues
Spring Data uses JIRA as issue tracking system to record bugs and feature requests. If you want to raise an issue, please follow the recommendations below:
Spring Data uses Github as issue tracking system to record bugs and feature requests.
If you want to raise an issue, please follow the recommendations below:
* Before you log a bug, please search the
https://jira.spring.io/browse/DATAMONGO[issue tracker] to see if someone has already reported the problem.
* If the issue doesnt already exist, https://jira.spring.io/browse/DATAMONGO[create a new issue].
* Please provide as much information as possible with the issue report, we like to know the version of Spring Data that you are using and JVM version.
* If you need to paste code, or include a stack trace use JIRA `{code}…{code}` escapes before and after your text.
* If possible try to create a test-case or project that replicates the issue. Attach a link to your code or a compressed file containing your code.
* Before you log a bug, please search the https://github.com/spring-projects/spring-data-mongodb/issues[issue tracker] to see if someone has already reported the problem.
* If the issue does not already exist, https://github.com/spring-projects/spring-data-mongodb/issues/new[create a new issue].
* Please provide as much information as possible with the issue report, we like to know the version of Spring Data that you are using, the JVM version, Stacktrace, etc.
* If you need to paste code, or include a stack trace use https://guides.github.com/features/mastering-markdown/[Markdown] code fences +++```+++.
== Building from Source

View File

@@ -0,0 +1,15 @@
FROM adoptopenjdk/openjdk11:latest
ENV TZ=Etc/UTC
ENV DEBIAN_FRONTEND=noninteractive
RUN set -eux; \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv e162f504a20cdf15827f718d4b7c549a058f8b6b ; \
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list; \
echo ${TZ} > /etc/timezone;
RUN apt-get update ; \
apt-get install -y mongodb-org=4.2.0 mongodb-org-server=4.2.0 mongodb-org-shell=4.2.0 mongodb-org-mongos=4.2.0 mongodb-org-tools=4.2.0 ; \
apt-get clean; \
rm -rf /var/lib/apt/lists/*;

View File

@@ -0,0 +1,15 @@
FROM adoptopenjdk/openjdk15:latest
ENV TZ=Etc/UTC
ENV DEBIAN_FRONTEND=noninteractive
RUN set -eux; \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv e162f504a20cdf15827f718d4b7c549a058f8b6b ; \
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list; \
echo ${TZ} > /etc/timezone;
RUN apt-get update ; \
apt-get install -y mongodb-org=4.2.0 mongodb-org-server=4.2.0 mongodb-org-shell=4.2.0 mongodb-org-mongos=4.2.0 mongodb-org-tools=4.2.0 ; \
apt-get clean; \
rm -rf /var/lib/apt/lists/*;

View File

@@ -1,14 +1,15 @@
FROM adoptopenjdk/openjdk8:latest
RUN apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2
ENV TZ=Etc/UTC
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
RUN RUN set -eux; \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4 ; \
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list; \
echo ${TZ} > /etc/timezone;
RUN echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list
RUN apt-get update
RUN apt-get install -y mongodb-org=4.0.9 mongodb-org-server=4.0.9 mongodb-org-shell=4.0.9 mongodb-org-mongos=4.0.9 mongodb-org-tools=4.0.9
RUN apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update ; \
apt-get install -y mongodb-org=4.0.14 mongodb-org-server=4.0.14 mongodb-org-shell=4.0.14 mongodb-org-mongos=4.0.14 mongodb-org-tools=4.0.14 ; \
apt-get clean; \
rm -rf /var/lib/apt/lists/*;

View File

@@ -1,14 +0,0 @@
FROM adoptopenjdk/openjdk8:latest
RUN apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2
RUN apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 4B7C549A058F8B6B
RUN echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.1 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.1.list
RUN apt-get update
RUN apt-get install -y mongodb-org-unstable=4.1.13 mongodb-org-unstable-server=4.1.13 mongodb-org-unstable-shell=4.1.13 mongodb-org-unstable-mongos=4.1.13 mongodb-org-unstable-tools=4.1.13
RUN apt-get clean \
&& rm -rf /var/lib/apt/lists/*

View File

@@ -1,14 +1,15 @@
FROM adoptopenjdk/openjdk8:latest
RUN apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2
ENV TZ=Etc/UTC
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv e162f504a20cdf15827f718d4b7c549a058f8b6b
RUN set -eux; \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv e162f504a20cdf15827f718d4b7c549a058f8b6b ; \
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list; \
echo ${TZ} > /etc/timezone;
RUN echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list
RUN apt-get update
RUN apt-get install -y mongodb-org=4.2.0 mongodb-org-server=4.2.0 mongodb-org-shell=4.2.0 mongodb-org-mongos=4.2.0 mongodb-org-tools=4.2.0
RUN apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update ; \
apt-get install -y mongodb-org=4.2.0 mongodb-org-server=4.2.0 mongodb-org-shell=4.2.0 mongodb-org-mongos=4.2.0 mongodb-org-tools=4.2.0 ; \
apt-get clean; \
rm -rf /var/lib/apt/lists/*;

23
pom.xml
View File

@@ -5,7 +5,7 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.0.RELEASE</version>
<version>3.1.13</version>
<packaging>pom</packaging>
<name>Spring Data MongoDB</name>
@@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>2.2.0.RELEASE</version>
<version>2.4.13</version>
</parent>
<modules>
@@ -26,9 +26,9 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.2.0.RELEASE</springdata.commons>
<mongo>3.11.0</mongo>
<mongo.reactivestreams>1.12.0</mongo.reactivestreams>
<springdata.commons>2.4.13</springdata.commons>
<mongo>4.1.2</mongo>
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
<jmh.version>1.19</jmh.version>
</properties>
@@ -127,7 +127,7 @@
<!-- MongoDB -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<artifactId>mongodb-driver-core</artifactId>
<version>${mongo}</version>
</dependency>
</dependencies>
@@ -137,6 +137,16 @@
<id>spring-libs-release</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>sonatype-libs-snapshot</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
@@ -148,7 +158,6 @@
<id>spring-libs-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
</pluginRepository>
</pluginRepositories>
</project>

29
settings.xml Normal file
View File

@@ -0,0 +1,29 @@
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>spring-plugins-release</id>
<username>${env.ARTIFACTORY_USR}</username>
<password>${env.ARTIFACTORY_PSW}</password>
</server>
<server>
<id>spring-libs-snapshot</id>
<username>${env.ARTIFACTORY_USR}</username>
<password>${env.ARTIFACTORY_PSW}</password>
</server>
<server>
<id>spring-libs-milestone</id>
<username>${env.ARTIFACTORY_USR}</username>
<password>${env.ARTIFACTORY_PSW}</password>
</server>
<server>
<id>spring-libs-release</id>
<username>${env.ARTIFACTORY_USR}</username>
<password>${env.ARTIFACTORY_PSW}</password>
</server>
</servers>
</settings>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.0.RELEASE</version>
<version>3.1.13</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.0.RELEASE</version>
<version>3.1.13</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.0.RELEASE</version>
<version>3.1.13</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -65,6 +65,12 @@
<artifactId>querydsl-mongodb</artifactId>
<version>${querydsl}</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
@@ -82,28 +88,19 @@
</dependency>
<!-- reactive -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-reactivestreams</artifactId>
<version>${mongo.reactivestreams}</version>
<artifactId>mongodb-driver-sync</artifactId>
<version>${mongo}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-async</artifactId>
<version>${mongo}</version>
<artifactId>mongodb-driver-reactivestreams</artifactId>
<version>${mongo.reactivestreams}</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
@@ -139,6 +136,13 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.reactivex.rxjava3</groupId>
<artifactId>rxjava</artifactId>
<version>${rxjava3}</version>
<optional>true</optional>
</dependency>
<!-- CDI -->
<!-- Dependency order required to build against CDI 1.0 and test with CDI 2.0 -->
<dependency>
@@ -195,7 +199,14 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
<version>5.4.3.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b11</version>
<scope>test</scope>
</dependency>
@@ -253,6 +264,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<version>0.5.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
@@ -340,12 +358,6 @@
<java.util.logging.config.file>src/test/resources/logging.properties</java.util.logging.config.file>
<reactor.trace.cancel>true</reactor.trace.cancel>
</systemPropertyVariables>
<properties>
<property>
<name>listener</name>
<value>org.springframework.data.mongodb.test.util.CleanMongoDBJunitRunListener</value>
</property>
</properties>
</configuration>
</plugin>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,9 @@ import java.util.List;
import org.springframework.dao.DataAccessException;
import com.mongodb.BulkWriteError;
import com.mongodb.BulkWriteException;
import com.mongodb.BulkWriteResult;
import com.mongodb.MongoBulkWriteException;
import com.mongodb.bulk.BulkWriteError;
import com.mongodb.bulk.BulkWriteResult;
/**
* Is thrown when errors occur during bulk operations.
@@ -38,12 +38,12 @@ public class BulkOperationException extends DataAccessException {
private final BulkWriteResult result;
/**
* Creates a new {@link BulkOperationException} with the given message and source {@link BulkWriteException}.
* Creates a new {@link BulkOperationException} with the given message and source {@link MongoBulkWriteException}.
*
* @param message must not be {@literal null}.
* @param source must not be {@literal null}.
*/
public BulkOperationException(String message, BulkWriteException source) {
public BulkOperationException(String message, MongoBulkWriteException source) {
super(message, source);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 the original author or authors.
* Copyright 2010-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2019 the original author or authors.
* Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,10 @@ public class LazyLoadingException extends UncategorizedDataAccessException {
private static final long serialVersionUID = -7089224903873220037L;
/**
* @param msg
* @param cause
* Constructor for LazyLoadingException.
*
* @param msg the detail message.
* @param cause the exception thrown by underlying data access API.
*/
public LazyLoadingException(String msg, Throwable cause) {
super(msg, cause);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -0,0 +1,112 @@
/*
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb;
import org.bson.codecs.configuration.CodecRegistry;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.core.MongoExceptionTranslator;
import com.mongodb.ClientSessionOptions;
import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoDatabase;
/**
* Interface for factories creating {@link MongoDatabase} instances.
*
* @author Mark Pollack
* @author Thomas Darimont
* @author Christoph Strobl
* @since 3.0
*/
public interface MongoDatabaseFactory extends CodecRegistryProvider, MongoSessionProvider {
/**
* Obtain a {@link MongoDatabase} from the underlying factory.
*
* @return never {@literal null}.
* @throws DataAccessException
*/
MongoDatabase getMongoDatabase() throws DataAccessException;
/**
* Obtain a {@link MongoDatabase} instance to access the database with the given name.
*
* @param dbName must not be {@literal null}.
* @return never {@literal null}.
* @throws DataAccessException
*/
MongoDatabase getMongoDatabase(String dbName) throws DataAccessException;
/**
* Exposes a shared {@link MongoExceptionTranslator}.
*
* @return will never be {@literal null}.
*/
PersistenceExceptionTranslator getExceptionTranslator();
/**
* Get the underlying {@link CodecRegistry} used by the MongoDB Java driver.
*
* @return never {@literal null}.
*/
@Override
default CodecRegistry getCodecRegistry() {
return getMongoDatabase().getCodecRegistry();
}
/**
* Obtain a {@link ClientSession} for given ClientSessionOptions.
*
* @param options must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
ClientSession getSession(ClientSessionOptions options);
/**
* Obtain a {@link ClientSession} bound instance of {@link MongoDatabaseFactory} returning {@link MongoDatabase}
* instances that are aware and bound to a new session with given {@link ClientSessionOptions options}.
*
* @param options must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
default MongoDatabaseFactory withSession(ClientSessionOptions options) {
return withSession(getSession(options));
}
/**
* Obtain a {@link ClientSession} bound instance of {@link MongoDatabaseFactory} returning {@link MongoDatabase}
* instances that are aware and bound to the given session.
*
* @param session must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
MongoDatabaseFactory withSession(ClientSession session);
/**
* Returns if the given {@link MongoDatabaseFactory} is bound to a {@link ClientSession} that has an
* {@link ClientSession#hasActiveTransaction() active transaction}.
*
* @return {@literal true} if there's an active transaction, {@literal false} otherwise.
* @since 2.1.3
*/
default boolean isTransactionActive() {
return false;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoDatabase;
/**
* Helper class for managing a {@link MongoDatabase} instances via {@link MongoDbFactory}. Used for obtaining
* Helper class for managing a {@link MongoDatabase} instances via {@link MongoDatabaseFactory}. Used for obtaining
* {@link ClientSession session bound} resources, such as {@link MongoDatabase} and
* {@link com.mongodb.client.MongoCollection} suitable for transactional usage.
* <p />
@@ -41,93 +41,94 @@ import com.mongodb.client.MongoDatabase;
public class MongoDatabaseUtils {
/**
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDbFactory factory} using
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory} using
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
* <p />
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
*
* @param factory the {@link MongoDbFactory} to get the {@link MongoDatabase} from.
* @param factory the {@link MongoDatabaseFactory} to get the {@link MongoDatabase} from.
* @return the {@link MongoDatabase} that is potentially associated with a transactional {@link ClientSession}.
*/
public static MongoDatabase getDatabase(MongoDbFactory factory) {
public static MongoDatabase getDatabase(MongoDatabaseFactory factory) {
return doGetMongoDatabase(null, factory, SessionSynchronization.ON_ACTUAL_TRANSACTION);
}
/**
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDbFactory factory}.
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory}.
* <p />
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
*
* @param factory the {@link MongoDbFactory} to get the {@link MongoDatabase} from.
* @param factory the {@link MongoDatabaseFactory} to get the {@link MongoDatabase} from.
* @param sessionSynchronization the synchronization to use. Must not be {@literal null}.
* @return the {@link MongoDatabase} that is potentially associated with a transactional {@link ClientSession}.
*/
public static MongoDatabase getDatabase(MongoDbFactory factory, SessionSynchronization sessionSynchronization) {
public static MongoDatabase getDatabase(MongoDatabaseFactory factory, SessionSynchronization sessionSynchronization) {
return doGetMongoDatabase(null, factory, sessionSynchronization);
}
/**
* Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDbFactory factory} using
* Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDatabaseFactory factory} using
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
* <p />
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
*
* @param dbName the name of the {@link MongoDatabase} to get.
* @param factory the {@link MongoDbFactory} to get the {@link MongoDatabase} from.
* @param factory the {@link MongoDatabaseFactory} to get the {@link MongoDatabase} from.
* @return the {@link MongoDatabase} that is potentially associated with a transactional {@link ClientSession}.
*/
public static MongoDatabase getDatabase(String dbName, MongoDbFactory factory) {
public static MongoDatabase getDatabase(@Nullable String dbName, MongoDatabaseFactory factory) {
return doGetMongoDatabase(dbName, factory, SessionSynchronization.ON_ACTUAL_TRANSACTION);
}
/**
* Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDbFactory factory}.
* Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDatabaseFactory factory}.
* <p />
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
*
*
* @param dbName the name of the {@link MongoDatabase} to get.
* @param factory the {@link MongoDbFactory} to get the {@link MongoDatabase} from.
* @param factory the {@link MongoDatabaseFactory} to get the {@link MongoDatabase} from.
* @param sessionSynchronization the synchronization to use. Must not be {@literal null}.
* @return the {@link MongoDatabase} that is potentially associated with a transactional {@link ClientSession}.
*/
public static MongoDatabase getDatabase(String dbName, MongoDbFactory factory,
public static MongoDatabase getDatabase(@Nullable String dbName, MongoDatabaseFactory factory,
SessionSynchronization sessionSynchronization) {
return doGetMongoDatabase(dbName, factory, sessionSynchronization);
}
private static MongoDatabase doGetMongoDatabase(@Nullable String dbName, MongoDbFactory factory,
private static MongoDatabase doGetMongoDatabase(@Nullable String dbName, MongoDatabaseFactory factory,
SessionSynchronization sessionSynchronization) {
Assert.notNull(factory, "Factory must not be null!");
if (!TransactionSynchronizationManager.isSynchronizationActive()) {
return StringUtils.hasText(dbName) ? factory.getDb(dbName) : factory.getDb();
return StringUtils.hasText(dbName) ? factory.getMongoDatabase(dbName) : factory.getMongoDatabase();
}
ClientSession session = doGetSession(factory, sessionSynchronization);
if (session == null) {
return StringUtils.hasText(dbName) ? factory.getDb(dbName) : factory.getDb();
return StringUtils.hasText(dbName) ? factory.getMongoDatabase(dbName) : factory.getMongoDatabase();
}
MongoDbFactory factoryToUse = factory.withSession(session);
return StringUtils.hasText(dbName) ? factoryToUse.getDb(dbName) : factoryToUse.getDb();
MongoDatabaseFactory factoryToUse = factory.withSession(session);
return StringUtils.hasText(dbName) ? factoryToUse.getMongoDatabase(dbName) : factoryToUse.getMongoDatabase();
}
/**
* Check if the {@link MongoDbFactory} is actually bound to a {@link ClientSession} that has an active transaction, or
* if a {@link TransactionSynchronization} has been registered for the {@link MongoDbFactory resource} and if the
* associated {@link ClientSession} has an {@link ClientSession#hasActiveTransaction() active transaction}.
* Check if the {@link MongoDatabaseFactory} is actually bound to a {@link ClientSession} that has an active
* transaction, or if a {@link TransactionSynchronization} has been registered for the {@link MongoDatabaseFactory
* resource} and if the associated {@link ClientSession} has an {@link ClientSession#hasActiveTransaction() active
* transaction}.
*
* @param dbFactory the resource to check transactions for. Must not be {@literal null}.
* @return {@literal true} if the factory has an ongoing transaction.
* @since 2.1.3
*/
public static boolean isTransactionActive(MongoDbFactory dbFactory) {
public static boolean isTransactionActive(MongoDatabaseFactory dbFactory) {
if (dbFactory.isTransactionActive()) {
return true;
@@ -138,7 +139,8 @@ public class MongoDatabaseUtils {
}
@Nullable
private static ClientSession doGetSession(MongoDbFactory dbFactory, SessionSynchronization sessionSynchronization) {
private static ClientSession doGetSession(MongoDatabaseFactory dbFactory,
SessionSynchronization sessionSynchronization) {
MongoResourceHolder resourceHolder = (MongoResourceHolder) TransactionSynchronizationManager.getResource(dbFactory);
@@ -169,7 +171,7 @@ public class MongoDatabaseUtils {
return resourceHolder.getSession();
}
private static ClientSession createClientSession(MongoDbFactory dbFactory) {
private static ClientSession createClientSession(MongoDatabaseFactory dbFactory) {
return dbFactory.getSession(ClientSessionOptions.builder().causallyConsistent(true).build());
}
@@ -184,7 +186,7 @@ public class MongoDatabaseUtils {
private final MongoResourceHolder resourceHolder;
MongoSessionSynchronization(MongoResourceHolder resourceHolder, MongoDbFactory dbFactory) {
MongoSessionSynchronization(MongoResourceHolder resourceHolder, MongoDatabaseFactory dbFactory) {
super(resourceHolder, dbFactory);
this.resourceHolder = resourceHolder;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,14 +15,8 @@
*/
package org.springframework.data.mongodb;
import org.bson.codecs.configuration.CodecRegistry;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.core.MongoExceptionTranslator;
import com.mongodb.ClientSessionOptions;
import com.mongodb.DB;
import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoDatabase;
/**
@@ -31,92 +25,33 @@ import com.mongodb.client.MongoDatabase;
* @author Mark Pollack
* @author Thomas Darimont
* @author Christoph Strobl
* @deprecated since 3.0, use {@link MongoDatabaseFactory} instead.
*/
public interface MongoDbFactory extends CodecRegistryProvider, MongoSessionProvider {
@Deprecated
public interface MongoDbFactory extends MongoDatabaseFactory {
/**
* Creates a default {@link MongoDatabase} instance.
*
* @return
* @return never {@literal null}.
* @throws DataAccessException
*/
MongoDatabase getDb() throws DataAccessException;
/**
* Creates a {@link DB} instance to access the database with the given name.
*
* @param dbName must not be {@literal null} or empty.
* @return
* @throws DataAccessException
*/
MongoDatabase getDb(String dbName) throws DataAccessException;
/**
* Exposes a shared {@link MongoExceptionTranslator}.
*
* @return will never be {@literal null}.
*/
PersistenceExceptionTranslator getExceptionTranslator();
/**
* Get the legacy database entry point. Please consider {@link #getDb()} instead.
*
* @return
* @deprecated since 2.1, use {@link #getDb()}. This method will be removed with a future version as it works only
* with the legacy MongoDB driver.
* @deprecated since 3.0. Use {@link #getMongoDatabase()} instead.
*/
@Deprecated
DB getLegacyDb();
/**
* Get the underlying {@link CodecRegistry} used by the MongoDB Java driver.
*
* @return never {@literal null}.
*/
@Override
default CodecRegistry getCodecRegistry() {
return getDb().getCodecRegistry();
default MongoDatabase getDb() throws DataAccessException {
return getMongoDatabase();
}
/**
* Obtain a {@link ClientSession} for given ClientSessionOptions.
* Obtain a {@link MongoDatabase} instance to access the database with the given name.
*
* @param options must not be {@literal null}.
* @param dbName must not be {@literal null} or empty.
* @return never {@literal null}.
* @since 2.1
* @throws DataAccessException
* @deprecated since 3.0. Use {@link #getMongoDatabase(String)} instead.
*/
ClientSession getSession(ClientSessionOptions options);
/**
* Obtain a {@link ClientSession} bound instance of {@link MongoDbFactory} returning {@link MongoDatabase} instances
* that are aware and bound to a new session with given {@link ClientSessionOptions options}.
*
* @param options must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
default MongoDbFactory withSession(ClientSessionOptions options) {
return withSession(getSession(options));
}
/**
* Obtain a {@link ClientSession} bound instance of {@link MongoDbFactory} returning {@link MongoDatabase} instances
* that are aware and bound to the given session.
*
* @param session must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
MongoDbFactory withSession(ClientSession session);
/**
* Returns if the given {@link MongoDbFactory} is bound to a {@link ClientSession} that has an
* {@link ClientSession#hasActiveTransaction() active transaction}.
*
* @return {@literal true} if there's an active transaction, {@literal false} otherwise.
* @since 2.1.3
*/
default boolean isTransactionActive() {
return false;
@Deprecated
default MongoDatabase getDb(String dbName) throws DataAccessException {
return getMongoDatabase(dbName);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,15 +36,15 @@ import com.mongodb.client.ClientSession;
class MongoResourceHolder extends ResourceHolderSupport {
private @Nullable ClientSession session;
private MongoDbFactory dbFactory;
private MongoDatabaseFactory dbFactory;
/**
* Create a new {@link MongoResourceHolder} for a given {@link ClientSession session}.
*
* @param session the associated {@link ClientSession}. Can be {@literal null}.
* @param dbFactory the associated {@link MongoDbFactory}. must not be {@literal null}.
* @param dbFactory the associated {@link MongoDatabaseFactory}. must not be {@literal null}.
*/
MongoResourceHolder(@Nullable ClientSession session, MongoDbFactory dbFactory) {
MongoResourceHolder(@Nullable ClientSession session, MongoDatabaseFactory dbFactory) {
this.session = session;
this.dbFactory = dbFactory;
@@ -75,9 +75,9 @@ class MongoResourceHolder extends ResourceHolderSupport {
}
/**
* @return the associated {@link MongoDbFactory}.
* @return the associated {@link MongoDatabaseFactory}.
*/
public MongoDbFactory getDbFactory() {
public MongoDatabaseFactory getDbFactory() {
return dbFactory;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,17 +36,18 @@ import com.mongodb.client.ClientSession;
/**
* A {@link org.springframework.transaction.PlatformTransactionManager} implementation that manages
* {@link ClientSession} based transactions for a single {@link MongoDbFactory}.
* {@link ClientSession} based transactions for a single {@link MongoDatabaseFactory}.
* <p />
* Binds a {@link ClientSession} from the specified {@link MongoDbFactory} to the thread.
* Binds a {@link ClientSession} from the specified {@link MongoDatabaseFactory} to the thread.
* <p />
* {@link TransactionDefinition#isReadOnly() Readonly} transactions operate on a {@link ClientSession} and enable causal
* consistency, and also {@link ClientSession#startTransaction() start}, {@link ClientSession#commitTransaction()
* commit} or {@link ClientSession#abortTransaction() abort} a transaction.
* <p />
* Application code is required to retrieve the {@link com.mongodb.client.MongoDatabase} via
* {@link MongoDatabaseUtils#getDatabase(MongoDbFactory)} instead of a standard {@link MongoDbFactory#getDb()} call.
* Spring classes such as {@link org.springframework.data.mongodb.core.MongoTemplate} use this strategy implicitly.
* {@link MongoDatabaseUtils#getDatabase(MongoDatabaseFactory)} instead of a standard
* {@link MongoDatabaseFactory#getMongoDatabase()} call. Spring classes such as
* {@link org.springframework.data.mongodb.core.MongoTemplate} use this strategy implicitly.
* <p />
* By default failure of a {@literal commit} operation raises a {@link TransactionSystemException}. One may override
* {@link #doCommit(MongoTransactionObject)} to implement the
@@ -58,46 +59,46 @@ import com.mongodb.client.ClientSession;
* @currentRead Shadow's Edge - Brent Weeks
* @since 2.1
* @see <a href="https://www.mongodb.com/transactions">MongoDB Transaction Documentation</a>
* @see MongoDatabaseUtils#getDatabase(MongoDbFactory, SessionSynchronization)
* @see MongoDatabaseUtils#getDatabase(MongoDatabaseFactory, SessionSynchronization)
*/
public class MongoTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, InitializingBean {
private @Nullable MongoDbFactory dbFactory;
private @Nullable MongoDatabaseFactory dbFactory;
private @Nullable TransactionOptions options;
/**
* Create a new {@link MongoTransactionManager} for bean-style usage.
* <p />
* <strong>Note:</strong>The {@link MongoDbFactory db factory} has to be {@link #setDbFactory(MongoDbFactory) set}
* before using the instance. Use this constructor to prepare a {@link MongoTransactionManager} via a
* {@link org.springframework.beans.factory.BeanFactory}.
* <strong>Note:</strong>The {@link MongoDatabaseFactory db factory} has to be
* {@link #setDbFactory(MongoDatabaseFactory) set} before using the instance. Use this constructor to prepare a
* {@link MongoTransactionManager} via a {@link org.springframework.beans.factory.BeanFactory}.
* <p />
* Optionally it is possible to set default {@link TransactionOptions transaction options} defining
* {@link com.mongodb.ReadConcern} and {@link com.mongodb.WriteConcern}.
*
* @see #setDbFactory(MongoDbFactory)
* @see #setDbFactory(MongoDatabaseFactory)
* @see #setTransactionSynchronization(int)
*/
public MongoTransactionManager() {}
/**
* Create a new {@link MongoTransactionManager} obtaining sessions from the given {@link MongoDbFactory}.
* Create a new {@link MongoTransactionManager} obtaining sessions from the given {@link MongoDatabaseFactory}.
*
* @param dbFactory must not be {@literal null}.
*/
public MongoTransactionManager(MongoDbFactory dbFactory) {
public MongoTransactionManager(MongoDatabaseFactory dbFactory) {
this(dbFactory, null);
}
/**
* Create a new {@link MongoTransactionManager} obtaining sessions from the given {@link MongoDbFactory} applying the
* given {@link TransactionOptions options}, if present, when starting a new transaction.
* Create a new {@link MongoTransactionManager} obtaining sessions from the given {@link MongoDatabaseFactory}
* applying the given {@link TransactionOptions options}, if present, when starting a new transaction.
*
* @param dbFactory must not be {@literal null}.
* @param options can be {@literal null}.
*/
public MongoTransactionManager(MongoDbFactory dbFactory, @Nullable TransactionOptions options) {
public MongoTransactionManager(MongoDatabaseFactory dbFactory, @Nullable TransactionOptions options) {
Assert.notNull(dbFactory, "DbFactory must not be null!");
@@ -295,11 +296,11 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
}
/**
* Set the {@link MongoDbFactory} that this instance should manage transactions for.
* Set the {@link MongoDatabaseFactory} that this instance should manage transactions for.
*
* @param dbFactory must not be {@literal null}.
*/
public void setDbFactory(MongoDbFactory dbFactory) {
public void setDbFactory(MongoDatabaseFactory dbFactory) {
Assert.notNull(dbFactory, "DbFactory must not be null!");
this.dbFactory = dbFactory;
@@ -315,12 +316,12 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
}
/**
* Get the {@link MongoDbFactory} that this instance manages transactions for.
* Get the {@link MongoDatabaseFactory} that this instance manages transactions for.
*
* @return can be {@literal null}.
*/
@Nullable
public MongoDbFactory getDbFactory() {
public MongoDatabaseFactory getDbFactory() {
return dbFactory;
}
@@ -329,7 +330,7 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
* @see org.springframework.transaction.support.ResourceTransactionManager#getResourceFactory()
*/
@Override
public MongoDbFactory getResourceFactory() {
public MongoDatabaseFactory getResourceFactory() {
return getRequiredDbFactory();
}
@@ -344,7 +345,7 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
private MongoResourceHolder newResourceHolder(TransactionDefinition definition, ClientSessionOptions options) {
MongoDbFactory dbFactory = getResourceFactory();
MongoDatabaseFactory dbFactory = getResourceFactory();
MongoResourceHolder resourceHolder = new MongoResourceHolder(dbFactory.getSession(options), dbFactory);
resourceHolder.setTimeoutIfNotDefaulted(determineTimeout(definition));
@@ -355,7 +356,7 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
/**
* @throws IllegalStateException if {@link #dbFactory} is {@literal null}.
*/
private MongoDbFactory getRequiredDbFactory() {
private MongoDatabaseFactory getRequiredDbFactory() {
Assert.state(dbFactory != null,
"MongoTransactionManager operates upon a MongoDbFactory. Did you forget to provide one? It's required.");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@ import com.mongodb.reactivestreams.client.MongoDatabase;
*
* @author Mark Paluch
* @author Christoph Strobl
* @author Mathieu Ouellet
* @since 2.0
*/
public interface ReactiveMongoDatabaseFactory extends CodecRegistryProvider {
@@ -38,19 +39,19 @@ public interface ReactiveMongoDatabaseFactory extends CodecRegistryProvider {
/**
* Creates a default {@link MongoDatabase} instance.
*
* @return
* @return never {@literal null}.
* @throws DataAccessException
*/
MongoDatabase getMongoDatabase() throws DataAccessException;
Mono<MongoDatabase> getMongoDatabase() throws DataAccessException;
/**
* Creates a {@link MongoDatabase} instance to access the database with the given name.
* Obtain a {@link MongoDatabase} instance to access the database with the given name.
*
* @param dbName must not be {@literal null} or empty.
* @return
* @return never {@literal null}.
* @throws DataAccessException
*/
MongoDatabase getMongoDatabase(String dbName) throws DataAccessException;
Mono<MongoDatabase> getMongoDatabase(String dbName) throws DataAccessException;
/**
* Exposes a shared {@link MongoExceptionTranslator}.
@@ -64,10 +65,7 @@ public interface ReactiveMongoDatabaseFactory extends CodecRegistryProvider {
*
* @return never {@literal null}.
*/
@Override
default CodecRegistry getCodecRegistry() {
return getMongoDatabase().getCodecRegistry();
}
CodecRegistry getCodecRegistry();
/**
* Obtain a {@link Mono} emitting a {@link ClientSession} for given {@link ClientSessionOptions options}.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@ import com.mongodb.reactivestreams.client.MongoDatabase;
*
* @author Mark Paluch
* @author Christoph Strobl
* @author Mathieu Ouellet
* @since 2.2
*/
public class ReactiveMongoDatabaseUtils {
@@ -142,14 +143,13 @@ public class ReactiveMongoDatabaseUtils {
.flatMap(synchronizationManager -> {
return doGetSession(synchronizationManager, factory, sessionSynchronization) //
.map(it -> getMongoDatabaseOrDefault(dbName, factory.withSession(it)));
})
.onErrorResume(NoTransactionException.class,
e -> Mono.fromSupplier(() -> getMongoDatabaseOrDefault(dbName, factory)))
.defaultIfEmpty(getMongoDatabaseOrDefault(dbName, factory));
.flatMap(it -> getMongoDatabaseOrDefault(dbName, factory.withSession(it)));
}) //
.onErrorResume(NoTransactionException.class, e -> getMongoDatabaseOrDefault(dbName, factory))
.switchIfEmpty(getMongoDatabaseOrDefault(dbName, factory));
}
private static MongoDatabase getMongoDatabaseOrDefault(@Nullable String dbName,
private static Mono<MongoDatabase> getMongoDatabaseOrDefault(@Nullable String dbName,
ReactiveMongoDatabaseFactory factory) {
return StringUtils.hasText(dbName) ? factory.getMongoDatabase(dbName) : factory.getMongoDatabase();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ class ReactiveMongoResourceHolder extends ResourceHolderSupport {
* Create a new {@link ReactiveMongoResourceHolder} for a given {@link ClientSession session}.
*
* @param session the associated {@link ClientSession}. Can be {@literal null}.
* @param databaseFactory the associated {@link MongoDbFactory}. must not be {@literal null}.
* @param databaseFactory the associated {@link MongoDatabaseFactory}. must not be {@literal null}.
*/
ReactiveMongoResourceHolder(@Nullable ClientSession session, ReactiveMongoDatabaseFactory databaseFactory) {
@@ -99,7 +99,7 @@ class ReactiveMongoResourceHolder extends ResourceHolderSupport {
* If the {@link ReactiveMongoResourceHolder} is {@link #hasSession() not already associated} with a
* {@link ClientSession} the given value is {@link #setSession(ClientSession) set} and returned, otherwise the current
* bound session is returned.
*
*
* @param session
* @return
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -110,7 +110,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
this.options = options;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doGetTransaction(org.springframework.transaction.reactive.TransactionSynchronizationManager)
*/
@@ -123,7 +123,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
return new ReactiveMongoTransactionObject(resourceHolder);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#isExistingTransaction(java.lang.Object)
*/
@@ -132,7 +132,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
return extractMongoTransaction(transaction).hasResourceHolder();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doBegin(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object, org.springframework.transaction.TransactionDefinition)
*/
@@ -175,7 +175,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
});
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doSuspend(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object)
*/
@@ -192,7 +192,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
});
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doResume(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object, java.lang.Object)
*/
@@ -203,7 +203,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
.fromRunnable(() -> synchronizationManager.bindResource(getRequiredDatabaseFactory(), suspendedResources));
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doCommit(org.springframework.transaction.reactive.TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction)
*/
@@ -243,7 +243,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
return transactionObject.commitTransaction();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doRollback(org.springframework.transaction.reactive.TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction)
*/
@@ -268,7 +268,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
});
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doSetRollbackOnly(org.springframework.transaction.reactive.TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction)
*/
@@ -282,7 +282,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
});
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doCleanupAfterCompletion(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object)
*/
@@ -509,7 +509,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
return session;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.support.SmartTransactionObject#isRollbackOnly()
*/
@@ -518,7 +518,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
return this.resourceHolder != null && this.resourceHolder.isRollbackOnly();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.transaction.support.SmartTransactionObject#flush()
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -0,0 +1,77 @@
/*
* Copyright 2020-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.util.Version;
import org.springframework.util.StringUtils;
import com.mongodb.MongoDriverInformation;
/**
* Class that exposes the SpringData MongoDB specific information like the current {@link Version} or
* {@link MongoDriverInformation driver information}.
*
* @author Christoph Strobl
* @since 3.0
*/
public class SpringDataMongoDB {
private static final Logger LOGGER = LoggerFactory.getLogger(SpringDataMongoDB.class);
private static final Version FALLBACK_VERSION = new Version(3);
private static final MongoDriverInformation DRIVER_INFORMATION = MongoDriverInformation
.builder(MongoDriverInformation.builder().build()).driverName("spring-data").build();
/**
* Obtain the SpringData MongoDB specific driver information.
*
* @return never {@literal null}.
*/
public static MongoDriverInformation driverInformation() {
return DRIVER_INFORMATION;
}
/**
* Fetches the "Implementation-Version" manifest attribute from the jar file.
* <p />
* Note that some ClassLoaders do not expose the package metadata, hence this class might not be able to determine the
* version in all environments. In this case the current Major version is returned as a fallback.
*
* @return never {@literal null}.
*/
public static Version version() {
Package pkg = SpringDataMongoDB.class.getPackage();
String versionString = (pkg != null ? pkg.getImplementationVersion() : null);
if (!StringUtils.hasText(versionString)) {
LOGGER.debug("Unable to find Spring Data MongoDB version.");
return FALLBACK_VERSION;
}
try {
return Version.parse(versionString);
} catch (Exception e) {
LOGGER.debug("Cannot read Spring Data MongoDB version '{}'.", versionString);
}
return FALLBACK_VERSION;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 the original author or authors.
* Copyright 2010-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,17 +17,22 @@ package org.springframework.data.mongodb.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.SpringDataMongoDB;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.lang.Nullable;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientSettings.Builder;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
/**
* Base class for Spring Data MongoDB configuration using JavaConfig with {@link com.mongodb.client.MongoClient}.
@@ -35,40 +40,44 @@ import com.mongodb.client.MongoClient;
* @author Christoph Strobl
* @since 2.1
* @see MongoConfigurationSupport
* @see AbstractMongoConfiguration
*/
@Configuration
@Configuration(proxyBeanMethods = false)
public abstract class AbstractMongoClientConfiguration extends MongoConfigurationSupport {
/**
* Return the {@link MongoClient} instance to connect to. Annotate with {@link Bean} in case you want to expose a
* {@link MongoClient} instance to the {@link org.springframework.context.ApplicationContext}.
* {@link MongoClient} instance to the {@link org.springframework.context.ApplicationContext}. <br />
* Override {@link #mongoClientSettings()} to configure connection details.
*
* @return
* @return never {@literal null}.
* @see #mongoClientSettings()
* @see #configureClientSettings(Builder)
*/
public abstract MongoClient mongoClient();
public MongoClient mongoClient() {
return createMongoClient(mongoClientSettings());
}
/**
* Creates a {@link MongoTemplate}.
*
* @return
* @see #mongoDbFactory()
* @see #mappingMongoConverter(MongoDatabaseFactory, MongoCustomConversions, MongoMappingContext)
*/
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
public MongoTemplate mongoTemplate(MongoDatabaseFactory databaseFactory, MappingMongoConverter converter) {
return new MongoTemplate(databaseFactory, converter);
}
/**
* Creates a {@link SimpleMongoDbFactory} to be used by the {@link MongoTemplate}. Will use the {@link MongoClient}
* instance configured in {@link #mongoClient()}.
* Creates a {@link org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory} to be used by the
* {@link MongoTemplate}. Will use the {@link MongoClient} instance configured in {@link #mongoClient()}.
*
* @see #mongoClient()
* @see #mongoTemplate()
* @return
* @see #mongoTemplate(MongoDatabaseFactory, MappingMongoConverter)
*/
@Bean
public MongoDbFactory mongoDbFactory() {
return new SimpleMongoClientDbFactory(mongoClient(), getDatabaseName());
public MongoDatabaseFactory mongoDbFactory() {
return new SimpleMongoClientDatabaseFactory(mongoClient(), getDatabaseName());
}
/**
@@ -91,22 +100,32 @@ public abstract class AbstractMongoClientConfiguration extends MongoConfiguratio
/**
* Creates a {@link MappingMongoConverter} using the configured {@link #mongoDbFactory()} and
* {@link #mongoMappingContext()}. Will get {@link #customConversions()} applied.
* {@link #mongoMappingContext(MongoCustomConversions)}. Will get {@link #customConversions()} applied.
*
* @see #customConversions()
* @see #mongoMappingContext()
* @see #mongoMappingContext(MongoCustomConversions)
* @see #mongoDbFactory()
* @return
* @throws Exception
*/
@Bean
public MappingMongoConverter mappingMongoConverter() throws Exception {
public MappingMongoConverter mappingMongoConverter(MongoDatabaseFactory databaseFactory,
MongoCustomConversions customConversions, MongoMappingContext mappingContext) {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext());
converter.setCustomConversions(customConversions());
converter.setCodecRegistryProvider(mongoDbFactory());
DbRefResolver dbRefResolver = new DefaultDbRefResolver(databaseFactory);
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mappingContext);
converter.setCustomConversions(customConversions);
converter.setCodecRegistryProvider(databaseFactory);
return converter;
}
/**
* Create the Reactive Streams {@link com.mongodb.reactivestreams.client.MongoClient} instance with given
* {@link MongoClientSettings}.
*
* @return never {@literal null}.
* @since 3.0
*/
protected MongoClient createMongoClient(MongoClientSettings settings) {
return MongoClients.create(settings, SpringDataMongoDB.driverInformation());
}
}

View File

@@ -1,121 +0,0 @@
/*
* Copyright 2011-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.lang.Nullable;
import com.mongodb.MongoClient;
/**
* Base class for Spring Data MongoDB configuration using JavaConfig with {@link com.mongodb.MongoClient}.
* <p />
* <strong>INFO:</strong>In case you want to use {@link com.mongodb.client.MongoClients} for configuration please refer
* to {@link AbstractMongoClientConfiguration}.
*
* @author Mark Pollack
* @author Oliver Gierke
* @author Thomas Darimont
* @author Ryan Tenney
* @author Christoph Strobl
* @author Mark Paluch
* @see MongoConfigurationSupport
* @see AbstractMongoClientConfiguration
* @deprecated since 2.2 in favor of {@link AbstractMongoClientConfiguration}.
*/
@Configuration
@Deprecated
public abstract class AbstractMongoConfiguration extends MongoConfigurationSupport {
/**
* Return the {@link MongoClient} instance to connect to. Annotate with {@link Bean} in case you want to expose a
* {@link MongoClient} instance to the {@link org.springframework.context.ApplicationContext}.
*
* @return
*/
public abstract MongoClient mongoClient();
/**
* Creates a {@link MongoTemplate}.
*
* @return
*/
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
}
/**
* Creates a {@link SimpleMongoDbFactory} to be used by the {@link MongoTemplate}. Will use the {@link MongoClient}
* instance configured in {@link #mongoClient()}.
*
* @see #mongoClient()
* @see #mongoTemplate()
* @return
*/
@Bean
public MongoDbFactory mongoDbFactory() {
return new SimpleMongoDbFactory(mongoClient(), getDatabaseName());
}
/**
* Return the base package to scan for mapped {@link Document}s. Will return the package name of the configuration
* class' (the concrete class, not this one here) by default. So if you have a {@code com.acme.AppConfig} extending
* {@link AbstractMongoConfiguration} the base package will be considered {@code com.acme} unless the method is
* overridden to implement alternate behavior.
*
* @return the base package to scan for mapped {@link Document} classes or {@literal null} to not enable scanning for
* entities.
* @deprecated use {@link #getMappingBasePackages()} instead.
*/
@Deprecated
@Nullable
protected String getMappingBasePackage() {
Package mappingBasePackage = getClass().getPackage();
return mappingBasePackage == null ? null : mappingBasePackage.getName();
}
/**
* Creates a {@link MappingMongoConverter} using the configured {@link #mongoDbFactory()} and
* {@link #mongoMappingContext()}. Will get {@link #customConversions()} applied.
*
* @see #customConversions()
* @see #mongoMappingContext()
* @see #mongoDbFactory()
* @return
* @throws Exception
*/
@Bean
public MappingMongoConverter mappingMongoConverter() throws Exception {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext());
converter.setCustomConversions(customConversions());
converter.setCodecRegistryProvider(mongoDbFactory());
return converter;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,13 +18,19 @@ package org.springframework.data.mongodb.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.SpringDataMongoDB;
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientSettings.Builder;
import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
/**
* Base class for reactive Spring Data MongoDB configuration using JavaConfig.
@@ -34,25 +40,33 @@ import com.mongodb.reactivestreams.client.MongoClient;
* @since 2.0
* @see MongoConfigurationSupport
*/
@Configuration
@Configuration(proxyBeanMethods = false)
public abstract class AbstractReactiveMongoConfiguration extends MongoConfigurationSupport {
/**
* Return the Reactive Streams {@link MongoClient} instance to connect to. Annotate with {@link Bean} in case you want
* to expose a {@link MongoClient} instance to the {@link org.springframework.context.ApplicationContext}.
* to expose a {@link MongoClient} instance to the {@link org.springframework.context.ApplicationContext}. <br />
* Override {@link #mongoClientSettings()} to configure connection details.
*
* @return never {@literal null}.
* @see #mongoClientSettings()
* @see #configureClientSettings(Builder)
*/
public abstract MongoClient reactiveMongoClient();
public MongoClient reactiveMongoClient() {
return createReactiveMongoClient(mongoClientSettings());
}
/**
* Creates {@link ReactiveMongoOperations}.
*
* @see #reactiveMongoDbFactory()
* @see #mappingMongoConverter(ReactiveMongoDatabaseFactory, MongoCustomConversions, MongoMappingContext)
* @return never {@literal null}.
*/
@Bean
public ReactiveMongoOperations reactiveMongoTemplate() throws Exception {
return new ReactiveMongoTemplate(reactiveMongoDbFactory(), mappingMongoConverter());
public ReactiveMongoTemplate reactiveMongoTemplate(ReactiveMongoDatabaseFactory databaseFactory,
MappingMongoConverter mongoConverter) {
return new ReactiveMongoTemplate(databaseFactory, mongoConverter);
}
/**
@@ -60,7 +74,7 @@ public abstract class AbstractReactiveMongoConfiguration extends MongoConfigurat
* {@link MongoClient} instance configured in {@link #reactiveMongoClient()}.
*
* @see #reactiveMongoClient()
* @see #reactiveMongoTemplate()
* @see #reactiveMongoTemplate(ReactiveMongoDatabaseFactory, MappingMongoConverter)
* @return never {@literal null}.
*/
@Bean
@@ -70,21 +84,31 @@ public abstract class AbstractReactiveMongoConfiguration extends MongoConfigurat
/**
* Creates a {@link MappingMongoConverter} using the configured {@link #reactiveMongoDbFactory()} and
* {@link #mongoMappingContext()}. Will get {@link #customConversions()} applied.
* {@link #mongoMappingContext(MongoCustomConversions)}. Will get {@link #customConversions()} applied.
*
* @see #customConversions()
* @see #mongoMappingContext()
* @see #mongoMappingContext(MongoCustomConversions)
* @see #reactiveMongoDbFactory()
* @return never {@literal null}.
* @throws Exception
*/
@Bean
public MappingMongoConverter mappingMongoConverter() throws Exception {
public MappingMongoConverter mappingMongoConverter(ReactiveMongoDatabaseFactory databaseFactory,
MongoCustomConversions customConversions, MongoMappingContext mappingContext) {
MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mongoMappingContext());
converter.setCustomConversions(customConversions());
converter.setCodecRegistryProvider(reactiveMongoDbFactory());
MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
converter.setCustomConversions(customConversions);
converter.setCodecRegistryProvider(databaseFactory);
return converter;
}
/**
* Create the Reactive Streams {@link MongoClient} instance with given {@link MongoClientSettings}.
*
* @return never {@literal null}.
* @since 3.0
*/
protected MongoClient createReactiveMongoClient(MongoClientSettings settings) {
return MongoClients.create(settings, SpringDataMongoDB.driverInformation());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.config;
import java.beans.PropertyEditorSupport;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import com.mongodb.ConnectionString;
/**
* Parse a {@link String} to a {@link com.mongodb.ConnectionString}.
*
* @author Christoph Strobl
* @since 3.0
*/
public class ConnectionStringPropertyEditor extends PropertyEditorSupport {
/*
* (non-Javadoc)
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
*/
@Override
public void setAsText(@Nullable String connectionString) {
if (!StringUtils.hasText(connectionString)) {
return;
}
setValue(new ConnectionString(connectionString));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2019 the original author or authors.
* Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,29 +42,29 @@ public @interface EnableMongoAuditing {
/**
* Configures the {@link AuditorAware} bean to be used to lookup the current principal.
*
* @return
* @return empty {@link String} by default.
*/
String auditorAwareRef() default "";
/**
* Configures whether the creation and modification dates are set. Defaults to {@literal true}.
*
* @return
* @return {@literal true} by default.
*/
boolean setDates() default true;
/**
* Configures whether the entity shall be marked as modified on creation. Defaults to {@literal true}.
*
* @return
* @return {@literal true} by default.
*/
boolean modifyOnCreate() default true;
/**
* Configures a {@link DateTimeProvider} bean name that allows customizing the {@link org.joda.time.DateTime} to be
* used for setting creation and modification dates.
* Configures a {@link DateTimeProvider} bean name that allows customizing the timestamp to be used for setting
* creation and modification dates.
*
* @return
* @return empty {@link String} by default.
*/
String dateTimeProviderRef() default "";
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2020-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.config;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
import org.springframework.data.auditing.DateTimeProvider;
import org.springframework.data.domain.ReactiveAuditorAware;
/**
* Annotation to enable auditing in MongoDB using reactive infrastructure via annotation configuration.
*
* @author Mark Paluch
* @since 3.1
*/
@Inherited
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ReactiveMongoAuditingRegistrar.class)
public @interface EnableReactiveMongoAuditing {
/**
* Configures the {@link ReactiveAuditorAware} bean to be used to lookup the current principal.
*
* @return empty {@link String} by default.
*/
String auditorAwareRef() default "";
/**
* Configures whether the creation and modification dates are set. Defaults to {@literal true}.
*
* @return {@literal true} by default.
*/
boolean setDates() default true;
/**
* Configures whether the entity shall be marked as modified on creation. Defaults to {@literal true}.
*
* @return {@literal true} by default.
*/
boolean modifyOnCreate() default true;
/**
* Configures a {@link DateTimeProvider} bean name that allows customizing the timestamp to be used for setting
* creation and modification dates.
*
* @return empty {@link String} by default.
*/
String dateTimeProviderRef() default "";
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2019 the original author or authors.
* Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -96,6 +96,9 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
String id = element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE);
id = StringUtils.hasText(id) ? id : DEFAULT_CONVERTER_BEAN_NAME;
String autoIndexCreation = element.getAttribute("auto-index-creation");
boolean autoIndexCreationEnabled = StringUtils.hasText(autoIndexCreation) && Boolean.valueOf(autoIndexCreation);
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mapping Mongo Converter", element));
BeanDefinition conversionsDefinition = getCustomConversions(element, parserContext);
@@ -199,6 +202,11 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
public static String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
@Nullable BeanDefinition conversionsDefinition, @Nullable String converterId) {
return potentiallyCreateMappingContext(element, parserContext, conversionsDefinition, converterId, false);
}
public static String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
@Nullable BeanDefinition conversionsDefinition, @Nullable String converterId, boolean autoIndexCreation) {
String ctxRef = element.getAttribute("mapping-context-ref");
@@ -226,6 +234,8 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
mappingContextBuilder.addPropertyValue("simpleTypeHolder", simpleTypesDefinition);
}
mappingContextBuilder.addPropertyValue("autoIndexCreation", autoIndexCreation);
parseFieldNamingStrategy(element, parserContext.getReaderContext(), mappingContextBuilder);
ctxRef = converterId == null || DEFAULT_CONVERTER_BEAN_NAME.equals(converterId) ? MAPPING_CONTEXT_BEAN_NAME

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2019 the original author or authors.
* Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@ package org.springframework.data.mongodb.config;
import java.lang.annotation.Annotation;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -28,14 +27,8 @@ import org.springframework.data.auditing.IsNewAwareAuditingHandler;
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
import org.springframework.data.auditing.config.AuditingConfiguration;
import org.springframework.data.config.ParsingUtils;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback;
import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableMongoAuditing} annotation.
@@ -46,9 +39,6 @@ import org.springframework.util.ClassUtils;
*/
class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
private static boolean PROJECT_REACTOR_AVAILABLE = ClassUtils.isPresent("reactor.core.publisher.Mono",
MongoAuditingRegistrar.class.getClassLoader());
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation()
@@ -91,7 +81,7 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContextLookup.class);
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntitiesFactoryBean.class);
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
builder.addConstructorArgValue(definition.getBeanDefinition());
@@ -116,68 +106,6 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(),
AuditingEntityCallback.class.getName(), registry);
if (PROJECT_REACTOR_AVAILABLE) {
registerReactiveAuditingEntityCallback(registry, auditingHandlerDefinition.getSource());
}
}
private void registerReactiveAuditingEntityCallback(BeanDefinitionRegistry registry, Object source) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class);
builder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
builder.getRawBeanDefinition().setSource(source);
registerInfrastructureBeanWithId(builder.getBeanDefinition(), ReactiveAuditingEntityCallback.class.getName(),
registry);
}
/**
* Simple helper to be able to wire the {@link MappingContext} from a {@link MappingMongoConverter} bean available in
* the application context.
*
* @author Oliver Gierke
*/
static class MongoMappingContextLookup
implements FactoryBean<MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty>> {
private final MappingMongoConverter converter;
/**
* Creates a new {@link MongoMappingContextLookup} for the given {@link MappingMongoConverter}.
*
* @param converter must not be {@literal null}.
*/
public MongoMappingContextLookup(MappingMongoConverter converter) {
this.converter = converter;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
@Override
public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getObject() throws Exception {
return converter.getMappingContext();
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
@Override
public Class<?> getObjectType() {
return MappingContext.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
@Override
public boolean isSingleton() {
return true;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,10 +50,11 @@ public class MongoClientParser implements BeanDefinitionParser {
ParsingUtils.setPropertyValue(builder, element, "port", "port");
ParsingUtils.setPropertyValue(builder, element, "host", "host");
ParsingUtils.setPropertyValue(builder, element, "credentials", "credentials");
ParsingUtils.setPropertyValue(builder, element, "credential", "credential");
ParsingUtils.setPropertyValue(builder, element, "replica-set", "replicaSet");
ParsingUtils.setPropertyValue(builder, element, "connection-string", "connectionString");
MongoParsingUtils.parseMongoClientOptions(element, builder);
MongoParsingUtils.parseReplicaSet(element, builder);
MongoParsingUtils.parseMongoClientSettings(element, builder);
String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO_BEAN_NAME;
@@ -62,22 +63,34 @@ public class MongoClientParser implements BeanDefinitionParser {
BeanComponentDefinition mongoComponent = helper.getComponent(builder, defaultedId);
parserContext.registerBeanComponent(mongoComponent);
BeanComponentDefinition serverAddressPropertyEditor = helper.getComponent(MongoParsingUtils
.getServerAddressPropertyEditorBuilder());
BeanComponentDefinition connectionStringPropertyEditor = helper
.getComponent(MongoParsingUtils.getConnectionStringPropertyEditorBuilder());
parserContext.registerBeanComponent(connectionStringPropertyEditor);
BeanComponentDefinition serverAddressPropertyEditor = helper
.getComponent(MongoParsingUtils.getServerAddressPropertyEditorBuilder());
parserContext.registerBeanComponent(serverAddressPropertyEditor);
BeanComponentDefinition writeConcernEditor = helper.getComponent(MongoParsingUtils
.getWriteConcernPropertyEditorBuilder());
BeanComponentDefinition writeConcernEditor = helper
.getComponent(MongoParsingUtils.getWriteConcernPropertyEditorBuilder());
parserContext.registerBeanComponent(writeConcernEditor);
BeanComponentDefinition readPreferenceEditor = helper.getComponent(MongoParsingUtils
.getReadPreferencePropertyEditorBuilder());
BeanComponentDefinition readConcernEditor = helper
.getComponent(MongoParsingUtils.getReadConcernPropertyEditorBuilder());
parserContext.registerBeanComponent(readConcernEditor);
BeanComponentDefinition readPreferenceEditor = helper
.getComponent(MongoParsingUtils.getReadPreferencePropertyEditorBuilder());
parserContext.registerBeanComponent(readPreferenceEditor);
BeanComponentDefinition credentialsEditor = helper.getComponent(MongoParsingUtils
.getMongoCredentialPropertyEditor());
BeanComponentDefinition credentialsEditor = helper
.getComponent(MongoParsingUtils.getMongoCredentialPropertyEditor());
parserContext.registerBeanComponent(credentialsEditor);
BeanComponentDefinition uuidRepresentationEditor = helper
.getComponent(MongoParsingUtils.getUUidRepresentationEditorBuilder());
parserContext.registerBeanComponent(uuidRepresentationEditor);
parserContext.popAndRegisterContainingComponent();
return mongoComponent.getBeanDefinition();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,22 +20,26 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.bson.UuidRepresentation;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.data.annotation.Persistent;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy;
import org.springframework.data.mapping.model.FieldNamingStrategy;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientSettings.Builder;
/**
* Base class for Spring Data MongoDB to be extended for JavaConfiguration usage.
*
@@ -75,11 +79,12 @@ public abstract class MongoConfigurationSupport {
* @throws ClassNotFoundException
*/
@Bean
public MongoMappingContext mongoMappingContext() throws ClassNotFoundException {
public MongoMappingContext mongoMappingContext(MongoCustomConversions customConversions)
throws ClassNotFoundException {
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setInitialEntitySet(getInitialEntitySet());
mappingContext.setSimpleTypeHolder(customConversions().getSimpleTypeHolder());
mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
mappingContext.setFieldNamingStrategy(fieldNamingStrategy());
mappingContext.setAutoIndexCreation(autoIndexCreation());
@@ -88,14 +93,30 @@ public abstract class MongoConfigurationSupport {
/**
* Register custom {@link Converter}s in a {@link CustomConversions} object if required. These
* {@link CustomConversions} will be registered with the {@link #mappingMongoConverter()} and
* {@link #mongoMappingContext()}. Returns an empty {@link MongoCustomConversions} instance by default.
* {@link CustomConversions} will be registered with the
* {@link org.springframework.data.mongodb.core.convert.MappingMongoConverter} and {@link MongoMappingContext}.
* Returns an empty {@link MongoCustomConversions} instance by default.
* <p>
* <strong>NOTE:</strong> Use {@link #configureConverters(MongoConverterConfigurationAdapter)} to configure MongoDB
* native simple types and register custom {@link Converter converters}.
*
* @return must not be {@literal null}.
*/
@Bean
public CustomConversions customConversions() {
return new MongoCustomConversions(Collections.emptyList());
public MongoCustomConversions customConversions() {
return MongoCustomConversions.create(this::configureConverters);
}
/**
* Configuration hook for {@link MongoCustomConversions} creation.
*
* @param converterConfigurationAdapter never {@literal null}.
* @since 2.3
* @see MongoConverterConfigurationAdapter#useNativeDriverJavaTimeCodecs()
* @see MongoConverterConfigurationAdapter#useSpringDataJavaTimeCodecs()
*/
protected void configureConverters(MongoConverterConfigurationAdapter converterConfigurationAdapter) {
}
/**
@@ -118,8 +139,7 @@ public abstract class MongoConfigurationSupport {
}
/**
* Scans the given base package for entities, i.e. MongoDB specific types annotated with {@link Document} and
* {@link Persistent}.
* Scans the given base package for entities, i.e. MongoDB specific types annotated with {@link Document}.
*
* @param basePackage must not be {@literal null}.
* @return
@@ -139,7 +159,6 @@ public abstract class MongoConfigurationSupport {
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
false);
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
@@ -177,11 +196,36 @@ public abstract class MongoConfigurationSupport {
* Configure whether to automatically create indices for domain types by deriving the
* {@link org.springframework.data.mongodb.core.index.IndexDefinition} from the entity or not.
*
* @return {@literal true} by default. <br />
* <strong>INFO</strong>: As of 3.x the default will be set to {@literal false}.
* @return {@literal false} by default. <br />
* <strong>INFO</strong>: As of 3.x the default is set to {@literal false}; In 2.x it was {@literal true}.
* @since 2.2
*/
protected boolean autoIndexCreation() {
return true;
return false;
}
/**
* Return the {@link MongoClientSettings} used to create the actual {@literal MongoClient}. <br />
* Override either this method, or use {@link #configureClientSettings(Builder)} to alter the setup.
*
* @return never {@literal null}.
* @since 3.0
*/
protected MongoClientSettings mongoClientSettings() {
MongoClientSettings.Builder builder = MongoClientSettings.builder();
builder.uuidRepresentation(UuidRepresentation.JAVA_LEGACY);
configureClientSettings(builder);
return builder.build();
}
/**
* Configure {@link MongoClientSettings} via its {@link Builder} API.
*
* @param builder never {@literal null}.
* @since 3.0
*/
protected void configureClientSettings(MongoClientSettings.Builder builder) {
// customization hook
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,14 +32,12 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.config.BeanComponentDefinitionBuilder;
import org.springframework.data.mongodb.core.MongoClientFactoryBean;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
import com.mongodb.Mongo;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoURI;
import com.mongodb.ConnectionString;
/**
* {@link BeanDefinitionParser} to parse {@code db-factory} elements into {@link BeanDefinition}s.
@@ -84,10 +82,11 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
// Common setup
BeanDefinitionBuilder dbFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(SimpleMongoDbFactory.class);
BeanDefinitionBuilder dbFactoryBuilder = BeanDefinitionBuilder
.genericBeanDefinition(SimpleMongoClientDatabaseFactory.class);
setPropertyValue(dbFactoryBuilder, element, "write-concern", "writeConcern");
BeanDefinition mongoUri = getMongoUri(element, parserContext);
BeanDefinition mongoUri = getConnectionString(element, parserContext);
if (mongoUri != null) {
@@ -97,7 +96,8 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
String mongoRef = element.getAttribute("mongo-ref");
String mongoRef = element.getAttribute("mongo-client-ref");
String dbname = element.getAttribute("dbname");
// Defaulting
@@ -119,8 +119,8 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
}
/**
* Registers a default {@link BeanDefinition} of a {@link Mongo} instance and returns the name under which the
* {@link Mongo} instance was registered under.
* Registers a default {@link BeanDefinition} of a {@link com.mongodb.client.MongoClient} instance and returns the
* name under which the {@link com.mongodb.client.MongoClient} instance was registered under.
*
* @param element must not be {@literal null}.
* @param parserContext must not be {@literal null}.
@@ -136,8 +136,7 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
}
/**
* Creates a {@link BeanDefinition} for a {@link MongoURI} or {@link MongoClientURI} depending on configured
* attributes. <br />
* Creates a {@link BeanDefinition} for a {@link ConnectionString} depending on configured attributes. <br />
* Errors when configured element contains {@literal uri} or {@literal client-uri} along with other attributes except
* {@literal write-concern} and/or {@literal id}.
*
@@ -146,11 +145,19 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
* @return {@literal null} in case no client-/uri defined.
*/
@Nullable
private BeanDefinition getMongoUri(Element element, ParserContext parserContext) {
private BeanDefinition getConnectionString(Element element, ParserContext parserContext) {
boolean hasClientUri = element.hasAttribute("client-uri");
String type = null;
if (!hasClientUri && !element.hasAttribute("uri")) {
if (element.hasAttribute("client-uri")) {
type = "client-uri";
} else if (element.hasAttribute("connection-string")) {
type = "connection-string";
} else if (element.hasAttribute("uri")) {
type = "uri";
}
if (!StringUtils.hasText(type)) {
return null;
}
@@ -164,16 +171,12 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
if (element.getAttributes().getLength() > allowedAttributesCount) {
parserContext.getReaderContext().error(
"Configure either " + (hasClientUri ? "Mongo Client URI" : "Mongo URI") + " or details individually!",
parserContext.getReaderContext().error("Configure either MongoDB " + type + " or details individually!",
parserContext.extractSource(element));
}
Class<?> type = MongoClientURI.class;
String uri = hasClientUri ? element.getAttribute("client-uri") : element.getAttribute("uri");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(type);
builder.addConstructorArgValue(uri);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ConnectionString.class);
builder.addConstructorArgValue(element.getAttribute(type));
return builder.getBeanDefinition();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ import org.springframework.beans.factory.config.CustomEditorConfigurer;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.data.mongodb.core.MongoClientOptionsFactoryBean;
import org.springframework.data.mongodb.core.MongoClientSettingsFactoryBean;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
@@ -43,60 +43,78 @@ abstract class MongoParsingUtils {
private MongoParsingUtils() {}
/**
* Parses the mongo replica-set element.
*
* @param parserContext the parser context
* @param element the mongo element
* @param mongoBuilder the bean definition builder to populate
* @return
*/
static void parseReplicaSet(Element element, BeanDefinitionBuilder mongoBuilder) {
setPropertyValue(mongoBuilder, element, "replica-set", "replicaSetSeeds");
}
/**
* Parses the {@code mongo:client-options} sub-element. Populates the given attribute factory with the proper
* Parses the {@code mongo:client-settings} sub-element. Populates the given attribute factory with the proper
* attributes.
*
* @param element must not be {@literal null}.
* @param mongoClientBuilder must not be {@literal null}.
* @param element
* @param mongoClientBuilder
* @return
* @since 1.7
* @since 3.0
*/
public static boolean parseMongoClientOptions(Element element, BeanDefinitionBuilder mongoClientBuilder) {
public static boolean parseMongoClientSettings(Element element, BeanDefinitionBuilder mongoClientBuilder) {
Element optionsElement = DomUtils.getChildElementByTagName(element, "client-options");
if (optionsElement == null) {
Element settingsElement = DomUtils.getChildElementByTagName(element, "client-settings");
if (settingsElement == null) {
return false;
}
BeanDefinitionBuilder clientOptionsDefBuilder = BeanDefinitionBuilder
.genericBeanDefinition(MongoClientOptionsFactoryBean.class);
.genericBeanDefinition(MongoClientSettingsFactoryBean.class);
setPropertyValue(clientOptionsDefBuilder, optionsElement, "description", "description");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "min-connections-per-host", "minConnectionsPerHost");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "connections-per-host", "connectionsPerHost");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "threads-allowed-to-block-for-connection-multiplier",
"threadsAllowedToBlockForConnectionMultiplier");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-wait-time", "maxWaitTime");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-connection-idle-time", "maxConnectionIdleTime");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-connection-life-time", "maxConnectionLifeTime");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "connect-timeout", "connectTimeout");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "socket-timeout", "socketTimeout");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "socket-keep-alive", "socketKeepAlive");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "read-preference", "readPreference");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "write-concern", "writeConcern");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-frequency", "heartbeatFrequency");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "min-heartbeat-frequency", "minHeartbeatFrequency");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-connect-timeout", "heartbeatConnectTimeout");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-socket-timeout", "heartbeatSocketTimeout");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "ssl", "ssl");
setPropertyReference(clientOptionsDefBuilder, optionsElement, "ssl-socket-factory-ref", "sslSocketFactory");
setPropertyReference(clientOptionsDefBuilder, optionsElement, "encryption-settings-ref", "autoEncryptionSettings");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "server-selection-timeout", "serverSelectionTimeout");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "application-name", "applicationName");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "read-preference", "readPreference");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "read-concern", "readConcern");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "write-concern", "writeConcern");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "retry-reads", "retryReads");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "retry-writes", "retryWrites");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "uuid-representation", "uUidRepresentation");
mongoClientBuilder.addPropertyValue("mongoClientOptions", clientOptionsDefBuilder.getBeanDefinition());
// SocketSettings
setPropertyValue(clientOptionsDefBuilder, settingsElement, "socket-connect-timeout", "socketConnectTimeoutMS");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "socket-read-timeout", "socketReadTimeoutMS");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "socket-receive-buffer-size", "socketReceiveBufferSize");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "socket-send-buffer-size", "socketSendBufferSize");
// Server Settings
setPropertyValue(clientOptionsDefBuilder, settingsElement, "server-heartbeat-frequency",
"serverHeartbeatFrequencyMS");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "server-min-heartbeat-frequency",
"serverMinHeartbeatFrequencyMS");
// Cluster Settings
setPropertyValue(clientOptionsDefBuilder, settingsElement, "cluster-srv-host", "clusterSrvHost");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "cluster-hosts", "clusterHosts");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "cluster-connection-mode", "clusterConnectionMode");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "cluster-type", "custerRequiredClusterType");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "cluster-local-threshold", "clusterLocalThresholdMS");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "cluster-server-selection-timeout",
"clusterServerSelectionTimeoutMS");
// Connection Pool Settings
setPropertyValue(clientOptionsDefBuilder, settingsElement, "connection-pool-max-size", "poolMaxSize");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "connection-pool-min-size", "poolMinSize");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "connection-pool-max-wait-time", "poolMaxWaitTimeMS");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "connection-pool-max-connection-life-time",
"poolMaxConnectionLifeTimeMS");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "connection-pool-max-connection-idle-time",
"poolMaxConnectionIdleTimeMS");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "connection-pool-maintenance-initial-delay",
"poolMaintenanceInitialDelayMS");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "connection-pool-maintenance-frequency",
"poolMaintenanceFrequencyMS");
// SSL Settings
setPropertyValue(clientOptionsDefBuilder, settingsElement, "ssl-enabled", "sslEnabled");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "ssl-invalid-host-name-allowed",
"sslInvalidHostNameAllowed");
setPropertyValue(clientOptionsDefBuilder, settingsElement, "ssl-provider", "sslProvider");
// Field level encryption
setPropertyReference(clientOptionsDefBuilder, settingsElement, "encryption-settings-ref", "autoEncryptionSettings");
// and the rest
mongoClientBuilder.addPropertyValue("mongoClientSettings", clientOptionsDefBuilder.getBeanDefinition());
return true;
}
@@ -118,6 +136,24 @@ abstract class MongoParsingUtils {
return builder;
}
/**
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
* {@link ReadConcernPropertyEditor}.
*
* @return
* @since 3.0
*/
static BeanDefinitionBuilder getReadConcernPropertyEditorBuilder() {
Map<String, Class<?>> customEditors = new ManagedMap<>();
customEditors.put("com.mongodb.ReadConcern", ReadConcernPropertyEditor.class);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
builder.addPropertyValue("customEditors", customEditors);
return builder;
}
/**
* One should only register one bean definition but want to have the convenience of using
* AbstractSingleBeanDefinitionParser but have the side effect of registering a 'default' property editor with the
@@ -125,7 +161,7 @@ abstract class MongoParsingUtils {
*/
static BeanDefinitionBuilder getServerAddressPropertyEditorBuilder() {
Map<String, String> customEditors = new ManagedMap<String, String>();
Map<String, String> customEditors = new ManagedMap<>();
customEditors.put("com.mongodb.ServerAddress[]",
"org.springframework.data.mongodb.config.ServerAddressPropertyEditor");
@@ -143,7 +179,7 @@ abstract class MongoParsingUtils {
*/
static BeanDefinitionBuilder getReadPreferencePropertyEditorBuilder() {
Map<String, Class<?>> customEditors = new ManagedMap<String, Class<?>>();
Map<String, Class<?>> customEditors = new ManagedMap<>();
customEditors.put("com.mongodb.ReadPreference", ReadPreferencePropertyEditor.class);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
@@ -169,4 +205,41 @@ abstract class MongoParsingUtils {
return builder;
}
/**
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
* {@link ConnectionStringPropertyEditor}.
*
* @return
* @since 3.0
*/
static BeanDefinitionBuilder getConnectionStringPropertyEditorBuilder() {
Map<String, Class<?>> customEditors = new ManagedMap<>();
customEditors.put("com.mongodb.ConnectionString", ConnectionStringPropertyEditor.class);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
builder.addPropertyValue("customEditors", customEditors);
return builder;
}
/**
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
* {@link ConnectionStringPropertyEditor}.
*
* @return
* @since 3.0
*/
static BeanDefinitionBuilder getUUidRepresentationEditorBuilder() {
Map<String, Class<?>> customEditors = new ManagedMap<>();
customEditors.put("org.bson.UuidRepresentation", UUidRepresentationPropertyEditor.class);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
builder.addPropertyValue("customEditors", customEditors);
return builder;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2020-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.config;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
/**
* Simple helper to be able to wire the {@link PersistentEntities} from a {@link MappingMongoConverter} bean available
* in the application context.
*
* @author Oliver Gierke
* @author Mark Paluch
* @author Christoph Strobl
* @since 3.1
*/
class PersistentEntitiesFactoryBean implements FactoryBean<PersistentEntities> {
private final MappingMongoConverter converter;
/**
* Creates a new {@link PersistentEntitiesFactoryBean} for the given {@link MappingMongoConverter}.
*
* @param converter must not be {@literal null}.
*/
public PersistentEntitiesFactoryBean(MappingMongoConverter converter) {
this.converter = converter;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
@Override
public PersistentEntities getObject() {
return PersistentEntities.of(converter.getMappingContext());
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
@Override
public Class<?> getObjectType() {
return PersistentEntities.class;
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2020-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.config;
import java.lang.annotation.Annotation;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.auditing.ReactiveIsNewAwareAuditingHandler;
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
import org.springframework.data.auditing.config.AuditingConfiguration;
import org.springframework.data.config.ParsingUtils;
import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback;
import org.springframework.util.Assert;
/**
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableReactiveMongoAuditing} annotation.
*
* @author Mark Paluch
* @since 3.1
*/
class ReactiveMongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation()
*/
@Override
protected Class<? extends Annotation> getAnnotation() {
return EnableReactiveMongoAuditing.class;
}
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName()
*/
@Override
protected String getAuditingHandlerBeanName() {
return "reactiveMongoAuditingHandler";
}
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration)
*/
@Override
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveIsNewAwareAuditingHandler.class);
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntitiesFactoryBean.class);
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
builder.addConstructorArgValue(definition.getBeanDefinition());
return configureDefaultAuditHandlerAttributes(configuration, builder);
}
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListener(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry)
*/
@Override
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
BeanDefinitionRegistry registry) {
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!");
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class);
builder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
builder.getRawBeanDefinition().setSource(auditingHandlerDefinition.getSource());
registerInfrastructureBeanWithId(builder.getBeanDefinition(), ReactiveAuditingEntityCallback.class.getName(),
registry);
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.config;
import java.beans.PropertyEditorSupport;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import com.mongodb.ReadConcern;
import com.mongodb.ReadConcernLevel;
/**
* Parse a {@link String} to a {@link ReadConcern}. If it is a well know {@link String} as identified by the
* {@link ReadConcernLevel#fromString(String)}.
*
* @author Christoph Strobl
* @since 3.0
*/
public class ReadConcernPropertyEditor extends PropertyEditorSupport {
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
*/
@Override
public void setAsText(@Nullable String readConcernString) {
if (!StringUtils.hasText(readConcernString)) {
return;
}
setValue(new ReadConcern(ReadConcernLevel.fromString(readConcernString)));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2020-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.config;
import java.beans.PropertyEditorSupport;
import org.bson.UuidRepresentation;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
* Parse a {@link String} to a {@link UuidRepresentation}.
*
* @author Christoph Strobl
* @since 3.0
*/
public class UUidRepresentationPropertyEditor extends PropertyEditorSupport {
/*
* (non-Javadoc)
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
*/
@Override
public void setAsText(@Nullable String value) {
if (!StringUtils.hasText(value)) {
return;
}
setValue(UuidRepresentation.valueOf(value));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ import com.mongodb.WriteConcern;
public class WriteConcernPropertyEditor extends PropertyEditorSupport {
/**
* Parse a string to a List<ServerAddress>
* Parse a string to a {@link WriteConcern}.
*/
@Override
public void setAsText(@Nullable String writeConcernString) {
@@ -51,6 +51,5 @@ public class WriteConcernPropertyEditor extends PropertyEditorSupport {
// pass on the string to the constructor
setValue(new WriteConcern(writeConcernString));
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,6 @@
*/
package org.springframework.data.mongodb.core;
import lombok.AllArgsConstructor;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -30,6 +28,7 @@ import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
import org.springframework.data.mongodb.core.aggregation.CountOperation;
import org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext;
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.convert.QueryMapper;
@@ -49,12 +48,18 @@ import org.springframework.util.ObjectUtils;
* @author Mark Paluch
* @since 2.1
*/
@AllArgsConstructor
class AggregationUtil {
QueryMapper queryMapper;
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
AggregationUtil(QueryMapper queryMapper,
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
this.queryMapper = queryMapper;
this.mappingContext = mappingContext;
}
/**
* Prepare the {@link AggregationOperationContext} for a given aggregation by either returning the context itself it
* is not {@literal null}, create a {@link TypeBasedAggregationOperationContext} if the aggregation contains type
@@ -71,12 +76,17 @@ class AggregationUtil {
return context;
}
if (aggregation instanceof TypedAggregation) {
return new TypeBasedAggregationOperationContext(((TypedAggregation) aggregation).getInputType(), mappingContext,
queryMapper);
if (!(aggregation instanceof TypedAggregation)) {
return new RelaxedTypeBasedAggregationOperationContext(Object.class, mappingContext, queryMapper);
}
return Aggregation.DEFAULT_CONTEXT;
Class<?> inputType = ((TypedAggregation) aggregation).getInputType();
if (aggregation.getPipeline().containsUnionWith()) {
return new RelaxedTypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper);
}
return new TypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper);
}
/**
@@ -88,7 +98,7 @@ class AggregationUtil {
*/
List<Document> createPipeline(Aggregation aggregation, AggregationOperationContext context) {
if (!ObjectUtils.nullSafeEquals(context, Aggregation.DEFAULT_CONTEXT)) {
if (ObjectUtils.nullSafeEquals(context, Aggregation.DEFAULT_CONTEXT)) {
return aggregation.toPipeline(context);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -94,7 +94,6 @@ public interface BulkOperations {
* Add a list of updates to the bulk operation. For each update request, all matching documents are updated.
*
* @param updates Update operations to perform.
* @return The bulk operation.
* @return the current {@link BulkOperations} instance with the update added, will never be {@literal null}.
*/
BulkOperations updateMulti(List<Pair<Query, Update>> updates);
@@ -105,7 +104,6 @@ public interface BulkOperations {
*
* @param query Update criteria.
* @param update Update operation to perform.
* @return The bulk operation.
* @return the current {@link BulkOperations} instance with the update added, will never be {@literal null}.
*/
BulkOperations upsert(Query query, Update update);
@@ -115,7 +113,6 @@ public interface BulkOperations {
* else an insert.
*
* @param updates Updates/insert operations to perform.
* @return The bulk operation.
* @return the current {@link BulkOperations} instance with the update added, will never be {@literal null}.
*/
BulkOperations upsert(List<Pair<Query, Update>> updates);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,6 @@
*/
package org.springframework.data.mongodb.core;
import lombok.EqualsAndHashCode;
import java.time.Instant;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -27,6 +25,7 @@ import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.messaging.Message;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import com.mongodb.client.model.changestream.ChangeStreamDocument;
import com.mongodb.client.model.changestream.OperationType;
@@ -39,7 +38,6 @@ import com.mongodb.client.model.changestream.OperationType;
* @author Mark Paluch
* @since 2.1
*/
@EqualsAndHashCode
public class ChangeStreamEvent<T> {
@SuppressWarnings("rawtypes") //
@@ -187,8 +185,8 @@ public class ChangeStreamEvent<T> {
return CONVERTED_UPDATER.compareAndSet(this, null, result) ? result : CONVERTED_UPDATER.get(this);
}
throw new IllegalArgumentException(String.format("No converter found capable of converting %s to %s",
fullDocument.getClass(), targetType));
throw new IllegalArgumentException(
String.format("No converter found capable of converting %s to %s", fullDocument.getClass(), targetType));
}
/*
@@ -199,4 +197,27 @@ public class ChangeStreamEvent<T> {
public String toString() {
return "ChangeStreamEvent {" + "raw=" + raw + ", targetType=" + targetType + '}';
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ChangeStreamEvent<?> that = (ChangeStreamEvent<?>) o;
if (!ObjectUtils.nullSafeEquals(this.raw, that.raw)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.targetType, that.targetType);
}
@Override
public int hashCode() {
int result = raw != null ? raw.hashCode() : 0;
result = 31 * result + ObjectUtils.nullSafeHashCode(targetType);
return result;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,6 @@
*/
package org.springframework.data.mongodb.core;
import lombok.EqualsAndHashCode;
import java.time.Instant;
import java.util.Arrays;
import java.util.Optional;
@@ -25,7 +23,6 @@ import org.bson.BsonDocument;
import org.bson.BsonTimestamp;
import org.bson.BsonValue;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.lang.Nullable;
@@ -45,7 +42,6 @@ import com.mongodb.client.model.changestream.FullDocument;
* @author Mark Paluch
* @since 2.1
*/
@EqualsAndHashCode
public class ChangeStreamOptions {
private @Nullable Object filter;
@@ -156,6 +152,44 @@ public class ChangeStreamOptions {
+ ObjectUtils.nullSafeClassName(timestamp));
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ChangeStreamOptions that = (ChangeStreamOptions) o;
if (!ObjectUtils.nullSafeEquals(this.filter, that.filter)) {
return false;
}
if (!ObjectUtils.nullSafeEquals(this.resumeToken, that.resumeToken)) {
return false;
}
if (!ObjectUtils.nullSafeEquals(this.fullDocumentLookup, that.fullDocumentLookup)) {
return false;
}
if (!ObjectUtils.nullSafeEquals(this.collation, that.collation)) {
return false;
}
if (!ObjectUtils.nullSafeEquals(this.resumeTimestamp, that.resumeTimestamp)) {
return false;
}
return resume == that.resume;
}
@Override
public int hashCode() {
int result = ObjectUtils.nullSafeHashCode(filter);
result = 31 * result + ObjectUtils.nullSafeHashCode(resumeToken);
result = 31 * result + ObjectUtils.nullSafeHashCode(fullDocumentLookup);
result = 31 * result + ObjectUtils.nullSafeHashCode(collation);
result = 31 * result + ObjectUtils.nullSafeHashCode(resumeTimestamp);
result = 31 * result + ObjectUtils.nullSafeHashCode(resume);
return result;
}
/**
* @author Christoph Strobl
* @since 2.2

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 the original author or authors.
* Copyright 2010-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import com.mongodb.client.MongoCollection;
* @author Grame Rocher
* @author Oliver Gierke
* @author John Brisbin
* @auhtor Christoph Strobl
* @author Christoph Strobl
* @since 1.0
*/
public interface CollectionCallback<T> {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 the original author or authors.
* Copyright 2010-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,6 @@
*/
package org.springframework.data.mongodb.core;
import lombok.RequiredArgsConstructor;
import java.util.Optional;
import org.springframework.data.mongodb.core.query.Collation;
@@ -95,7 +93,7 @@ public class CollectionOptions {
/**
* Create new {@link CollectionOptions} with already given settings and capped set to {@literal true}. <br />
* <strong>NOTE</strong> Using capped collections requires defining {@link #size(int)}.
* <strong>NOTE</strong> Using capped collections requires defining {@link #size(long)}.
*
* @return new {@link CollectionOptions}.
* @since 2.0
@@ -312,7 +310,6 @@ public class CollectionOptions {
* @author Andreas Zink
* @since 2.1
*/
@RequiredArgsConstructor
public static class ValidationOptions {
private static final ValidationOptions NONE = new ValidationOptions(null, null, null);
@@ -321,6 +318,13 @@ public class CollectionOptions {
private final @Nullable ValidationLevel validationLevel;
private final @Nullable ValidationAction validationAction;
public ValidationOptions(Validator validator, ValidationLevel validationLevel, ValidationAction validationAction) {
this.validator = validator;
this.validationLevel = validationLevel;
this.validationAction = validationAction;
}
/**
* Create an empty {@link ValidationOptions}.
*

View File

@@ -0,0 +1,227 @@
/*
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.core;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.bson.Document;
import org.springframework.data.geo.Point;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
* Value object representing a count query. Count queries using {@code $near} or {@code $nearSphere} require a rewrite
* to {@code $geoWithin}.
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 3.0
*/
class CountQuery {
private Document source;
private CountQuery(Document source) {
this.source = source;
}
public static CountQuery of(Document source) {
return new CountQuery(source);
}
/**
* Returns the query {@link Document} that can be used with {@code countDocuments()}. Potentially rewrites the query
* to be usable with {@code countDocuments()}.
*
* @return the query {@link Document} that can be used with {@code countDocuments()}.
*/
public Document toQueryDocument() {
if (!requiresRewrite(source)) {
return source;
}
Document target = new Document();
for (Map.Entry<String, Object> entry : source.entrySet()) {
if (entry.getValue() instanceof Document && requiresRewrite(entry.getValue())) {
Document theValue = (Document) entry.getValue();
target.putAll(createGeoWithin(entry.getKey(), theValue, source.get("$and")));
continue;
}
if (entry.getValue() instanceof Collection && requiresRewrite(entry.getValue())) {
Collection<?> source = (Collection<?>) entry.getValue();
target.put(entry.getKey(), rewriteCollection(source));
continue;
}
if ("$and".equals(entry.getKey()) && target.containsKey("$and")) {
// Expect $and to be processed with Document and createGeoWithin.
continue;
}
target.put(entry.getKey(), entry.getValue());
}
return target;
}
/**
* @param valueToInspect
* @return {@code true} if the enclosing element needs to be rewritten.
*/
private boolean requiresRewrite(Object valueToInspect) {
if (valueToInspect instanceof Document) {
return requiresRewrite((Document) valueToInspect);
}
if (valueToInspect instanceof Collection) {
return requiresRewrite((Collection) valueToInspect);
}
return false;
}
private boolean requiresRewrite(Collection<?> collection) {
for (Object o : collection) {
if (o instanceof Document && requiresRewrite((Document) o)) {
return true;
}
}
return false;
}
private boolean requiresRewrite(Document document) {
if (containsNear(document)) {
return true;
}
for (Object entry : document.values()) {
if (requiresRewrite(entry)) {
return true;
}
}
return false;
}
private Collection<Object> rewriteCollection(Collection<?> source) {
Collection<Object> rewrittenCollection = new ArrayList<>(source.size());
for (Object item : source) {
if (item instanceof Document && requiresRewrite(item)) {
rewrittenCollection.add(CountQuery.of((Document) item).toQueryDocument());
} else {
rewrittenCollection.add(item);
}
}
return rewrittenCollection;
}
/**
* Rewrite the near query for field {@code key} to {@code $geoWithin}.
*
* @param key the queried field.
* @param source source {@link Document}.
* @param $and potentially existing {@code $and} condition.
* @return the rewritten query {@link Document}.
*/
private static Document createGeoWithin(String key, Document source, @Nullable Object $and) {
boolean spheric = source.containsKey("$nearSphere");
Object $near = spheric ? source.get("$nearSphere") : source.get("$near");
Number maxDistance = source.containsKey("$maxDistance") ? (Number) source.get("$maxDistance") : Double.MAX_VALUE;
List<Object> $centerMax = Arrays.asList(toCenterCoordinates($near), maxDistance);
Document $geoWithinMax = new Document("$geoWithin",
new Document(spheric ? "$centerSphere" : "$center", $centerMax));
if (!containsNearWithMinDistance(source)) {
return new Document(key, $geoWithinMax);
}
Number minDistance = (Number) source.get("$minDistance");
List<Object> $centerMin = Arrays.asList(toCenterCoordinates($near), minDistance);
Document $geoWithinMin = new Document("$geoWithin",
new Document(spheric ? "$centerSphere" : "$center", $centerMin));
List<Document> criteria = new ArrayList<>();
if ($and != null) {
if ($and instanceof Collection) {
criteria.addAll((Collection) $and);
} else {
throw new IllegalArgumentException(
"Cannot rewrite query as it contains an '$and' element that is not a Collection!: Offending element: "
+ $and);
}
}
criteria.add(new Document("$nor", Collections.singletonList(new Document(key, $geoWithinMin))));
criteria.add(new Document(key, $geoWithinMax));
return new Document("$and", criteria);
}
private static boolean containsNear(Document source) {
return source.containsKey("$near") || source.containsKey("$nearSphere");
}
private static boolean containsNearWithMinDistance(Document source) {
if (!containsNear(source)) {
return false;
}
return source.containsKey("$minDistance");
}
private static Object toCenterCoordinates(Object value) {
if (ObjectUtils.isArray(value)) {
return value;
}
if (value instanceof Point) {
return Arrays.asList(((Point) value).getX(), ((Point) value).getY());
}
if (value instanceof Document && ((Document) value).containsKey("x")) {
Document point = (Document) value;
return Arrays.asList(point.get("x"), point.get("y"));
}
return value;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,9 +43,10 @@ public interface CursorPreparer extends ReadPreferenceAware {
/**
* Prepare the given cursor (apply limits, skips and so on). Returns the prepared cursor.
*
* @param cursor
* @param iterable must not be {@literal null}.
* @return never {@literal null}.
*/
FindIterable<Document> prepare(FindIterable<Document> cursor);
FindIterable<Document> prepare(FindIterable<Document> iterable);
/**
* Apply query specific settings to {@link MongoCollection} and initate a find operation returning a
@@ -53,7 +54,7 @@ public interface CursorPreparer extends ReadPreferenceAware {
*
* @param collection must not be {@literal null}.
* @param find must not be {@literal null}.
* @return
* @return never {@literal null}.
* @throws IllegalArgumentException if one of the required arguments is {@literal null}.
* @since 2.2
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 the original author or authors.
* Copyright 2010-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,11 +24,13 @@ import java.util.stream.Collectors;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.mapping.callback.EntityCallbacks;
import org.springframework.data.mongodb.BulkOperationException;
import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.convert.UpdateMapper;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.event.AfterSaveCallback;
import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertCallback;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
@@ -38,18 +40,19 @@ import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent;
import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.core.query.UpdateDefinition;
import org.springframework.data.mongodb.core.query.UpdateDefinition.ArrayFilter;
import org.springframework.data.util.Pair;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.mongodb.MongoBulkWriteException;
import com.mongodb.WriteConcern;
import com.mongodb.bulk.BulkWriteResult;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.*;
import lombok.NonNull;
import lombok.Value;
/**
* Default implementation for {@link BulkOperations}.
*
@@ -60,6 +63,8 @@ import lombok.Value;
* @author Minsu Kim
* @author Jens Schauder
* @author Michail Nikolaev
* @author Roman Puchkovskiy
* @author Jacob Botuck
* @since 1.9
*/
class DefaultBulkOperations implements BulkOperations {
@@ -69,7 +74,6 @@ class DefaultBulkOperations implements BulkOperations {
private final BulkOperationContext bulkOperationContext;
private final List<SourceAwareWriteModelHolder> models = new ArrayList<>();
private PersistenceExceptionTranslator exceptionTranslator;
private @Nullable WriteConcern defaultWriteConcern;
private BulkWriteOptions bulkOptions;
@@ -93,19 +97,9 @@ class DefaultBulkOperations implements BulkOperations {
this.mongoOperations = mongoOperations;
this.collectionName = collectionName;
this.bulkOperationContext = bulkOperationContext;
this.exceptionTranslator = new MongoExceptionTranslator();
this.bulkOptions = getBulkWriteOptions(bulkOperationContext.getBulkMode());
}
/**
* Configures the {@link PersistenceExceptionTranslator} to be used. Defaults to {@link MongoExceptionTranslator}.
*
* @param exceptionTranslator can be {@literal null}.
*/
public void setExceptionTranslator(@Nullable PersistenceExceptionTranslator exceptionTranslator) {
this.exceptionTranslator = exceptionTranslator == null ? new MongoExceptionTranslator() : exceptionTranslator;
}
/**
* Configures the default {@link WriteConcern} to be used. Defaults to {@literal null}.
*
@@ -298,6 +292,7 @@ class DefaultBulkOperations implements BulkOperations {
Assert.state(result != null, "Result must not be null.");
models.forEach(this::maybeEmitAfterSaveEvent);
models.forEach(this::maybeInvokeAfterSaveCallback);
return result;
} finally {
@@ -311,11 +306,26 @@ class DefaultBulkOperations implements BulkOperations {
collection = collection.withWriteConcern(defaultWriteConcern);
}
return collection.bulkWrite( //
models.stream() //
.map(this::extractAndMapWriteModel) //
.collect(Collectors.toList()), //
bulkOptions);
try {
return collection.bulkWrite( //
models.stream() //
.map(this::extractAndMapWriteModel) //
.collect(Collectors.toList()), //
bulkOptions);
} catch (RuntimeException ex) {
if (ex instanceof MongoBulkWriteException) {
MongoBulkWriteException mongoBulkWriteException = (MongoBulkWriteException) ex;
if (mongoBulkWriteException.getWriteConcernError() != null) {
throw new DataIntegrityViolationException(ex.getMessage(), ex);
}
throw new BulkOperationException(ex.getMessage(), mongoBulkWriteException);
}
throw ex;
}
}
private WriteModel<Document> extractAndMapWriteModel(SourceAwareWriteModelHolder it) {
@@ -349,9 +359,7 @@ class DefaultBulkOperations implements BulkOperations {
Assert.notNull(query, "Query must not be null!");
Assert.notNull(update, "Update must not be null!");
UpdateOptions options = new UpdateOptions();
options.upsert(upsert);
query.getCollation().map(Collation::toMongoCollation).ifPresent(options::collation);
UpdateOptions options = computeUpdateOptions(query, update, upsert);
if (multi) {
addModel(update, new UpdateManyModel<>(query.getQueryObject(), update.getUpdateObject(), options));
@@ -421,38 +429,52 @@ class DefaultBulkOperations implements BulkOperations {
models.add(new SourceAwareWriteModelHolder(source, model));
}
private void maybeEmitBeforeSaveEvent(SourceAwareWriteModelHolder it) {
private void maybeEmitBeforeSaveEvent(SourceAwareWriteModelHolder holder) {
if (it.getModel() instanceof InsertOneModel) {
if (holder.getModel() instanceof InsertOneModel) {
Document target = ((InsertOneModel<Document>) it.getModel()).getDocument();
maybeEmitEvent(new BeforeSaveEvent<>(it.getSource(), target, collectionName));
} else if (it.getModel() instanceof ReplaceOneModel) {
Document target = ((InsertOneModel<Document>) holder.getModel()).getDocument();
maybeEmitEvent(new BeforeSaveEvent<>(holder.getSource(), target, collectionName));
} else if (holder.getModel() instanceof ReplaceOneModel) {
Document target = ((ReplaceOneModel<Document>) it.getModel()).getReplacement();
maybeEmitEvent(new BeforeSaveEvent<>(it.getSource(), target, collectionName));
Document target = ((ReplaceOneModel<Document>) holder.getModel()).getReplacement();
maybeEmitEvent(new BeforeSaveEvent<>(holder.getSource(), target, collectionName));
}
}
private void maybeEmitAfterSaveEvent(SourceAwareWriteModelHolder it) {
private void maybeEmitAfterSaveEvent(SourceAwareWriteModelHolder holder) {
if (it.getModel() instanceof InsertOneModel) {
if (holder.getModel() instanceof InsertOneModel) {
Document target = ((InsertOneModel<Document>) it.getModel()).getDocument();
maybeEmitEvent(new AfterSaveEvent<>(it.getSource(), target, collectionName));
} else if (it.getModel() instanceof ReplaceOneModel) {
Document target = ((InsertOneModel<Document>) holder.getModel()).getDocument();
maybeEmitEvent(new AfterSaveEvent<>(holder.getSource(), target, collectionName));
} else if (holder.getModel() instanceof ReplaceOneModel) {
Document target = ((ReplaceOneModel<Document>) it.getModel()).getReplacement();
maybeEmitEvent(new AfterSaveEvent<>(it.getSource(), target, collectionName));
Document target = ((ReplaceOneModel<Document>) holder.getModel()).getReplacement();
maybeEmitEvent(new AfterSaveEvent<>(holder.getSource(), target, collectionName));
}
}
private void maybeInvokeAfterSaveCallback(SourceAwareWriteModelHolder holder) {
if (holder.getModel() instanceof InsertOneModel) {
Document target = ((InsertOneModel<Document>) holder.getModel()).getDocument();
maybeInvokeAfterSaveCallback(holder.getSource(), target);
} else if (holder.getModel() instanceof ReplaceOneModel) {
Document target = ((ReplaceOneModel<Document>) holder.getModel()).getReplacement();
maybeInvokeAfterSaveCallback(holder.getSource(), target);
}
}
private <E extends MongoMappingEvent<T>, T> E maybeEmitEvent(E event) {
if (null != bulkOperationContext.getEventPublisher()) {
bulkOperationContext.getEventPublisher().publishEvent(event);
if (bulkOperationContext.getEventPublisher() == null) {
return event;
}
bulkOperationContext.getEventPublisher().publishEvent(event);
return event;
}
@@ -475,6 +497,16 @@ class DefaultBulkOperations implements BulkOperations {
collectionName);
}
private Object maybeInvokeAfterSaveCallback(Object value, Document mappedDocument) {
if (bulkOperationContext.getEntityCallbacks() == null) {
return value;
}
return bulkOperationContext.getEntityCallbacks().callback(AfterSaveCallback.class, value, mappedDocument,
collectionName);
}
private static BulkWriteOptions getBulkWriteOptions(BulkMode bulkMode) {
BulkWriteOptions options = new BulkWriteOptions();
@@ -489,6 +521,29 @@ class DefaultBulkOperations implements BulkOperations {
throw new IllegalStateException("BulkMode was null!");
}
/**
* @param filterQuery The {@link Query} to read a potential {@link Collation} from. Must not be {@literal null}.
* @param update The {@link Update} to apply
* @param upsert flag to indicate if document should be upserted.
* @return new instance of {@link UpdateOptions}.
*/
private static UpdateOptions computeUpdateOptions(Query filterQuery, UpdateDefinition update, boolean upsert) {
UpdateOptions options = new UpdateOptions();
options.upsert(upsert);
if (update.hasArrayFilters()) {
List<Document> list = new ArrayList<>(update.getArrayFilters().size());
for (ArrayFilter arrayFilter : update.getArrayFilters()) {
list.add(arrayFilter.asDocument());
}
options.arrayFilters(list);
}
filterQuery.getCollation().map(Collation::toMongoCollation).ifPresent(options::collation);
return options;
}
/**
* {@link BulkOperationContext} holds information about
* {@link org.springframework.data.mongodb.core.BulkOperations.BulkMode} the entity in use as well as references to
@@ -497,15 +552,93 @@ class DefaultBulkOperations implements BulkOperations {
* @author Christoph Strobl
* @since 2.0
*/
@Value
static class BulkOperationContext {
static final class BulkOperationContext {
@NonNull BulkMode bulkMode;
@NonNull Optional<? extends MongoPersistentEntity<?>> entity;
@NonNull QueryMapper queryMapper;
@NonNull UpdateMapper updateMapper;
ApplicationEventPublisher eventPublisher;
EntityCallbacks entityCallbacks;
private final BulkMode bulkMode;
private final Optional<? extends MongoPersistentEntity<?>> entity;
private final QueryMapper queryMapper;
private final UpdateMapper updateMapper;
private final ApplicationEventPublisher eventPublisher;
private final EntityCallbacks entityCallbacks;
BulkOperationContext(BulkOperations.BulkMode bulkMode, Optional<? extends MongoPersistentEntity<?>> entity,
QueryMapper queryMapper, UpdateMapper updateMapper, ApplicationEventPublisher eventPublisher,
EntityCallbacks entityCallbacks) {
this.bulkMode = bulkMode;
this.entity = entity;
this.queryMapper = queryMapper;
this.updateMapper = updateMapper;
this.eventPublisher = eventPublisher;
this.entityCallbacks = entityCallbacks;
}
public BulkMode getBulkMode() {
return this.bulkMode;
}
public Optional<? extends MongoPersistentEntity<?>> getEntity() {
return this.entity;
}
public QueryMapper getQueryMapper() {
return this.queryMapper;
}
public UpdateMapper getUpdateMapper() {
return this.updateMapper;
}
public ApplicationEventPublisher getEventPublisher() {
return this.eventPublisher;
}
public EntityCallbacks getEntityCallbacks() {
return this.entityCallbacks;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
BulkOperationContext that = (BulkOperationContext) o;
if (bulkMode != that.bulkMode)
return false;
if (!ObjectUtils.nullSafeEquals(this.entity, that.entity)) {
return false;
}
if (!ObjectUtils.nullSafeEquals(this.queryMapper, that.queryMapper)) {
return false;
}
if (!ObjectUtils.nullSafeEquals(this.updateMapper, that.updateMapper)) {
return false;
}
if (!ObjectUtils.nullSafeEquals(this.eventPublisher, that.eventPublisher)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.entityCallbacks, that.entityCallbacks);
}
@Override
public int hashCode() {
int result = bulkMode != null ? bulkMode.hashCode() : 0;
result = 31 * result + ObjectUtils.nullSafeHashCode(entity);
result = 31 * result + ObjectUtils.nullSafeHashCode(queryMapper);
result = 31 * result + ObjectUtils.nullSafeHashCode(updateMapper);
result = 31 * result + ObjectUtils.nullSafeHashCode(eventPublisher);
result = 31 * result + ObjectUtils.nullSafeHashCode(entityCallbacks);
return result;
}
public String toString() {
return "DefaultBulkOperations.BulkOperationContext(bulkMode=" + this.getBulkMode() + ", entity="
+ this.getEntity() + ", queryMapper=" + this.getQueryMapper() + ", updateMapper=" + this.getUpdateMapper()
+ ", eventPublisher=" + this.getEventPublisher() + ", entityCallbacks=" + this.getEntityCallbacks() + ")";
}
}
/**
@@ -514,10 +647,50 @@ class DefaultBulkOperations implements BulkOperations {
* @since 2.2
* @author Christoph Strobl
*/
@Value
private static class SourceAwareWriteModelHolder {
private static final class SourceAwareWriteModelHolder {
Object source;
WriteModel<Document> model;
private final Object source;
private final WriteModel<Document> model;
SourceAwareWriteModelHolder(Object source, WriteModel<Document> model) {
this.source = source;
this.model = model;
}
public Object getSource() {
return this.source;
}
public WriteModel<Document> getModel() {
return this.model;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
SourceAwareWriteModelHolder that = (SourceAwareWriteModelHolder) o;
if (!ObjectUtils.nullSafeEquals(this.source, that.source)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.model, that.model);
}
@Override
public int hashCode() {
int result = ObjectUtils.nullSafeHashCode(model);
result = 31 * result + ObjectUtils.nullSafeHashCode(source);
return result;
}
public String toString() {
return "DefaultBulkOperations.SourceAwareWriteModelHolder(source=" + this.getSource() + ", model="
+ this.getModel() + ")";
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import java.util.List;
import org.bson.Document;
import org.springframework.dao.DataAccessException;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.index.IndexDefinition;
import org.springframework.data.mongodb.core.index.IndexInfo;
@@ -64,7 +64,7 @@ public class DefaultIndexOperations implements IndexOperations {
* {@link DefaultIndexOperations#DefaultIndexOperations(MongoOperations, String, Class)}.
*/
@Deprecated
public DefaultIndexOperations(MongoDbFactory mongoDbFactory, String collectionName, QueryMapper queryMapper) {
public DefaultIndexOperations(MongoDatabaseFactory mongoDbFactory, String collectionName, QueryMapper queryMapper) {
this(mongoDbFactory, collectionName, queryMapper, null);
}
@@ -80,7 +80,7 @@ public class DefaultIndexOperations implements IndexOperations {
* {@link DefaultIndexOperations#DefaultIndexOperations(MongoOperations, String, Class)}.
*/
@Deprecated
public DefaultIndexOperations(MongoDbFactory mongoDbFactory, String collectionName, QueryMapper queryMapper,
public DefaultIndexOperations(MongoDatabaseFactory mongoDbFactory, String collectionName, QueryMapper queryMapper,
@Nullable Class<?> type) {
Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null!");
@@ -127,7 +127,7 @@ public class DefaultIndexOperations implements IndexOperations {
indexOptions = addPartialFilterIfPresent(indexOptions, indexDefinition.getIndexOptions(), entity);
indexOptions = addDefaultCollationIfRequired(indexOptions, entity);
Document mappedKeys = mapper.getMappedObject(indexDefinition.getIndexKeys(), entity);
Document mappedKeys = mapper.getMappedSort(indexDefinition.getIndexKeys(), entity);
return collection.createIndex(mappedKeys, indexOptions);
});
}
@@ -223,7 +223,7 @@ public class DefaultIndexOperations implements IndexOperations {
Assert.isInstanceOf(Document.class, sourceOptions.get(PARTIAL_FILTER_EXPRESSION_KEY));
return ops.partialFilterExpression(
mapper.getMappedObject((Document) sourceOptions.get(PARTIAL_FILTER_EXPRESSION_KEY), entity));
mapper.getMappedSort((Document) sourceOptions.get(PARTIAL_FILTER_EXPRESSION_KEY), entity));
}
private static IndexOptions addDefaultCollationIfRequired(IndexOptions ops, MongoPersistentEntity<?> entity) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,13 +15,13 @@
*/
package org.springframework.data.mongodb.core;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.index.IndexOperations;
import org.springframework.data.mongodb.core.index.IndexOperationsProvider;
/**
* {@link IndexOperationsProvider} to obtain {@link IndexOperations} from a given {@link MongoDbFactory}.
* {@link IndexOperationsProvider} to obtain {@link IndexOperations} from a given {@link MongoDatabaseFactory}.
*
* @author Mark Paluch
* @author Christoph Strobl
@@ -29,14 +29,14 @@ import org.springframework.data.mongodb.core.index.IndexOperationsProvider;
*/
class DefaultIndexOperationsProvider implements IndexOperationsProvider {
private final MongoDbFactory mongoDbFactory;
private final MongoDatabaseFactory mongoDbFactory;
private final QueryMapper mapper;
/**
* @param mongoDbFactory must not be {@literal null}.
* @param mapper must not be {@literal null}.
*/
DefaultIndexOperationsProvider(MongoDbFactory mongoDbFactory, QueryMapper mapper) {
DefaultIndexOperationsProvider(MongoDatabaseFactory mongoDbFactory, QueryMapper mapper) {
this.mongoDbFactory = mongoDbFactory;
this.mapper = mapper;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 the original author or authors.
* Copyright 2010-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import com.mongodb.MongoException;
/**
* An interface used by {@link MongoTemplate} for processing documents returned from a MongoDB query on a per-document
* basis. Implementations of this interface perform the actual work of prcoessing each document but don't need to worry
* about exception handling. {@MongoException}s will be caught and translated by the calling MongoTemplate An
* about exception handling. {@link MongoException}s will be caught and translated by the calling MongoTemplate An
* DocumentCallbackHandler is typically stateful: It keeps the result state within the object, to be available later for
* later inspection.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,10 +15,6 @@
*/
package org.springframework.data.mongodb.core;
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
@@ -55,21 +51,24 @@ import org.springframework.util.MultiValueMap;
* @see MongoTemplate
* @see ReactiveMongoTemplate
*/
@RequiredArgsConstructor
class EntityOperations {
private static final String ID_FIELD = "_id";
private final @NonNull MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context;
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context;
EntityOperations(MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) {
this.context = context;
}
/**
* Creates a new {@link Entity} for the given bean.
*
* @param entity must not be {@literal null}.
* @return
* @return new instance of {@link Entity}.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> Entity<T> forEntity(T entity) {
<T> Entity<T> forEntity(T entity) {
Assert.notNull(entity, "Bean must not be null!");
@@ -89,10 +88,10 @@ class EntityOperations {
*
* @param entity must not be {@literal null}.
* @param conversionService must not be {@literal null}.
* @return
* @return new instance of {@link AdaptibleEntity}.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> AdaptibleEntity<T> forEntity(T entity, ConversionService conversionService) {
<T> AdaptibleEntity<T> forEntity(T entity, ConversionService conversionService) {
Assert.notNull(entity, "Bean must not be null!");
Assert.notNull(conversionService, "ConversionService must not be null!");
@@ -108,6 +107,10 @@ class EntityOperations {
return AdaptibleMappedEntity.of(entity, context, conversionService);
}
/**
* @param entityClass should not be null.
* @return the {@link MongoPersistentEntity#getCollection() collection name}.
*/
public String determineCollectionName(@Nullable Class<?> entityClass) {
if (entityClass == null) {
@@ -138,7 +141,7 @@ class EntityOperations {
* {@code _id} if no identifier property can be found.
*
* @param type must not be {@literal null}.
* @return
* @return never {@literal null}.
*/
public String getIdPropertyName(Class<?> type) {
@@ -342,11 +345,14 @@ class EntityOperations {
Number getVersion();
}
@RequiredArgsConstructor
private static class UnmappedEntity<T extends Map<String, Object>> implements AdaptibleEntity<T> {
private final T map;
protected UnmappedEntity(T map) {
this.map = map;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getIdPropertyName()
@@ -456,7 +462,7 @@ class EntityOperations {
private static class SimpleMappedEntity<T extends Map<String, Object>> extends UnmappedEntity<T> {
SimpleMappedEntity(T map) {
protected SimpleMappedEntity(T map) {
super(map);
}
@@ -479,12 +485,19 @@ class EntityOperations {
}
}
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
private static class MappedEntity<T> implements Entity<T> {
private final @NonNull MongoPersistentEntity<?> entity;
private final @NonNull IdentifierAccessor idAccessor;
private final @NonNull PersistentPropertyAccessor<T> propertyAccessor;
private final MongoPersistentEntity<?> entity;
private final IdentifierAccessor idAccessor;
private final PersistentPropertyAccessor<T> propertyAccessor;
protected MappedEntity(MongoPersistentEntity<?> entity, IdentifierAccessor idAccessor,
PersistentPropertyAccessor<T> propertyAccessor) {
this.entity = entity;
this.idAccessor = idAccessor;
this.propertyAccessor = propertyAccessor;
}
private static <T> MappedEntity<T> of(T bean,
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) {
@@ -755,11 +768,12 @@ class EntityOperations {
* {@link TypedOperations} for generic entities that are not represented with {@link PersistentEntity} (e.g. custom
* conversions).
*/
@RequiredArgsConstructor
enum UntypedOperations implements TypedOperations<Object> {
INSTANCE;
UntypedOperations() {}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T> TypedOperations<T> instance() {
return (TypedOperations) INSTANCE;
@@ -794,10 +808,13 @@ class EntityOperations {
*
* @param <T>
*/
@RequiredArgsConstructor
static class TypedEntityOperations<T> implements TypedOperations<T> {
private final @NonNull MongoPersistentEntity<T> entity;
private final MongoPersistentEntity<T> entity;
protected TypedEntityOperations(MongoPersistentEntity<T> entity) {
this.entity = entity;
}
/*
* (non-Javadoc)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -88,9 +88,9 @@ public interface ExecutableAggregationOperation {
/**
* Apply pipeline operations as specified and stream all matching elements. <br />
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link com.mongodb.Cursor}
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link com.mongodb.client.FindIterable}
*
* @return a {@link CloseableIterator} that wraps the a Mongo DB {@link com.mongodb.Cursor} that needs to be closed.
* @return a {@link CloseableIterator} that wraps the a Mongo DB {@link com.mongodb.client.FindIterable} that needs to be closed.
* Never {@literal null}.
*/
CloseableIterator<T> stream();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,16 +15,10 @@
*/
package org.springframework.data.mongodb.core;
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.util.CloseableIterator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -35,10 +29,13 @@ import org.springframework.util.StringUtils;
* @author Mark Paluch
* @since 2.0
*/
@RequiredArgsConstructor
class ExecutableAggregationOperationSupport implements ExecutableAggregationOperation {
private final @NonNull MongoTemplate template;
private final MongoTemplate template;
ExecutableAggregationOperationSupport(MongoTemplate template) {
this.template = template;
}
/*
* (non-Javadoc)
@@ -56,15 +53,21 @@ class ExecutableAggregationOperationSupport implements ExecutableAggregationOper
* @author Christoph Strobl
* @since 2.0
*/
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
static class ExecutableAggregationSupport<T>
implements AggregationWithAggregation<T>, ExecutableAggregation<T>, TerminatingAggregation<T> {
@NonNull MongoTemplate template;
@NonNull Class<T> domainType;
@Nullable Aggregation aggregation;
@Nullable String collection;
private final MongoTemplate template;
private final Class<T> domainType;
private final Aggregation aggregation;
private final String collection;
public ExecutableAggregationSupport(MongoTemplate template, Class<T> domainType, Aggregation aggregation,
String collection) {
this.template = template;
this.domainType = domainType;
this.aggregation = aggregation;
this.collection = collection;
}
/*
* (non-Javadoc)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import java.util.stream.Stream;
import org.springframework.dao.DataAccessException;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.lang.Nullable;
@@ -43,7 +44,7 @@ import com.mongodb.client.MongoCollection;
* query(Human.class)
* .inCollection("star-wars")
* .as(Jedi.class)
* .matching(query(where("firstname").is("luke")))
* .matching(where("firstname").is("luke"))
* .all();
* </code>
* </pre>
@@ -117,13 +118,18 @@ public interface ExecutableFindOperation {
/**
* Stream all matching elements.
*
* @return a {@link Stream} that wraps the a Mongo DB {@link com.mongodb.Cursor} that needs to be closed. Never
* @return a {@link Stream} that wraps the a Mongo DB {@link com.mongodb.client.FindIterable} that needs to be closed. Never
* {@literal null}.
*/
Stream<T> stream();
/**
* Get the number of matching elements.
* <p />
* This method uses an {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) aggregation
* execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees shard,
* session and transaction compliance. In case an inaccurate count satisfies the applications needs use
* {@link MongoOperations#estimatedCount(String)} for empty queries instead.
*
* @return total number of matching elements.
*/
@@ -170,6 +176,18 @@ public interface ExecutableFindOperation {
*/
TerminatingFind<T> matching(Query query);
/**
* Set the filter {@link CriteriaDefinition criteria} to be used.
*
* @param criteria must not be {@literal null}.
* @return new instance of {@link TerminatingFind}.
* @throws IllegalArgumentException if criteria is {@literal null}.
* @since 3.0
*/
default TerminatingFind<T> matching(CriteriaDefinition criteria) {
return matching(Query.query(criteria));
}
/**
* Set the filter query for the geoNear execution.
*
@@ -291,9 +309,21 @@ public interface ExecutableFindOperation {
*
* @param query must not be {@literal null}.
* @return new instance of {@link TerminatingDistinct}.
* @throws IllegalArgumentException if resultType is {@literal null}.
* @throws IllegalArgumentException if query is {@literal null}.
*/
TerminatingDistinct<T> matching(Query query);
/**
* Set the filter {@link CriteriaDefinition criteria} to be used.
*
* @param criteria must not be {@literal null}.
* @return new instance of {@link TerminatingDistinct}.
* @throws IllegalArgumentException if criteria is {@literal null}.
* @since 3.0
*/
default TerminatingDistinct<T> matching(CriteriaDefinition criteria) {
return matching(Query.query(criteria));
}
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,12 +15,6 @@
*/
package org.springframework.data.mongodb.core;
import com.mongodb.ReadPreference;
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
@@ -37,6 +31,7 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.mongodb.ReadPreference;
import com.mongodb.client.FindIterable;
/**
@@ -46,12 +41,15 @@ import com.mongodb.client.FindIterable;
* @author Mark Paluch
* @since 2.0
*/
@RequiredArgsConstructor
class ExecutableFindOperationSupport implements ExecutableFindOperation {
private static final Query ALL_QUERY = new Query();
private final @NonNull MongoTemplate template;
private final MongoTemplate template;
ExecutableFindOperationSupport(MongoTemplate template) {
this.template = template;
}
/*
* (non-Javadoc)
@@ -70,16 +68,23 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
* @author Christoph Strobl
* @since 2.0
*/
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
static class ExecutableFindSupport<T>
implements ExecutableFind<T>, FindWithCollection<T>, FindWithProjection<T>, FindWithQuery<T> {
@NonNull MongoTemplate template;
@NonNull Class<?> domainType;
Class<T> returnType;
@Nullable String collection;
Query query;
private final MongoTemplate template;
private final Class<?> domainType;
private final Class<T> returnType;
@Nullable private final String collection;
private final Query query;
ExecutableFindSupport(MongoTemplate template, Class<?> domainType, Class<T> returnType,
String collection, Query query) {
this.template = template;
this.domainType = domainType;
this.returnType = returnType;
this.collection = collection;
this.query = query;
}
/*
* (non-Javadoc)
@@ -257,9 +262,9 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
* @see org.springframework.data.mongodb.core.CursorPreparer#prepare(com.mongodb.clientFindIterable)
*/
@Override
public FindIterable<Document> prepare(FindIterable<Document> cursor) {
public FindIterable<Document> prepare(FindIterable<Document> iterable) {
FindIterable<Document> target = delegate != null ? delegate.prepare(cursor) : cursor;
FindIterable<Document> target = delegate != null ? delegate.prepare(iterable) : iterable;
return limit.map(target::limit).orElse(target);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,11 +15,6 @@
*/
package org.springframework.data.mongodb.core;
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import java.util.ArrayList;
import java.util.Collection;
@@ -37,10 +32,13 @@ import com.mongodb.bulk.BulkWriteResult;
* @author Mark Paluch
* @since 2.0
*/
@RequiredArgsConstructor
class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
private final @NonNull MongoTemplate template;
private final MongoTemplate template;
ExecutableInsertOperationSupport(MongoTemplate template) {
this.template = template;
}
/*
* (non-Javadoc)
@@ -58,14 +56,20 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
* @author Christoph Strobl
* @since 2.0
*/
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
static class ExecutableInsertSupport<T> implements ExecutableInsert<T> {
@NonNull MongoTemplate template;
@NonNull Class<T> domainType;
@Nullable String collection;
@Nullable BulkMode bulkMode;
private final MongoTemplate template;
private final Class<T> domainType;
@Nullable private final String collection;
@Nullable private final BulkMode bulkMode;
ExecutableInsertSupport(MongoTemplate template, Class<T> domainType, String collection, BulkMode bulkMode) {
this.template = template;
this.domainType = domainType;
this.collection = collection;
this.bulkMode = bulkMode;
}
/*
* (non-Javadoc)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import java.util.List;
import org.springframework.data.mongodb.core.ExecutableFindOperation.ExecutableFind;
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.data.mongodb.core.query.Query;
/**
@@ -30,7 +31,7 @@ import org.springframework.data.mongodb.core.query.Query;
* The collection to operate on is by default derived from the initial {@literal domainType} and can be defined there
* via {@link org.springframework.data.mongodb.core.mapping.Document}. Using {@code inCollection} allows to override the
* collection name for the execution.
*
*
* <pre>
* <code>
* mapReduce(Human.class)
@@ -44,6 +45,7 @@ import org.springframework.data.mongodb.core.query.Query;
* </pre>
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.1
*/
public interface ExecutableMapReduceOperation {
@@ -146,6 +148,18 @@ public interface ExecutableMapReduceOperation {
* @throws IllegalArgumentException if query is {@literal null}.
*/
TerminatingMapReduce<T> matching(Query query);
/**
* Set the filter {@link CriteriaDefinition criteria} to be used.
*
* @param criteria must not be {@literal null}.
* @return new instance of {@link TerminatingMapReduce}.
* @throws IllegalArgumentException if query is {@literal null}.
* @since 3.0
*/
default TerminatingMapReduce<T> matching(CriteriaDefinition criteria) {
return matching(Query.query(criteria));
}
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,6 @@
*/
package org.springframework.data.mongodb.core;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
@@ -32,12 +29,17 @@ import org.springframework.util.StringUtils;
* @author Christoph Strobl
* @since 2.1
*/
@RequiredArgsConstructor
class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperation {
private static final Query ALL_QUERY = new Query();
private final @NonNull MongoTemplate template;
private final MongoTemplate template;
ExecutableMapReduceOperationSupport(MongoTemplate template) {
Assert.notNull(template, "Template must not be null!");
this.template = template;
}
/*
* (non-Javascript)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core;
import java.util.List;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.data.mongodb.core.query.Query;
import com.mongodb.client.result.DeleteResult;
@@ -119,6 +120,18 @@ public interface ExecutableRemoveOperation {
* @throws IllegalArgumentException if query is {@literal null}.
*/
TerminatingRemove<T> matching(Query query);
/**
* Set the filter {@link CriteriaDefinition criteria} to be used.
*
* @param criteria must not be {@literal null}.
* @return new instance of {@link TerminatingRemove}.
* @throws IllegalArgumentException if query is {@literal null}.
* @since 3.0
*/
default TerminatingRemove<T> matching(CriteriaDefinition criteria) {
return matching(Query.query(criteria));
}
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,11 +15,6 @@
*/
package org.springframework.data.mongodb.core;
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import java.util.List;
import org.springframework.data.mongodb.core.query.Query;
@@ -36,12 +31,15 @@ import com.mongodb.client.result.DeleteResult;
* @author Mark Paluch
* @since 2.0
*/
@RequiredArgsConstructor
class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation {
private static final Query ALL_QUERY = new Query();
private final @NonNull MongoTemplate tempate;
private final MongoTemplate tempate;
public ExecutableRemoveOperationSupport(MongoTemplate tempate) {
this.tempate = tempate;
}
/*
* (non-Javadoc)
@@ -59,14 +57,19 @@ class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation {
* @author Christoph Strobl
* @since 2.0
*/
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
static class ExecutableRemoveSupport<T> implements ExecutableRemove<T>, RemoveWithCollection<T> {
@NonNull MongoTemplate template;
@NonNull Class<T> domainType;
Query query;
@Nullable String collection;
private final MongoTemplate template;
private final Class<T> domainType;
private final Query query;
@Nullable private final String collection;
public ExecutableRemoveSupport(MongoTemplate template, Class<T> domainType, Query query, String collection) {
this.template = template;
this.domainType = domainType;
this.query = query;
this.collection = collection;
}
/*
* (non-Javadoc)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,8 +17,11 @@ package org.springframework.data.mongodb.core;
import java.util.Optional;
import org.springframework.data.mongodb.core.aggregation.AggregationUpdate;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.core.query.UpdateDefinition;
import org.springframework.lang.Nullable;
import com.mongodb.client.result.UpdateResult;
@@ -151,13 +154,16 @@ public interface ExecutableUpdateOperation {
interface UpdateWithUpdate<T> {
/**
* Set the {@link Update} to be applied.
* Set the {@link UpdateDefinition} to be applied.
*
* @param update must not be {@literal null}.
* @return new instance of {@link TerminatingUpdate}.
* @throws IllegalArgumentException if update is {@literal null}.
* @since 3.0
* @see Update
* @see AggregationUpdate
*/
TerminatingUpdate<T> apply(Update update);
TerminatingUpdate<T> apply(UpdateDefinition update);
/**
* Specify {@code replacement} object.
@@ -205,6 +211,18 @@ public interface ExecutableUpdateOperation {
* @throws IllegalArgumentException if query is {@literal null}.
*/
UpdateWithUpdate<T> matching(Query query);
/**
* Set the filter {@link CriteriaDefinition criteria} to be used.
*
* @param criteria must not be {@literal null}.
* @return new instance of {@link UpdateWithUpdate}.
* @throws IllegalArgumentException if query is {@literal null}.
* @since 3.0
*/
default UpdateWithUpdate<T> matching(CriteriaDefinition criteria) {
return matching(Query.query(criteria));
}
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,13 +15,8 @@
*/
package org.springframework.data.mongodb.core;
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.core.query.UpdateDefinition;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -35,12 +30,15 @@ import com.mongodb.client.result.UpdateResult;
* @author Mark Paluch
* @since 2.0
*/
@RequiredArgsConstructor
class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
private static final Query ALL_QUERY = new Query();
private final @NonNull MongoTemplate template;
private final MongoTemplate template;
ExecutableUpdateOperationSupport(MongoTemplate template) {
this.template = template;
}
/*
* (non-Javadoc)
@@ -58,28 +56,41 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
* @author Christoph Strobl
* @since 2.0
*/
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
static class ExecutableUpdateSupport<T>
implements ExecutableUpdate<T>, UpdateWithCollection<T>, UpdateWithQuery<T>, TerminatingUpdate<T>,
FindAndReplaceWithOptions<T>, TerminatingFindAndReplace<T>, FindAndReplaceWithProjection<T> {
@NonNull MongoTemplate template;
@NonNull Class domainType;
Query query;
@Nullable Update update;
@Nullable String collection;
@Nullable FindAndModifyOptions findAndModifyOptions;
@Nullable FindAndReplaceOptions findAndReplaceOptions;
@Nullable Object replacement;
@NonNull Class<T> targetType;
private final MongoTemplate template;
private final Class domainType;
private final Query query;
@Nullable private final UpdateDefinition update;
@Nullable private final String collection;
@Nullable private final FindAndModifyOptions findAndModifyOptions;
@Nullable private final FindAndReplaceOptions findAndReplaceOptions;
@Nullable private final Object replacement;
private final Class<T> targetType;
ExecutableUpdateSupport(MongoTemplate template, Class domainType, Query query, UpdateDefinition update,
String collection, FindAndModifyOptions findAndModifyOptions, FindAndReplaceOptions findAndReplaceOptions,
Object replacement, Class<T> targetType) {
this.template = template;
this.domainType = domainType;
this.query = query;
this.update = update;
this.collection = collection;
this.findAndModifyOptions = findAndModifyOptions;
this.findAndReplaceOptions = findAndReplaceOptions;
this.replacement = replacement;
this.targetType = targetType;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.UpdateWithUpdate#apply(Update)
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.UpdateWithUpdate#apply(org.springframework.data.mongodb.core.query.UpdateDefinition)
*/
@Override
public TerminatingUpdate<T> apply(Update update) {
public TerminatingUpdate<T> apply(UpdateDefinition update) {
Assert.notNull(update, "Update must not be null!");

Some files were not shown because too many files have changed in this diff Show More