Compare commits

...

165 Commits

Author SHA1 Message Date
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
991 changed files with 21943 additions and 9166 deletions

View File

@@ -1,8 +1,5 @@
language: java
jdk:
- oraclejdk8
before_install:
- mkdir -p downloads
- mkdir -p var/db var/log
@@ -14,20 +11,22 @@ before_install:
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
jdk:
- openjdk13
- openjdk-ea
matrix:
allow_failures:
- jdk: openjdk-ea
env:
matrix:
- MONGO_VERSION=4.1.10
- MONGO_VERSION=4.0.4
- MONGO_VERSION=3.6.12
- MONGO_VERSION=3.4.20
- MONGO_VERSION=4.2.0
- MONGO_VERSION=4.0.14
- MONGO_VERSION=3.6.16
global:
- PROFILE=ci
addons:
apt:
packages:
- oracle-java8-installer
sudo: false
cache:
@@ -35,4 +34,7 @@ cache:
- $HOME/.m2
- downloads
script: "mvn clean dependency:list test -P${PROFILE} -Dsort"
install: true
script:
- "./mvnw clean dependency:list test -Pjava11 -Dsort -U"

79
Jenkinsfile vendored
View File

@@ -30,42 +30,42 @@ 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 13 + MongoDB 4.2') {
when {
changeset "ci/openjdk13-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-openjdk13-with-mongodb-4.2.0", "ci/openjdk13-mongodb-4.2/")
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
image.push()
}
}
}
}
}
}
stage("test: baseline") {
stage("test: baseline (jdk8)") {
when {
anyOf {
branch 'master'
@@ -74,7 +74,7 @@ pipeline {
}
agent {
docker {
image 'springci/spring-data-openjdk8-with-mongodb-4.2:latest'
image 'springci/spring-data-openjdk8-with-mongodb-4.2.0:latest'
label 'data'
args '-v $HOME:/tmp/jenkins-home'
}
@@ -83,11 +83,11 @@ pipeline {
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 '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 clean dependency:list test -Dsort -U -B'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
@@ -99,7 +99,7 @@ pipeline {
}
}
parallel {
stage("test: mongodb 4.0") {
stage("test: mongodb 4.0 (jdk8)") {
agent {
docker {
image 'springci/spring-data-openjdk8-with-mongodb-4.0:latest'
@@ -111,17 +111,18 @@ pipeline {
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 '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 clean dependency:list test -Dsort -U -B'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw 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'
image 'springci/spring-data-openjdk8-with-mongodb-4.2.0:latest'
label 'data'
args '-v $HOME:/tmp/jenkins-home'
}
@@ -130,11 +131,31 @@ pipeline {
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 '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 clean dependency:list test -Dsort -U -B'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
stage("test: baseline (jdk13)") {
agent {
docker {
image 'springci/spring-data-openjdk13-with-mongodb-4.2.0:latest'
label 'data'
args '-v $HOME:/tmp/jenkins-home'
}
}
options { timeout(time: 30, unit: 'MINUTES') }
steps {
sh 'rm -rf ?'
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 -Pjava11 clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
}

View File

@@ -50,11 +50,11 @@ public class MyService {
@Configuration
@EnableMongoRepositories
class ApplicationConfig extends AbstractMongoConfiguration {
class ApplicationConfig extends AbstractMongoClientConfiguration {
@Override
public MongoClient mongoClient() {
return new MongoClient();
return MongoClients.create();
}
@Override
@@ -94,6 +94,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!

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/openjdk13: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/*;

26
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.0.0.RC1</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.3.0.RC1</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.3.0.RC1</springdata.commons>
<mongo>4.0.1</mongo>
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
<jmh.version>1.19</jmh.version>
</properties>
@@ -127,15 +127,25 @@
<!-- MongoDB -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<artifactId>mongodb-driver-core</artifactId>
<version>${mongo}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-libs-release</id>
<url>https://repo.spring.io/libs-release</url>
<id>spring-libs-milestone</id>
<url>https://repo.spring.io/libs-milestone</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>

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.0.0.RC1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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.0.0.RC1</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.0.0.RC1</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>
@@ -253,6 +250,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 +344,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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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-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;
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
* @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-2020 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(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(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-2020 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
* @throws DataAccessException
* @deprecated since 3.0. Use {@link #getMongoDatabase()} instead.
*/
MongoDatabase getDb() throws DataAccessException;
@Deprecated
default MongoDatabase getDb() throws DataAccessException {
return getMongoDatabase();
}
/**
* Creates a {@link DB} 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
* @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(String)} 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();
}
/**
* 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 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;
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-2020 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-2020 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-2020 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-2020 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-2020 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.
@@ -44,7 +44,7 @@ public interface ReactiveMongoDatabaseFactory extends CodecRegistryProvider {
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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 the original author or authors.
* Copyright 2019-2020 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 2019 the original author or authors.
* Copyright 2019-2020 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-2020 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-2020 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-2020 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 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-2020 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-2020 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-2020 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-2020 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 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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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,6 +20,7 @@ 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;
@@ -31,11 +32,15 @@ import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingSt
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 +80,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 +94,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) {
}
/**
@@ -177,11 +199,35 @@ 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();
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) {
builder.uuidRepresentation(UuidRepresentation.JAVA_LEGACY);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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,48 @@
/*
* Copyright 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 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-2020 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-2020 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-2020 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 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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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,227 @@
/*
* Copyright 2019-2020 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-2020 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-2020 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-2020 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,6 +15,9 @@
*/
package org.springframework.data.mongodb.core;
import lombok.NonNull;
import lombok.Value;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -29,6 +32,7 @@ import org.springframework.data.mapping.callback.EntityCallbacks;
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,6 +42,8 @@ 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;
@@ -47,9 +53,6 @@ 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,7 @@ import lombok.Value;
* @author Minsu Kim
* @author Jens Schauder
* @author Michail Nikolaev
* @author Roman Puchkovskiy
* @since 1.9
*/
class DefaultBulkOperations implements BulkOperations {
@@ -298,6 +302,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 {
@@ -349,9 +354,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 +424,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 +492,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 +516,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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2019 the original author or authors.
* Copyright 2011-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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-2020 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;
@@ -170,6 +171,18 @@ public interface ExecutableFindOperation {
*/
TerminatingFind<T> matching(Query query);
/**
* Set the filter {@link CriteriaDefinition criteria} to be used.
*
* @param criteriaDefinition must not be {@literal null}.
* @return new instance of {@link TerminatingFind}.
* @throws IllegalArgumentException if query is {@literal null}.
* @since 3.0
*/
default TerminatingFind<T> matching(CriteriaDefinition criteriaDefinition) {
return matching(Query.query(criteriaDefinition));
}
/**
* Set the filter query for the geoNear execution.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2020 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-2020 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-2020 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-2020 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 criteriaDefinition 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 criteriaDefinition) {
return matching(Query.query(criteriaDefinition));
}
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 the original author or authors.
* Copyright 2018-2020 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-2020 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 criteriaDefinition 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 criteriaDefinition) {
return matching(Query.query(criteriaDefinition));
}
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2020 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-2020 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 criteriaDefinition 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 criteriaDefinition) {
return matching(Query.query(criteriaDefinition));
}
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2020 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 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;
@@ -67,7 +67,7 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
@NonNull MongoTemplate template;
@NonNull Class domainType;
Query query;
@Nullable Update update;
@Nullable UpdateDefinition update;
@Nullable String collection;
@Nullable FindAndModifyOptions findAndModifyOptions;
@Nullable FindAndReplaceOptions findAndReplaceOptions;
@@ -76,10 +76,10 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
/*
* (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!");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 the original author or authors.
* Copyright 2010-2020 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-2020 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 2016-2019 the original author or authors.
* Copyright 2016-2020 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-2020 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 2016-2019 the original author or authors.
* Copyright 2016-2020 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 2016-2019 the original author or authors.
* Copyright 2016-2020 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.

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