Compare commits

..

67 Commits

Author SHA1 Message Date
Mark Paluch
cec6edfa26 DATAMONGO-1859 - Release version 2.0.4 (Kay SR4). 2018-02-19 19:46:53 +01:00
Mark Paluch
3261936e8a DATAMONGO-1859 - Prepare 2.0.4 (Kay SR4). 2018-02-19 19:46:05 +01:00
Mark Paluch
d2d471d135 DATAMONGO-1859 - Updated changelog. 2018-02-19 19:45:58 +01:00
Mark Paluch
bcd2de000c DATAMONGO-1870 - Polishing.
Extend copyright license years. Slightly reword documentation. Use IntStream and insertAll to create test fixture.

Original pull request: #532.
Related pull request: #531.
2018-02-15 10:56:14 +01:00
Christoph Strobl
c873e49d71 DATAMONGO-1870 - Consider skip/limit on MongoOperations.remove(Query, Class).
We now use _id lookup for remove operations that query with limit or skip parameters. This allows more fine grained control over documents removed.

Original pull request: #532.
Related pull request: #531.
2018-02-15 10:56:05 +01:00
Christoph Strobl
4ebcac19bc DATAMONGO-1860 - Polishing.
Fix references to QuerydslPredicateExecutor.

Original Pull Request: #529
2018-02-14 13:36:17 +01:00
Mark Paluch
78212948bc DATAMONGO-1860 - Polishing.
Fix type references in Javadoc. Change lambdas to method references where applicable.

Original Pull Request: #529
2018-02-14 13:36:17 +01:00
Mark Paluch
38575baec1 DATAMONGO-1860 - Retrieve result count via QuerydslMongoPredicateExecutor only for paging.
We now use AbstractMongodbQuery.fetch() instead of AbstractMongodbQuery.fetchResults() to execute MongoDB queries. fetchResults() executes a find(…) and a count(…) query. Retrieving the record count is an expensive operation in MongoDB and the count is not always required. For regular find(…) method, the count is ignored, for paging the count(…) is only required in certain result/request scenarios.

Original Pull Request: #529
2018-02-14 13:36:17 +01:00
Mark Paluch
f1a3c37a79 DATAMONGO-1865 - Polishing.
Adapt to collection name retrieval during query execution. Slightly reword documentation and JavaDoc.

Original pull request: #530.
2018-02-14 12:01:44 +01:00
Christoph Strobl
c668a47243 DATAMONGO-1865 - Avoid IncorrectResultSizeDataAccessException for derived findFirst/findTop queries.
We now return the first result when executing findFirst/findTop queries. This fixes a glitch introduced in the Kay release throwing IncorrectResultSizeDataAccessException for single entity executions returning more than one result, which is explicitly not the desired behavior in this case.

Original pull request: #530.
2018-02-14 12:01:44 +01:00
Mark Paluch
6a20ddf5a2 DATAMONGO-1871 - Polishing.
Migrate test to AssertJ.

Original pull request: #533.
2018-02-14 11:05:20 +01:00
Christoph Strobl
cec6526543 DATAMONGO-1871 - Fix AggregationExpression aliasing.
We now make sure to allow a nested property alias by setting the target.

Original pull request: #533.
2018-02-14 11:05:17 +01:00
Oliver Gierke
46ea58f3b9 DATAMONGO-1872 - Polishing.
Fixed @since tag for newly introduced method in MongoEntityMetadata.
2018-02-13 12:24:09 +01:00
Oliver Gierke
ebaea8d22f DATAMONGO-1872 - Repository query execution doesn't prematurely fix collection to be queried.
We now avoid calling ….inCollection(…) with a fixed, one-time calculated collection name to make sure we dynamically resolve the collections. That's necessary to make sure SpEL expressions in @Document are evaluated for every query execution.
2018-02-13 12:18:19 +01:00
Christoph Strobl
ed6aaeed25 DATAMONGO-1794 - Updated changelog. 2018-02-06 11:14:01 +01:00
Mark Paluch
89b1b6fbb2 DATAMONGO-1830 - After release cleanups. 2018-01-24 13:46:10 +01:00
Mark Paluch
23769301b5 DATAMONGO-1830 - Prepare next development iteration. 2018-01-24 13:46:08 +01:00
Mark Paluch
3399160acf DATAMONGO-1830 - Release version 2.0.3 (Kay SR3). 2018-01-24 13:21:24 +01:00
Mark Paluch
32a8ee9b31 DATAMONGO-1830 - Prepare 2.0.3 (Kay SR3). 2018-01-24 13:20:39 +01:00
Mark Paluch
17cea70abc DATAMONGO-1830 - Updated changelog. 2018-01-24 13:20:34 +01:00
Mark Paluch
07731c39ba DATAMONGO-1858 - Fix line endings to LF. 2018-01-24 12:57:24 +01:00
Mark Paluch
c5b580b82b DATAMONGO-1829 - Updated changelog. 2018-01-24 12:22:10 +01:00
Mark Paluch
9a1385186e DATAMONGO-1843 - Polishing.
Convert anonymous classes to lambdas. Typo fixes. Migrate test to AssertJ.

Original pull request: #526.
2018-01-23 10:34:46 +01:00
Christoph Strobl
704524d7f4 DATAMONGO-1843 - Fix parameter shadowing in ArrayOperators reduce.
Original pull request: #526.
2018-01-23 10:34:35 +01:00
Christoph Strobl
cc9a3ac8da DATAMONGO-1850 - Polishing.
Remove blank line, add tests and migrate to AssertJ.

Original Pull Request: #527
2018-01-22 16:16:52 +01:00
Mark Paluch
acb68f3ca4 DATAMONGO-1850 - Guard GridFsResource.getContentType() against absent file metadata.
We now consider fall back to GridFS.getContentType() if GridFS metadata is absent to prevent null dereference.

Original Pull Request: #527
2018-01-22 15:14:35 +01:00
Mark Paluch
3088f0469e DATAMONGO-1824 - Polishing.
Move method from AggregationCommandPreparer and AggregationResultPostProcessor to BatchAggregationLoader. Extract field names to constants. Tiny renames to variables. Add unit test for aggregation response without cursor use. Migrate test to AssertJ.

Original pull request: #521.
2017-12-15 14:30:24 +01:00
Christoph Strobl
a1ae04881d DATAMONGO-1824 - Skip tests no longer applicable for MongoDB 3.6.
Original pull request: #521.
2017-12-15 14:25:31 +01:00
Christoph Strobl
6f55c66060 DATAMONGO-1824 - Fix aggregation execution for MongoDB 3.6.
We now send aggregation commands along a cursor batch size for compatibility with MongoDB 3.6 that no longer supports aggregations without cursor. We consume the whole cursor before returning and converting results and omit the 16MB aggregation result limit. For MongoDB versions not supporting aggregation cursors we return results directly.

Original pull request: #521.
2017-12-15 14:25:20 +01:00
Christoph Strobl
f86447bd04 DATAMONGO-1831 - Fix array type conversion for empty source.
We now make sure that we convert empty sources to the corresponding target type. This prevents entity instantiation from failing due to incorrect argument types when invoking the constructor.

Original pull request: #520.
2017-12-02 12:18:55 -08:00
Mark Paluch
1bb4324b2e DATAMONGO-1816 - After release cleanups. 2017-11-27 16:42:54 +01:00
Mark Paluch
856506f121 DATAMONGO-1816 - Prepare next development iteration. 2017-11-27 16:42:52 +01:00
Mark Paluch
2a81dc75a8 DATAMONGO-1816 - Release version 2.0.2 (Kay SR2). 2017-11-27 16:12:34 +01:00
Mark Paluch
58cd4c08ca DATAMONGO-1816 - Prepare 2.0.2 (Kay SR2). 2017-11-27 16:11:21 +01:00
Mark Paluch
344e019143 DATAMONGO-1816 - Updated changelog. 2017-11-27 16:11:15 +01:00
Mark Paluch
918b7e96bb DATAMONGO-1799 - Updated changelog. 2017-11-27 15:58:45 +01:00
Christoph Strobl
fce7a5c1cb DATAMONGO-1818 - Polishing.
Move overlapping/duplicate documentation into one place.

Original Pull Request: #512
2017-11-27 07:53:22 +01:00
Mark Paluch
dbd2de8e0f DATAMONGO-1818 - Reword tailable cursors documentation.
Fix reference to @Tailable annotation. Slightly reword documentation.

Original Pull Request: #512
2017-11-27 07:53:08 +01:00
Mark Paluch
0dbe331ab0 DATAMONGO-1823 - Polishing.
Replace constructor with lombok's RequiredArgsConstructor. Add Nullable annotation. Tiny reformatting. Align license header. Migrate test to AssertJ.

Original pull request: #517.
2017-11-22 14:33:20 +01:00
Christoph Strobl
846ebcd91d DATAMONGO-1823 - Emit ApplicationEvents using projecting find methods.
We now again emit application events when using finder methods that apply projection.

Original pull request: #517.
2017-11-22 14:33:20 +01:00
Oliver Gierke
9e0b5caeac DATAMONGO-1737 - BasicMongoPersistentEntity now correctly initializes comparator.
In BasicMongoPersistentEntity.verify() we now properly call the super method to make sure the comparators that honor the @Field's order value are initialized properly.
2017-11-17 14:55:00 +01:00
Mark Paluch
cf70f5e5eb DATAMONGO-1819 - Polishing.
Use native field names for NamedMongoScript query instead of relying on metadata-based mapping as NamedMongoScript is considered a simple top-level type.

Related pull request: #513.
2017-11-17 13:49:06 +01:00
Mark Paluch
331dc6df6f DATAMONGO-1821 - Fix method ambiguity in tests when compiling against MongoDB 3.6 2017-11-07 12:47:51 +01:00
Mark Paluch
a51dce2c90 DATAMONGO-1820 - Set Mongo's Feature Compatibility flag for TravisCI build to 3.4.
Apply setFeatureCompatibilityVersion to upgrade MongoDB to 3.4 features.
2017-11-06 10:28:10 +01:00
Mark Paluch
c0cf1aa95b DATAMONGO-1817 - Polishing.
Remove blank line.

Original pull request: #510.
2017-11-06 10:02:35 +01:00
Sola
7104ffa543 DATAMONGO-1817 - Align nullability in Kotlin MongoOperationsExtensions with Java API.
Return types in MongoOperationsExtensions are now aligned to the nullability of MongoOperations.

Original pull request: #510.
2017-11-06 10:02:35 +01:00
Oliver Gierke
28d2fb6680 DATAMONGO-1793 - After release cleanups. 2017-10-27 15:50:48 +02:00
Oliver Gierke
140e26946f DATAMONGO-1793 - Prepare next development iteration. 2017-10-27 15:50:45 +02:00
Oliver Gierke
f4e730ce87 DATAMONGO-1793 - Release version 2.0.1 (Kay SR1). 2017-10-27 15:25:11 +02:00
Oliver Gierke
e3a83ebc42 DATAMONGO-1793 - Prepare 2.0.1 (Kay SR1). 2017-10-27 15:24:24 +02:00
Oliver Gierke
f65c1e324e DATAMONGO-1793 - Updated changelog. 2017-10-27 15:24:14 +02:00
Oliver Gierke
1dd0061f03 DATAMONGO-1815 - Adapt API changes in Property in test cases. 2017-10-27 11:13:31 +02:00
Mark Paluch
5ea860700c DATAMONGO-1814 - Update reference documentation for faceted classification.
Original pull request: #426.
Original ticket: DATAMONGO-1552.
2017-10-26 09:44:50 +02:00
Christoph Strobl
3dd653a702 DATAMONGO-1811 - Update documentation of MongoOperations.executeCommand.
Update Javadoc and reference documentation.
2017-10-24 14:59:47 +02:00
Christoph Strobl
f87847407b DATAMONGO-1805 - Update GridFsOperations documentation.
Fix return type in reference documentation and update Javadoc.
2017-10-24 14:59:40 +02:00
Christoph Strobl
433a125c9e DATAMONGO-1806 - Polishing.
Remove unused import, trailing whitespaces and update Javadoc.

Original Pull Request: #506
2017-10-24 14:59:33 +02:00
hartmut
5827cb0971 DATAMONGO-1806 - Fix Javadoc for GridFsResource.
Original Pull Request: #506
2017-10-24 14:59:24 +02:00
Mark Paluch
0109bf6858 DATAMONGO-1809 - Introduce AssertJ assertions for Document.
Original pull request: #508.
2017-10-24 14:45:03 +02:00
Christoph Strobl
49d1555576 DATAMONGO-1809 - Polishing.
Move tests to AssertJ.

Original pull request: #508.
2017-10-24 14:45:03 +02:00
Christoph Strobl
fdbb305b8e DATAMONGO-1809 - Fix positional parameter detection for PropertyPaths.
We now make sure to capture all digits for positional parameters.

Original pull request: #508.
2017-10-24 14:45:03 +02:00
Mark Paluch
49dd03311a DATAMONGO-1696 - Mention appropriate EnableMongoAuditing annotation in reference documentation. 2017-10-20 08:45:33 +02:00
Mark Paluch
a86a3210e1 DATAMONGO-1802 - Polishing.
Reduce converter visibility to MongoConverters's package-scope visibility. Tiny alignment in Javadoc wording. Copyright year, create empty byte array with element count instead initializer.

Original pull request: #505.
2017-10-17 14:52:11 +02:00
Christoph Strobl
4b655abfb6 DATAMONGO-1802 - Add Binary to byte array converter.
We now provide and register a Binary to byte[] converter to provide conversion of binary data to a byte array. MongoDB deserializes binary data using the document API to its Binary type. With this converter, we reinstantiated the previous capability to use byte arrays for binary data within domain types.

Original pull request: #505.
2017-10-17 14:52:11 +02:00
Oliver Gierke
0963e6cf77 DATAMONGO-1775 - Updated changelog. 2017-10-11 19:03:29 +02:00
Oliver Gierke
3e1b2c4bdb DATAMONGO-1795 - Removed obsolete Kotlin build setup. 2017-10-04 11:05:27 +02:00
Mark Paluch
03e0e0c431 DATAMONGO-1776 - After release cleanups. 2017-10-02 11:38:04 +02:00
Mark Paluch
51900021a1 DATAMONGO-1776 - Prepare next development iteration. 2017-10-02 11:38:03 +02:00
749 changed files with 2410 additions and 20706 deletions

View File

@@ -5,14 +5,6 @@ jdk:
before_script: before_script:
- mongod --version - mongod --version
- |-
echo "replication:
replSetName: rs0" | sudo tee -a /etc/mongod.conf
- sudo service mongod restart
- sleep 20
- |-
mongo --eval "rs.initiate({_id: 'rs0', members:[{_id: 0, host: '127.0.0.1:27017'}]});"
- sleep 15
services: services:
- mongodb - mongodb

View File

@@ -83,7 +83,7 @@ You can have Spring automatically create a proxy for the interface by using the
class ApplicationConfig extends AbstractMongoConfiguration { class ApplicationConfig extends AbstractMongoConfiguration {
@Override @Override
public MongoClient mongoClient() throws Exception { public Mongo mongo() throws Exception {
return new MongoClient(); return new MongoClient();
} }

19
pom.xml
View File

@@ -5,7 +5,7 @@
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId> <artifactId>spring-data-mongodb-parent</artifactId>
<version>2.1.0.M2</version> <version>2.0.4.RELEASE</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Spring Data MongoDB</name> <name>Spring Data MongoDB</name>
@@ -15,7 +15,7 @@
<parent> <parent>
<groupId>org.springframework.data.build</groupId> <groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId> <artifactId>spring-data-parent</artifactId>
<version>2.1.0.M2</version> <version>2.0.4.RELEASE</version>
</parent> </parent>
<modules> <modules>
@@ -27,9 +27,9 @@
<properties> <properties>
<project.type>multi</project.type> <project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id> <dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.1.0.M2</springdata.commons> <springdata.commons>2.0.4.RELEASE</springdata.commons>
<mongo>3.6.3</mongo> <mongo>3.5.0</mongo>
<mongo.reactivestreams>1.7.1</mongo.reactivestreams> <mongo.reactivestreams>1.6.0</mongo.reactivestreams>
<jmh.version>1.19</jmh.version> <jmh.version>1.19</jmh.version>
</properties> </properties>
@@ -183,8 +183,8 @@
<repositories> <repositories>
<repository> <repository>
<id>spring-libs-milestone</id> <id>spring-libs-release</id>
<url>https://repo.spring.io/libs-milestone</url> <url>https://repo.spring.io/libs-release</url>
</repository> </repository>
</repositories> </repositories>
@@ -193,11 +193,6 @@
<id>spring-plugins-release</id> <id>spring-plugins-release</id>
<url>https://repo.spring.io/plugins-release</url> <url>https://repo.spring.io/plugins-release</url>
</pluginRepository> </pluginRepository>
<pluginRepository>
<id>spring-libs-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
</pluginRepository>
</pluginRepositories> </pluginRepositories>
</project> </project>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId> <artifactId>spring-data-mongodb-parent</artifactId>
<version>2.1.0.M2</version> <version>2.0.4.RELEASE</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
@@ -17,7 +17,6 @@
<jpa>2.1.1</jpa> <jpa>2.1.1</jpa>
<hibernate>5.2.1.Final</hibernate> <hibernate>5.2.1.Final</hibernate>
<java-module-name>spring.data.mongodb.cross.store</java-module-name> <java-module-name>spring.data.mongodb.cross.store</java-module-name>
<project.root>${basedir}/..</project.root>
</properties> </properties>
<dependencies> <dependencies>
@@ -50,7 +49,7 @@
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId> <artifactId>spring-data-mongodb</artifactId>
<version>2.1.0.M2</version> <version>2.0.4.RELEASE</version>
</dependency> </dependency>
<!-- reactive --> <!-- reactive -->

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -204,7 +204,7 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
/** /**
* Returns the collection the given entity type shall be persisted to. * Returns the collection the given entity type shall be persisted to.
* *
* @param entityClass must not be {@literal null}. * @param entityClass must not be {@literal null}.
* @return * @return
*/ */

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@ import org.springframework.transaction.support.TransactionTemplate;
/** /**
* Integration tests for MongoDB cross-store persistence (mainly {@link MongoChangeSetPersister}). * Integration tests for MongoDB cross-store persistence (mainly {@link MongoChangeSetPersister}).
* *
* @author Thomas Risberg * @author Thomas Risberg
* @author Oliver Gierke * @author Oliver Gierke
*/ */

View File

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

View File

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

View File

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

View File

@@ -13,7 +13,7 @@
<parent> <parent>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId> <artifactId>spring-data-mongodb-parent</artifactId>
<version>2.1.0.M2</version> <version>2.0.4.RELEASE</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@@ -11,7 +11,7 @@
<parent> <parent>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId> <artifactId>spring-data-mongodb-parent</artifactId>
<version>2.1.0.M2</version> <version>2.0.4.RELEASE</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
@@ -19,8 +19,6 @@
<objenesis>1.3</objenesis> <objenesis>1.3</objenesis>
<equalsverifier>1.7.8</equalsverifier> <equalsverifier>1.7.8</equalsverifier>
<java-module-name>spring.data.mongodb</java-module-name> <java-module-name>spring.data.mongodb</java-module-name>
<project.root>${basedir}/..</project.root>
<multithreadedtc>1.01</multithreadedtc>
</properties> </properties>
<dependencies> <dependencies>
@@ -147,7 +145,7 @@
<version>1.0.1</version> <version>1.0.1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.interceptor</groupId> <groupId>javax.interceptor</groupId>
<artifactId>javax.interceptor-api</artifactId> <artifactId>javax.interceptor-api</artifactId>
@@ -216,6 +214,7 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>${jackson}</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
@@ -246,13 +245,6 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>edu.umd.cs.mtc</groupId>
<artifactId>multithreadedtc</artifactId>
<version>${multithreadedtc}</version>
<scope>test</scope>
</dependency>
<!-- Kotlin extension --> <!-- Kotlin extension -->
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
@@ -296,7 +288,7 @@
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@@ -348,8 +340,8 @@
</properties> </properties>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2015-2018 the original author or authors. * Copyright 2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ import com.mongodb.BulkWriteResult;
/** /**
* Is thrown when errors occur during bulk operations. * Is thrown when errors occur during bulk operations.
* *
* @author Tobias Trelle * @author Tobias Trelle
* @author Oliver Gierke * @author Oliver Gierke
* @since 1.9 * @since 1.9
@@ -39,7 +39,7 @@ public class BulkOperationException extends DataAccessException {
/** /**
* 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 BulkWriteException}.
* *
* @param message must not be {@literal null}. * @param message must not be {@literal null}.
* @param source must not be {@literal null}. * @param source must not be {@literal null}.
*/ */

View File

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

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2018 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
*
* http://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.springframework.dao.NonTransientDataAccessException;
import org.springframework.lang.Nullable;
/**
* {@link NonTransientDataAccessException} specific to MongoDB {@link com.mongodb.session.ClientSession} related data
* access failures such as reading data using an already closed session.
*
* @author Christoph Strobl
* @since 2.1
*/
public class ClientSessionException extends NonTransientDataAccessException {
/**
* Constructor for {@link ClientSessionException}.
*
* @param msg the detail message. Must not be {@literal null}.
*/
public ClientSessionException(String msg) {
super(msg);
}
/**
* Constructor for {@link ClientSessionException}.
*
* @param msg the detail message. Can be {@literal null}.
* @param cause the root cause. Can be {@literal null}.
*/
public ClientSessionException(@Nullable String msg, @Nullable Throwable cause) {
super(msg, cause);
}
}

View File

@@ -1,74 +0,0 @@
/*
* Copyright 2017-2018 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
*
* http://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 java.util.Optional;
import org.bson.codecs.Codec;
import org.bson.codecs.configuration.CodecConfigurationException;
import org.bson.codecs.configuration.CodecRegistry;
import org.springframework.util.Assert;
/**
* Provider interface to obtain {@link CodecRegistry} from the underlying MongoDB Java driver.
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.1
*/
@FunctionalInterface
public interface CodecRegistryProvider {
/**
* Get the underlying {@link CodecRegistry} used by the MongoDB Java driver.
*
* @return never {@literal null}.
* @throws IllegalStateException if {@link CodecRegistry} cannot be obtained.
*/
CodecRegistry getCodecRegistry();
/**
* Checks if a {@link Codec} is registered for a given type.
*
* @param type must not be {@literal null}.
* @return true if {@link #getCodecRegistry()} holds a {@link Codec} for given type.
* @throws IllegalStateException if {@link CodecRegistry} cannot be obtained.
*/
default boolean hasCodecFor(Class<?> type) {
return getCodecFor(type).isPresent();
}
/**
* Get the {@link Codec} registered for the given {@literal type} or an {@link Optional#empty() empty Optional}
* instead.
*
* @param type must not be {@literal null}.
* @param <T>
* @return never {@literal null}.
* @throws IllegalArgumentException if {@literal type} is {@literal null}.
*/
default <T> Optional<Codec<T>> getCodecFor(Class<T> type) {
Assert.notNull(type, "Type must not be null!");
try {
return Optional.of(getCodecRegistry().get(type));
} catch (CodecConfigurationException e) {
// ignore
}
return Optional.empty();
}
}

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import org.springframework.util.StringUtils;
* <p/> * <p/>
* <p/> * <p/>
* Mainly intended for internal use within the framework. * Mainly intended for internal use within the framework.
* *
* @author Thomas Risberg * @author Thomas Risberg
* @since 1.0 * @since 1.0
*/ */
@@ -38,7 +38,7 @@ public abstract class MongoCollectionUtils {
/** /**
* Obtains the collection name to use for the provided class * Obtains the collection name to use for the provided class
* *
* @param entityClass The class to determine the preferred collection name for * @param entityClass The class to determine the preferred collection name for
* @return The preferred collection name * @return The preferred collection name
*/ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -15,28 +15,24 @@
*/ */
package org.springframework.data.mongodb; package org.springframework.data.mongodb;
import org.bson.codecs.configuration.CodecRegistry;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.core.MongoExceptionTranslator; import org.springframework.data.mongodb.core.MongoExceptionTranslator;
import com.mongodb.ClientSessionOptions;
import com.mongodb.DB; import com.mongodb.DB;
import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoDatabase;
import com.mongodb.session.ClientSession;
/** /**
* Interface for factories creating {@link MongoDatabase} instances. * Interface for factories creating {@link DB} instances.
* *
* @author Mark Pollack * @author Mark Pollack
* @author Thomas Darimont * @author Thomas Darimont
* @author Christoph Strobl
*/ */
public interface MongoDbFactory extends CodecRegistryProvider { public interface MongoDbFactory {
/** /**
* Creates a default {@link MongoDatabase} instance. * Creates a default {@link DB} instance.
* *
* @return * @return
* @throws DataAccessException * @throws DataAccessException
*/ */
@@ -44,7 +40,7 @@ public interface MongoDbFactory extends CodecRegistryProvider {
/** /**
* Creates a {@link DB} instance to access the database with the given name. * Creates a {@link DB} instance to access the database with the given name.
* *
* @param dbName must not be {@literal null} or empty. * @param dbName must not be {@literal null} or empty.
* @return * @return
* @throws DataAccessException * @throws DataAccessException
@@ -53,51 +49,10 @@ public interface MongoDbFactory extends CodecRegistryProvider {
/** /**
* Exposes a shared {@link MongoExceptionTranslator}. * Exposes a shared {@link MongoExceptionTranslator}.
* *
* @return will never be {@literal null}. * @return will never be {@literal null}.
*/ */
PersistenceExceptionTranslator getExceptionTranslator(); PersistenceExceptionTranslator getExceptionTranslator();
DB getLegacyDb(); 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);
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2018 the original author or authors. * Copyright 2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,25 +16,19 @@
package org.springframework.data.mongodb; package org.springframework.data.mongodb;
import reactor.core.publisher.Mono;
import org.bson.codecs.configuration.CodecRegistry;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.core.MongoExceptionTranslator; import org.springframework.data.mongodb.core.MongoExceptionTranslator;
import com.mongodb.ClientSessionOptions;
import com.mongodb.reactivestreams.client.MongoDatabase; import com.mongodb.reactivestreams.client.MongoDatabase;
import com.mongodb.session.ClientSession;
/** /**
* Interface for factories creating reactive {@link MongoDatabase} instances. * Interface for factories creating reactive {@link MongoDatabase} instances.
* *
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl
* @since 2.0 * @since 2.0
*/ */
public interface ReactiveMongoDatabaseFactory extends CodecRegistryProvider { public interface ReactiveMongoDatabaseFactory {
/** /**
* Creates a default {@link MongoDatabase} instance. * Creates a default {@link MongoDatabase} instance.
@@ -59,33 +53,4 @@ public interface ReactiveMongoDatabaseFactory extends CodecRegistryProvider {
* @return will never be {@literal null}. * @return will never be {@literal null}.
*/ */
PersistenceExceptionTranslator getExceptionTranslator(); PersistenceExceptionTranslator getExceptionTranslator();
/**
* Get the underlying {@link CodecRegistry} used by the reactive MongoDB Java driver.
*
* @return never {@literal null}.
*/
@Override
default CodecRegistry getCodecRegistry() {
return getMongoDatabase().getCodecRegistry();
}
/**
* Obtain a {@link Mono} emitting a {@link ClientSession} for given {@link ClientSessionOptions options}.
*
* @param options must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
Mono<ClientSession> getSession(ClientSessionOptions options);
/**
* Obtain a {@link ClientSession} bound instance of {@link ReactiveMongoDatabaseFactory} 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
*/
ReactiveMongoDatabaseFactory withSession(ClientSession session);
} }

View File

@@ -1,211 +0,0 @@
/*
* Copyright 2018 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
*
* http://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 java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Optional;
import java.util.function.BiFunction;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.MethodClassKey;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.util.ReflectionUtils;
import com.mongodb.WriteConcern;
import com.mongodb.session.ClientSession;
/**
* {@link MethodInterceptor} implementation looking up and invoking an alternative target method having
* {@link ClientSession} as its first argument. This allows seamless integration with the existing code base.
* <p />
* The {@link MethodInterceptor} is aware of methods on {@code MongoCollection} that my return new instances of itself
* like (eg. {@link com.mongodb.reactivestreams.client.MongoCollection#withWriteConcern(WriteConcern)} and decorate them
* if not already proxied.
*
* @param <D> Type of the actual Mongo Database.
* @param <C> Type of the actual Mongo Collection.
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.1
*/
public class SessionAwareMethodInterceptor<D, C> implements MethodInterceptor {
private static final MethodCache METHOD_CACHE = new MethodCache();
private final ClientSession session;
private final ClientSessionOperator collectionDecorator;
private final ClientSessionOperator databaseDecorator;
private final Object target;
private final Class<?> targetType;
private final Class<?> collectionType;
private final Class<?> databaseType;
/**
* Create a new SessionAwareMethodInterceptor for given target.
*
* @param session the {@link ClientSession} to be used on invocation.
* @param target the original target object.
* @param databaseType the MongoDB database type
* @param databaseDecorator a {@link ClientSessionOperator} used to create the proxy for an imperative / reactive
* {@code MongoDatabase}.
* @param collectionType the MongoDB collection type.
* @param collectionDecorator a {@link ClientSessionOperator} used to create the proxy for an imperative / reactive
* {@code MongoCollection}.
* @param <T> target object type.
*/
public <T> SessionAwareMethodInterceptor(ClientSession session, T target, Class<D> databaseType,
ClientSessionOperator<D> databaseDecorator, Class<C> collectionType,
ClientSessionOperator<C> collectionDecorator) {
Assert.notNull(session, "ClientSession must not be null!");
Assert.notNull(target, "Target must not be null!");
Assert.notNull(databaseType, "Database type must not be null!");
Assert.notNull(databaseDecorator, "Database ClientSessionOperator must not be null!");
Assert.notNull(collectionType, "Collection type must not be null!");
Assert.notNull(collectionDecorator, "Collection ClientSessionOperator must not be null!");
this.session = session;
this.target = target;
this.databaseType = ClassUtils.getUserClass(databaseType);
this.collectionType = ClassUtils.getUserClass(collectionType);
this.collectionDecorator = collectionDecorator;
this.databaseDecorator = databaseDecorator;
this.targetType = ClassUtils.isAssignable(databaseType, target.getClass()) ? databaseType : collectionType;
}
/*
* (non-Javadoc)
* @see org.aopalliance.intercept.MethodInterceptor(org.aopalliance.intercept.MethodInvocation)
*/
@Nullable
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
if (requiresDecoration(methodInvocation.getMethod())) {
Object target = methodInvocation.proceed();
if (target instanceof Proxy) {
return target;
}
return decorate(target);
}
if (!requiresSession(methodInvocation.getMethod())) {
return methodInvocation.proceed();
}
Optional<Method> targetMethod = METHOD_CACHE.lookup(methodInvocation.getMethod(), targetType);
return !targetMethod.isPresent() ? methodInvocation.proceed()
: ReflectionUtils.invokeMethod(targetMethod.get(), target,
prependSessionToArguments(session, methodInvocation));
}
private boolean requiresDecoration(Method method) {
return ClassUtils.isAssignable(databaseType, method.getReturnType())
|| ClassUtils.isAssignable(collectionType, method.getReturnType());
}
@SuppressWarnings("unchecked")
protected Object decorate(Object target) {
return ClassUtils.isAssignable(databaseType, target.getClass()) ? databaseDecorator.apply(session, target)
: collectionDecorator.apply(session, target);
}
private static boolean requiresSession(Method method) {
if (method.getParameterCount() == 0
|| !ClassUtils.isAssignable(ClientSession.class, method.getParameterTypes()[0])) {
return true;
}
return false;
}
private static Object[] prependSessionToArguments(ClientSession session, MethodInvocation invocation) {
Object[] args = new Object[invocation.getArguments().length + 1];
args[0] = session;
System.arraycopy(invocation.getArguments(), 0, args, 1, invocation.getArguments().length);
return args;
}
/**
* Simple {@link Method} to {@link Method} caching facility for {@link ClientSession} overloaded targets.
*
* @since 2.1
* @author Christoph Strobl
*/
static class MethodCache {
private final ConcurrentReferenceHashMap<MethodClassKey, Optional<Method>> cache = new ConcurrentReferenceHashMap<>();
/**
* Lookup the target {@link Method}.
*
* @param method
* @param targetClass
* @return
*/
Optional<Method> lookup(Method method, Class<?> targetClass) {
return cache.computeIfAbsent(new MethodClassKey(method, targetClass),
val -> Optional.ofNullable(findTargetWithSession(method, targetClass)));
}
@Nullable
private Method findTargetWithSession(Method sourceMethod, Class<?> targetType) {
Class<?>[] argTypes = sourceMethod.getParameterTypes();
Class<?>[] args = new Class<?>[argTypes.length + 1];
args[0] = ClientSession.class;
System.arraycopy(argTypes, 0, args, 1, argTypes.length);
return ReflectionUtils.findMethod(targetType, sourceMethod.getName(), args);
}
/**
* Check whether the cache contains an entry for {@link Method} and {@link Class}.
*
* @param method
* @param targetClass
* @return
*/
boolean contains(Method method, Class<?> targetClass) {
return cache.containsKey(new MethodClassKey(method, targetClass));
}
}
/**
* Represents an operation upon two operands of the same type, producing a result of the same type as the operands
* accepting {@link ClientSession}. This is a specialization of {@link BiFunction} for the case where the operands and
* the result are all of the same type.
*
* @param <T> the type of the operands and result of the operator
*/
public interface ClientSessionOperator<T> extends BiFunction<ClientSession, T, T> {}
}

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@ package org.springframework.data.mongodb.config;
/** /**
* Constants to declare bean names used by the namespace configuration. * Constants to declare bean names used by the namespace configuration.
* *
* @author Jon Brisbin * @author Jon Brisbin
* @author Oliver Gierke * @author Oliver Gierke
* @author Martin Baumgartner * @author Martin Baumgartner

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2013-2018 the original author or authors. * Copyright 2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@ import org.springframework.data.domain.AuditorAware;
/** /**
* Annotation to enable auditing in MongoDB via annotation configuration. * Annotation to enable auditing in MongoDB via annotation configuration.
* *
* @author Thomas Darimont * @author Thomas Darimont
* @author Oliver Gierke * @author Oliver Gierke
*/ */
@@ -41,21 +41,21 @@ public @interface EnableMongoAuditing {
/** /**
* Configures the {@link AuditorAware} bean to be used to lookup the current principal. * Configures the {@link AuditorAware} bean to be used to lookup the current principal.
* *
* @return * @return
*/ */
String auditorAwareRef() default ""; String auditorAwareRef() default "";
/** /**
* Configures whether the creation and modification dates are set. Defaults to {@literal true}. * Configures whether the creation and modification dates are set. Defaults to {@literal true}.
* *
* @return * @return
*/ */
boolean setDates() default true; boolean setDates() default true;
/** /**
* Configures whether the entity shall be marked as modified on creation. Defaults to {@literal true}. * Configures whether the entity shall be marked as modified on creation. Defaults to {@literal true}.
* *
* @return * @return
*/ */
boolean modifyOnCreate() default true; boolean modifyOnCreate() default true;
@@ -63,7 +63,7 @@ public @interface EnableMongoAuditing {
/** /**
* Configures a {@link DateTimeProvider} bean name that allows customizing the {@link org.joda.time.DateTime} to be * Configures a {@link DateTimeProvider} bean name that allows customizing the {@link org.joda.time.DateTime} to be
* used for setting creation and modification dates. * used for setting creation and modification dates.
* *
* @return * @return
*/ */
String dateTimeProviderRef() default ""; String dateTimeProviderRef() default "";

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2015-2018 the original author or authors. * Copyright 2015-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import org.springframework.data.web.config.SpringDataJacksonModules;
/** /**
* Configuration class to expose {@link GeoJsonModule} as a Spring bean. * Configuration class to expose {@link GeoJsonModule} as a Spring bean.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Jens Schauder * @author Jens Schauder
*/ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2013-2018 the original author or authors. * Copyright 2013-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import org.w3c.dom.Element;
/** /**
* {@link BeanDefinitionParser} to parse {@code gridFsTemplate} elements into {@link BeanDefinition}s. * {@link BeanDefinitionParser} to parse {@code gridFsTemplate} elements into {@link BeanDefinition}s.
* *
* @author Martin Baumgartner * @author Martin Baumgartner
*/ */
class GridFsTemplateParser extends AbstractBeanDefinitionParser { class GridFsTemplateParser extends AbstractBeanDefinitionParser {

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -33,12 +33,12 @@ import org.w3c.dom.Element;
/** /**
* {@link BeanDefinitionParser} to register a {@link AuditingEventListener} to transparently set auditing information on * {@link BeanDefinitionParser} to register a {@link AuditingEventListener} to transparently set auditing information on
* an entity. * an entity.
* *
* @author Oliver Gierke * @author Oliver Gierke
*/ */
public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element) * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element)
*/ */
@@ -47,7 +47,7 @@ public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinit
return AuditingEventListener.class; return AuditingEventListener.class;
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#shouldGenerateId() * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#shouldGenerateId()
*/ */
@@ -56,7 +56,7 @@ public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinit
return true; return true;
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder) * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder)
*/ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2013-2018 the original author or authors. * Copyright 2013-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -37,13 +37,13 @@ import org.springframework.util.Assert;
/** /**
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableMongoAuditing} annotation. * {@link ImportBeanDefinitionRegistrar} to enable {@link EnableMongoAuditing} annotation.
* *
* @author Thomas Darimont * @author Thomas Darimont
* @author Oliver Gierke * @author Oliver Gierke
*/ */
class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport { class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation() * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation()
*/ */
@@ -52,7 +52,7 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
return EnableMongoAuditing.class; return EnableMongoAuditing.class;
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName() * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName()
*/ */
@@ -61,7 +61,7 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
return "mongoAuditingHandler"; return "mongoAuditingHandler";
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry) * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
*/ */
@@ -74,7 +74,7 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
super.registerBeanDefinitions(annotationMetadata, registry); super.registerBeanDefinitions(annotationMetadata, registry);
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration) * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration)
*/ */
@@ -92,7 +92,7 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
return configureDefaultAuditHandlerAttributes(configuration, builder); return configureDefaultAuditHandlerAttributes(configuration, builder);
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListener(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry) * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListener(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry)
*/ */
@@ -125,14 +125,14 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
/** /**
* Creates a new {@link MongoMappingContextLookup} for the given {@link MappingMongoConverter}. * Creates a new {@link MongoMappingContextLookup} for the given {@link MappingMongoConverter}.
* *
* @param converter must not be {@literal null}. * @param converter must not be {@literal null}.
*/ */
public MongoMappingContextLookup(MappingMongoConverter converter) { public MongoMappingContextLookup(MappingMongoConverter converter) {
this.converter = converter; this.converter = converter;
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObject() * @see org.springframework.beans.factory.FactoryBean#getObject()
*/ */
@@ -141,7 +141,7 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
return converter.getMappingContext(); return converter.getMappingContext();
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType() * @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/ */
@@ -150,7 +150,7 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
return MappingContext.class; return MappingContext.class;
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton() * @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2015-2018 the original author or authors. * Copyright 2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -29,13 +29,13 @@ import org.w3c.dom.Element;
/** /**
* Parser for {@code mongo-client} definitions. * Parser for {@code mongo-client} definitions.
* *
* @author Christoph Strobl * @author Christoph Strobl
* @since 1.7 * @since 1.7
*/ */
public class MongoClientParser implements BeanDefinitionParser { public class MongoClientParser implements BeanDefinitionParser {
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext) * @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
*/ */

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
/** /**
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB configuration. * {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB configuration.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Martin Baumgartner * @author Martin Baumgartner
* @author Christoph Strobl * @author Christoph Strobl

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import org.w3c.dom.Element;
/** /**
* Utility methods for {@link BeanDefinitionParser} implementations for MongoDB. * Utility methods for {@link BeanDefinitionParser} implementations for MongoDB.
* *
* @author Mark Pollack * @author Mark Pollack
* @author Oliver Gierke * @author Oliver Gierke
* @author Thomas Darimont * @author Thomas Darimont
@@ -43,7 +43,7 @@ abstract class MongoParsingUtils {
/** /**
* Parses the mongo replica-set element. * Parses the mongo replica-set element.
* *
* @param parserContext the parser context * @param parserContext the parser context
* @param element the mongo element * @param element the mongo element
* @param mongoBuilder the bean definition builder to populate * @param mongoBuilder the bean definition builder to populate
@@ -56,7 +56,7 @@ abstract class MongoParsingUtils {
/** /**
* Parses the {@code mongo:client-options} sub-element. Populates the given attribute factory with the proper * Parses the {@code mongo:client-options} sub-element. Populates the given attribute factory with the proper
* attributes. * attributes.
* *
* @param element must not be {@literal null}. * @param element must not be {@literal null}.
* @param mongoClientBuilder must not be {@literal null}. * @param mongoClientBuilder must not be {@literal null}.
* @return * @return
@@ -102,7 +102,7 @@ abstract class MongoParsingUtils {
/** /**
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a * Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
* {@link WriteConcernPropertyEditor}. * {@link WriteConcernPropertyEditor}.
* *
* @return * @return
*/ */
static BeanDefinitionBuilder getWriteConcernPropertyEditorBuilder() { static BeanDefinitionBuilder getWriteConcernPropertyEditorBuilder() {
@@ -135,7 +135,7 @@ abstract class MongoParsingUtils {
/** /**
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a * Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
* {@link ReadPreferencePropertyEditor}. * {@link ReadPreferencePropertyEditor}.
* *
* @return * @return
* @since 1.7 * @since 1.7
*/ */
@@ -153,7 +153,7 @@ abstract class MongoParsingUtils {
/** /**
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a * Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
* {@link MongoCredentialPropertyEditor}. * {@link MongoCredentialPropertyEditor}.
* *
* @return * @return
* @since 1.7 * @since 1.7
*/ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -33,13 +33,13 @@ import org.w3c.dom.Element;
/** /**
* {@link BeanDefinitionParser} to parse {@code template} elements into {@link BeanDefinition}s. * {@link BeanDefinitionParser} to parse {@code template} elements into {@link BeanDefinition}s.
* *
* @author Martin Baumgartner * @author Martin Baumgartner
* @author Oliver Gierke * @author Oliver Gierke
*/ */
class MongoTemplateParser extends AbstractBeanDefinitionParser { class MongoTemplateParser extends AbstractBeanDefinitionParser {
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext) * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
*/ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2015-2018 the original author or authors. * Copyright 2015-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import com.mongodb.ReadPreference;
/** /**
* Parse a {@link String} to a {@link ReadPreference}. * Parse a {@link String} to a {@link ReadPreference}.
* *
* @author Christoph Strobl * @author Christoph Strobl
* @since 1.7 * @since 1.7
*/ */

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -21,12 +21,12 @@ import com.mongodb.WriteConcern;
/** /**
* Converter to create {@link WriteConcern} instances from String representations. * Converter to create {@link WriteConcern} instances from String representations.
* *
* @author Oliver Gierke * @author Oliver Gierke
*/ */
public class StringToWriteConcernConverter implements Converter<String, WriteConcern> { public class StringToWriteConcernConverter implements Converter<String, WriteConcern> {
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ import com.mongodb.WriteConcern;
* {@link WriteConcern#valueOf(String)}, use the well known {@link WriteConcern} value, otherwise pass the string as is * {@link WriteConcern#valueOf(String)}, use the well known {@link WriteConcern} value, otherwise pass the string as is
* to the constructor of the write concern. There is no support for other constructor signatures when parsing from a * to the constructor of the write concern. There is no support for other constructor signatures when parsing from a
* string value. * string value.
* *
* @author Mark Pollack * @author Mark Pollack
* @author Christoph Strobl * @author Christoph Strobl
*/ */

View File

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

View File

@@ -1,117 +0,0 @@
/*
* Copyright 2018 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
*
* http://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 lombok.EqualsAndHashCode;
import java.util.concurrent.atomic.AtomicReference;
import org.bson.Document;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.messaging.Message;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import com.mongodb.client.model.changestream.ChangeStreamDocument;
/**
* {@link Message} implementation specific to MongoDB <a href="https://docs.mongodb.com/manual/changeStreams/">Change
* Streams</a>.
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.1
*/
@EqualsAndHashCode
public class ChangeStreamEvent<T> {
private final @Nullable ChangeStreamDocument<Document> raw;
private final Class<T> targetType;
private final MongoConverter converter;
private final AtomicReference<T> converted = new AtomicReference<>();
/**
* @param raw can be {@literal null}.
* @param targetType must not be {@literal null}.
* @param converter must not be {@literal null}.
*/
public ChangeStreamEvent(@Nullable ChangeStreamDocument<Document> raw, Class<T> targetType,
MongoConverter converter) {
this.raw = raw;
this.targetType = targetType;
this.converter = converter;
}
/**
* Get the raw {@link ChangeStreamDocument} as emitted by the driver.
*
* @return can be {@literal null}.
*/
@Nullable
public ChangeStreamDocument<Document> getRaw() {
return raw;
}
/**
* Get the potentially converted {@link ChangeStreamDocument#getFullDocument()}.
*
* @return {@literal null} when {@link #getRaw()} or {@link ChangeStreamDocument#getFullDocument()} is
* {@literal null}.
*/
@Nullable
public T getBody() {
if (raw == null) {
return null;
}
if (raw.getFullDocument() == null) {
return targetType.cast(raw.getFullDocument());
}
return getConverted();
}
private T getConverted() {
T result = converted.get();
if (result != null) {
return result;
}
if (ClassUtils.isAssignable(Document.class, raw.getFullDocument().getClass())) {
result = converter.read(targetType, raw.getFullDocument());
return converted.compareAndSet(null, result) ? result : converted.get();
}
if (converter.getConversionService().canConvert(raw.getFullDocument().getClass(), targetType)) {
result = converter.getConversionService().convert(raw.getFullDocument(), targetType);
return converted.compareAndSet(null, result) ? result : converted.get();
}
throw new IllegalArgumentException(String.format("No converter found capable of converting %s to %s",
raw.getFullDocument().getClass(), targetType));
}
@Override
public String toString() {
return "ChangeStreamEvent {" + "raw=" + raw + ", targetType=" + targetType + '}';
}
}

View File

@@ -1,218 +0,0 @@
/*
* Copyright 2018 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
*
* http://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 lombok.EqualsAndHashCode;
import java.util.Arrays;
import java.util.Optional;
import org.bson.BsonValue;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import com.mongodb.client.model.changestream.ChangeStreamDocument;
import com.mongodb.client.model.changestream.FullDocument;
/**
* Options applicable to MongoDB <a href="https://docs.mongodb.com/manual/changeStreams/">Change Streams</a>. Intended
* to be used along with {@link org.springframework.data.mongodb.core.messaging.ChangeStreamRequest} in a sync world as
* well {@link ReactiveMongoOperations} if you prefer it that way.
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.1
*/
@EqualsAndHashCode
public class ChangeStreamOptions {
private @Nullable Object filter;
private @Nullable BsonValue resumeToken;
private @Nullable FullDocument fullDocumentLookup;
private @Nullable Collation collation;
protected ChangeStreamOptions() {}
/**
* @return {@link Optional#empty()} if not set.
*/
public Optional<Object> getFilter() {
return Optional.ofNullable(filter);
}
/**
* @return {@link Optional#empty()} if not set.
*/
public Optional<BsonValue> getResumeToken() {
return Optional.ofNullable(resumeToken);
}
/**
* @return {@link Optional#empty()} if not set.
*/
public Optional<FullDocument> getFullDocumentLookup() {
return Optional.ofNullable(fullDocumentLookup);
}
/**
* @return {@link Optional#empty()} if not set.
*/
public Optional<Collation> getCollation() {
return Optional.ofNullable(collation);
}
/**
* @return empty {@link ChangeStreamOptions}.
*/
public static ChangeStreamOptions empty() {
return ChangeStreamOptions.builder().build();
}
/**
* Obtain a shiny new {@link ChangeStreamOptionsBuilder} and start defining options in this fancy fluent way. Just
* don't forget to call {@link ChangeStreamOptionsBuilder#build() build()} when your're done.
*
* @return new instance of {@link ChangeStreamOptionsBuilder}.
*/
public static ChangeStreamOptionsBuilder builder() {
return new ChangeStreamOptionsBuilder();
}
/**
* Builder for creating {@link ChangeStreamOptions}.
*
* @author Christoph Strobl
* @since 2.1
*/
public static class ChangeStreamOptionsBuilder {
private @Nullable Object filter;
private @Nullable BsonValue resumeToken;
private @Nullable FullDocument fullDocumentLookup;
private @Nullable Collation collation;
private ChangeStreamOptionsBuilder() {}
/**
* Set the collation to use.
*
* @param collation must not be {@literal null} nor {@literal empty}.
* @return this.
*/
public ChangeStreamOptionsBuilder collation(Collation collation) {
Assert.notNull(collation, "Collation must not be null nor empty!");
this.collation = collation;
return this;
}
/**
* Set the filter to apply.
* <p/>
* Fields on aggregation expression root level are prefixed to map to fields contained in
* {@link ChangeStreamDocument#getFullDocument() fullDocument}. However {@literal operationType}, {@literal ns},
* {@literal documentKey} and {@literal fullDocument} are reserved words that will be omitted, and therefore taken
* as given, during the mapping procedure. You may want to have a look at the
* <a href="https://docs.mongodb.com/manual/reference/change-events/">structure of Change Events</a>.
* <p/>
* Use {@link org.springframework.data.mongodb.core.aggregation.TypedAggregation} to ensure filter expressions are
* mapped to domain type fields.
*
* @param filter the {@link Aggregation Aggregation pipeline} to apply for filtering events. Must not be
* {@literal null}.
* @return this.
*/
public ChangeStreamOptionsBuilder filter(Aggregation filter) {
Assert.notNull(filter, "Filter must not be null!");
this.filter = filter;
return this;
}
/**
* Set the plain filter chain to apply.
*
* @param filter must not be {@literal null} nor contain {@literal null} values.
* @return this.
*/
public ChangeStreamOptionsBuilder filter(Document... filter) {
Assert.noNullElements(filter, "Filter must not contain null values");
this.filter = Arrays.asList(filter);
return this;
}
/**
* Set the resume token (typically a {@link org.bson.BsonDocument} containing a {@link org.bson.BsonBinary binary
* token}) after which to start with listening.
*
* @param resumeToken must not be {@literal null}.
* @return this.
*/
public ChangeStreamOptionsBuilder resumeToken(BsonValue resumeToken) {
Assert.notNull(resumeToken, "ResumeToken must not be null!");
this.resumeToken = resumeToken;
return this;
}
/**
* Set the {@link FullDocument} lookup to {@link FullDocument#UPDATE_LOOKUP}.
*
* @return this.
* @see #fullDocumentLookup(FullDocument)
*/
public ChangeStreamOptionsBuilder returnFullDocumentOnUpdate() {
return fullDocumentLookup(FullDocument.UPDATE_LOOKUP);
}
/**
* Set the {@link FullDocument} lookup to use.
*
* @param lookup must not be {@literal null}.
* @return this.
*/
public ChangeStreamOptionsBuilder fullDocumentLookup(FullDocument lookup) {
Assert.notNull(lookup, "Lookup must not be null!");
this.fullDocumentLookup = lookup;
return this;
}
/**
* @return the built {@link ChangeStreamOptions}
*/
public ChangeStreamOptions build() {
ChangeStreamOptions options = new ChangeStreamOptions();
options.filter = filter;
options.resumeToken = resumeToken;
options.fullDocumentLookup = fullDocumentLookup;
options.collation = collation;
return options;
}
}
}

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2018 the original author or authors. * Copyright 2010-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -15,27 +15,18 @@
*/ */
package org.springframework.data.mongodb.core; package org.springframework.data.mongodb.core;
import lombok.RequiredArgsConstructor;
import java.util.Optional; import java.util.Optional;
import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
import org.springframework.data.mongodb.core.validation.Validator;
import org.springframework.data.util.Optionals;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import com.mongodb.client.model.ValidationAction;
import com.mongodb.client.model.ValidationLevel;
/** /**
* Provides a simple wrapper to encapsulate the variety of settings you can use when creating a collection. * Provides a simple wrapper to encapsulate the variety of settings you can use when creating a collection.
* *
* @author Thomas Risberg * @author Thomas Risberg
* @author Christoph Strobl * @author Christoph Strobl
* @author Mark Paluch * @author Mark Paluch
* @author Andreas Zink
*/ */
public class CollectionOptions { public class CollectionOptions {
@@ -43,7 +34,6 @@ public class CollectionOptions {
private @Nullable Long size; private @Nullable Long size;
private @Nullable Boolean capped; private @Nullable Boolean capped;
private @Nullable Collation collation; private @Nullable Collation collation;
private ValidationOptions validationOptions;
/** /**
* Constructs a new <code>CollectionOptions</code> instance. * Constructs a new <code>CollectionOptions</code> instance.
@@ -56,17 +46,16 @@ public class CollectionOptions {
*/ */
@Deprecated @Deprecated
public CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped) { public CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped) {
this(size, maxDocuments, capped, null, ValidationOptions.none()); this(size, maxDocuments, capped, null);
} }
private CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped, private CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped,
@Nullable Collation collation, ValidationOptions validationOptions) { @Nullable Collation collation) {
this.maxDocuments = maxDocuments; this.maxDocuments = maxDocuments;
this.size = size; this.size = size;
this.capped = capped; this.capped = capped;
this.collation = collation; this.collation = collation;
this.validationOptions = validationOptions;
} }
/** /**
@@ -80,7 +69,7 @@ public class CollectionOptions {
Assert.notNull(collation, "Collation must not be null!"); Assert.notNull(collation, "Collation must not be null!");
return new CollectionOptions(null, null, null, collation, ValidationOptions.none()); return new CollectionOptions(null, null, null, collation);
} }
/** /**
@@ -90,7 +79,7 @@ public class CollectionOptions {
* @since 2.0 * @since 2.0
*/ */
public static CollectionOptions empty() { public static CollectionOptions empty() {
return new CollectionOptions(null, null, null, null, ValidationOptions.none()); return new CollectionOptions(null, null, null, null);
} }
/** /**
@@ -101,7 +90,7 @@ public class CollectionOptions {
* @since 2.0 * @since 2.0
*/ */
public CollectionOptions capped() { public CollectionOptions capped() {
return new CollectionOptions(size, maxDocuments, true, collation, validationOptions); return new CollectionOptions(size, maxDocuments, true, collation);
} }
/** /**
@@ -112,7 +101,7 @@ public class CollectionOptions {
* @since 2.0 * @since 2.0
*/ */
public CollectionOptions maxDocuments(long maxDocuments) { public CollectionOptions maxDocuments(long maxDocuments) {
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions); return new CollectionOptions(size, maxDocuments, capped, collation);
} }
/** /**
@@ -123,7 +112,7 @@ public class CollectionOptions {
* @since 2.0 * @since 2.0
*/ */
public CollectionOptions size(long size) { public CollectionOptions size(long size) {
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions); return new CollectionOptions(size, maxDocuments, capped, collation);
} }
/** /**
@@ -134,127 +123,7 @@ public class CollectionOptions {
* @since 2.0 * @since 2.0
*/ */
public CollectionOptions collation(@Nullable Collation collation) { public CollectionOptions collation(@Nullable Collation collation) {
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions); return new CollectionOptions(size, maxDocuments, capped, collation);
}
/**
* Create new {@link CollectionOptions} with already given settings and {@code validationOptions} set to given
* {@link MongoJsonSchema}.
*
* @param schema can be {@literal null}.
* @return new {@link CollectionOptions}.
* @since 2.1
*/
public CollectionOptions schema(@Nullable MongoJsonSchema schema) {
return validator(Validator.schema(schema));
}
/**
* Create new {@link CollectionOptions} with already given settings and {@code validationOptions} set to given
* {@link Validator}.
*
* @param validator can be {@literal null}.
* @return new {@link CollectionOptions}.
* @since 2.1
*/
public CollectionOptions validator(@Nullable Validator validator) {
return validation(validationOptions.validator(validator));
}
/**
* Create new {@link CollectionOptions} with already given settings and {@code validationLevel} set to
* {@link ValidationLevel#OFF}.
*
* @return new {@link CollectionOptions}.
* @since 2.1
*/
public CollectionOptions disableValidation() {
return schemaValidationLevel(ValidationLevel.OFF);
}
/**
* Create new {@link CollectionOptions} with already given settings and {@code validationLevel} set to
* {@link ValidationLevel#STRICT}.
*
* @return new {@link CollectionOptions}.
* @since 2.1
*/
public CollectionOptions strictValidation() {
return schemaValidationLevel(ValidationLevel.STRICT);
}
/**
* Create new {@link CollectionOptions} with already given settings and {@code validationLevel} set to
* {@link ValidationLevel#MODERATE}.
*
* @return new {@link CollectionOptions}.
* @since 2.1
*/
public CollectionOptions moderateValidation() {
return schemaValidationLevel(ValidationLevel.MODERATE);
}
/**
* Create new {@link CollectionOptions} with already given settings and {@code validationAction} set to
* {@link ValidationAction#WARN}.
*
* @return new {@link CollectionOptions}.
* @since 2.1
*/
public CollectionOptions warnOnValidationError() {
return schemaValidationAction(ValidationAction.WARN);
}
/**
* Create new {@link CollectionOptions} with already given settings and {@code validationAction} set to
* {@link ValidationAction#ERROR}.
*
* @return new {@link CollectionOptions}.
* @since 2.1
*/
public CollectionOptions failOnValidationError() {
return schemaValidationAction(ValidationAction.ERROR);
}
/**
* Create new {@link CollectionOptions} with already given settings and {@code validationLevel} set given
* {@link ValidationLevel}.
*
* @param validationLevel must not be {@literal null}.
* @return new {@link CollectionOptions}.
* @since 2.1
*/
public CollectionOptions schemaValidationLevel(ValidationLevel validationLevel) {
Assert.notNull(validationLevel, "ValidationLevel must not be null!");
return validation(validationOptions.validationLevel(validationLevel));
}
/**
* Create new {@link CollectionOptions} with already given settings and {@code validationAction} set given
* {@link ValidationAction}.
*
* @param validationAction must not be {@literal null}.
* @return new {@link CollectionOptions}.
* @since 2.1
*/
public CollectionOptions schemaValidationAction(ValidationAction validationAction) {
Assert.notNull(validationAction, "ValidationAction must not be null!");
return validation(validationOptions.validationAction(validationAction));
}
/**
* Create new {@link CollectionOptions} with the given {@link ValidationOptions}.
*
* @param validationOptions must not be {@literal null}. Use {@link ValidationOptions#none()} to remove validation.
* @return new {@link CollectionOptions}.
* @since 2.1
*/
public CollectionOptions validation(ValidationOptions validationOptions) {
Assert.notNull(validationOptions, "ValidationOptions must not be null!");
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions);
} }
/** /**
@@ -294,104 +163,4 @@ public class CollectionOptions {
public Optional<Collation> getCollation() { public Optional<Collation> getCollation() {
return Optional.ofNullable(collation); return Optional.ofNullable(collation);
} }
/**
* Get the {@link MongoJsonSchema} for the collection.
*
* @return {@link Optional#empty()} if not set.
* @since 2.1
*/
public Optional<ValidationOptions> getValidationOptions() {
return validationOptions.isEmpty() ? Optional.empty() : Optional.of(validationOptions);
}
/**
* Encapsulation of ValidationOptions options.
*
* @author Christoph Strobl
* @author Andreas Zink
* @since 2.1
*/
@RequiredArgsConstructor
public static class ValidationOptions {
private static final ValidationOptions NONE = new ValidationOptions(null, null, null);
private final @Nullable Validator validator;
private final @Nullable ValidationLevel validationLevel;
private final @Nullable ValidationAction validationAction;
/**
* Create an empty {@link ValidationOptions}.
*
* @return never {@literal null}.
*/
public static ValidationOptions none() {
return NONE;
}
/**
* Define the {@link Validator} to be used for document validation.
*
* @param validator can be {@literal null}.
* @return new instance of {@link ValidationOptions}.
*/
public ValidationOptions validator(@Nullable Validator validator) {
return new ValidationOptions(validator, validationLevel, validationAction);
}
/**
* Define the validation level to apply.
*
* @param validationLevel can be {@literal null}.
* @return new instance of {@link ValidationOptions}.
*/
public ValidationOptions validationLevel(ValidationLevel validationLevel) {
return new ValidationOptions(validator, validationLevel, validationAction);
}
/**
* Define the validation action to take.
*
* @param validationAction can be {@literal null}.
* @return new instance of {@link ValidationOptions}.
*/
public ValidationOptions validationAction(ValidationAction validationAction) {
return new ValidationOptions(validator, validationLevel, validationAction);
}
/**
* Get the {@link Validator} to use.
*
* @return never {@literal null}.
*/
public Optional<Validator> getValidator() {
return Optional.ofNullable(validator);
}
/**
* Get the {@code validationLevel} to apply.
*
* @return {@link Optional#empty()} if not set.
*/
public Optional<ValidationLevel> getValidationLevel() {
return Optional.ofNullable(validationLevel);
}
/**
* Get the {@code validationAction} to perform.
*
* @return @return {@link Optional#empty()} if not set.
*/
public Optional<ValidationAction> getValidationAction() {
return Optional.ofNullable(validationAction);
}
/**
* @return {@literal true} if no arguments set.
*/
boolean isEmpty() {
return !Optionals.isAnyPresent(getValidator(), getValidationAction(), getValidationLevel());
}
}
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import com.mongodb.client.FindIterable;
/** /**
* Simple callback interface to allow customization of a {@link FindIterable}. * Simple callback interface to allow customization of a {@link FindIterable}.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Christoph Strobl * @author Christoph Strobl
*/ */
@@ -29,7 +29,7 @@ interface CursorPreparer {
/** /**
* Prepare the given cursor (apply limits, skips and so on). Returns the prepared cursor. * Prepare the given cursor (apply limits, skips and so on). Returns the prepared cursor.
* *
* @param cursor * @param cursor
*/ */
FindIterable<Document> prepare(FindIterable<Document> cursor); FindIterable<Document> prepare(FindIterable<Document> cursor);

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2015-2018 the original author or authors. * Copyright 2015-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -274,10 +274,19 @@ class DefaultBulkOperations implements BulkOperations {
public com.mongodb.bulk.BulkWriteResult execute() { public com.mongodb.bulk.BulkWriteResult execute() {
try { try {
return mongoOperations.execute(collectionName, collection -> { MongoCollection<Document> collection = mongoOperations.getCollection(collectionName);
return collection.bulkWrite(models.stream().map(this::mapWriteModel).collect(Collectors.toList()), bulkOptions); if (defaultWriteConcern != null) {
}); collection = collection.withWriteConcern(defaultWriteConcern);
}
return collection.bulkWrite(models.stream().map(this::mapWriteModel).collect(Collectors.toList()), bulkOptions);
} catch (BulkWriteException o_O) {
DataAccessException toThrow = exceptionTranslator.translateExceptionIfPossible(o_O);
throw toThrow == null ? o_O : toThrow;
} finally { } finally {
this.bulkOptions = getBulkWriteOptions(bulkOperationContext.getBulkMode()); this.bulkOptions = getBulkWriteOptions(bulkOperationContext.getBulkMode());
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/ */
package org.springframework.data.mongodb.core; package org.springframework.data.mongodb.core;
import static org.springframework.data.mongodb.core.MongoTemplate.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@@ -48,22 +50,18 @@ public class DefaultIndexOperations implements IndexOperations {
private static final String PARTIAL_FILTER_EXPRESSION_KEY = "partialFilterExpression"; private static final String PARTIAL_FILTER_EXPRESSION_KEY = "partialFilterExpression";
private final MongoDbFactory mongoDbFactory;
private final String collectionName; private final String collectionName;
private final QueryMapper mapper; private final QueryMapper mapper;
private final @Nullable Class<?> type; private final @Nullable Class<?> type;
private MongoOperations mongoOperations;
/** /**
* Creates a new {@link DefaultIndexOperations}. * Creates a new {@link DefaultIndexOperations}.
* *
* @param mongoDbFactory must not be {@literal null}. * @param mongoDbFactory must not be {@literal null}.
* @param collectionName must not be {@literal null}. * @param collectionName must not be {@literal null}.
* @param queryMapper must not be {@literal null}. * @param queryMapper must not be {@literal null}.
* @deprecated since 2.1. Please use
* {@link DefaultIndexOperations#DefaultIndexOperations(MongoOperations, String, Class)}.
*/ */
@Deprecated
public DefaultIndexOperations(MongoDbFactory mongoDbFactory, String collectionName, QueryMapper queryMapper) { public DefaultIndexOperations(MongoDbFactory mongoDbFactory, String collectionName, QueryMapper queryMapper) {
this(mongoDbFactory, collectionName, queryMapper, null); this(mongoDbFactory, collectionName, queryMapper, null);
} }
@@ -76,10 +74,7 @@ public class DefaultIndexOperations implements IndexOperations {
* @param queryMapper must not be {@literal null}. * @param queryMapper must not be {@literal null}.
* @param type Type used for mapping potential partial index filter expression. Can be {@literal null}. * @param type Type used for mapping potential partial index filter expression. Can be {@literal null}.
* @since 1.10 * @since 1.10
* @deprecated since 2.1. Please use
* {@link DefaultIndexOperations#DefaultIndexOperations(MongoOperations, String, Class)}.
*/ */
@Deprecated
public DefaultIndexOperations(MongoDbFactory mongoDbFactory, String collectionName, QueryMapper queryMapper, public DefaultIndexOperations(MongoDbFactory mongoDbFactory, String collectionName, QueryMapper queryMapper,
@Nullable Class<?> type) { @Nullable Class<?> type) {
@@ -87,29 +82,10 @@ public class DefaultIndexOperations implements IndexOperations {
Assert.notNull(collectionName, "Collection name can not be null!"); Assert.notNull(collectionName, "Collection name can not be null!");
Assert.notNull(queryMapper, "QueryMapper must not be null!"); Assert.notNull(queryMapper, "QueryMapper must not be null!");
this.mongoDbFactory = mongoDbFactory;
this.collectionName = collectionName; this.collectionName = collectionName;
this.mapper = queryMapper; this.mapper = queryMapper;
this.type = type; this.type = type;
this.mongoOperations = new MongoTemplate(mongoDbFactory);
}
/**
* Creates a new {@link DefaultIndexOperations}.
*
* @param mongoOperations must not be {@literal null}.
* @param collectionName must not be {@literal null} or empty.
* @param type can be {@literal null}.
* @since 2.1
*/
public DefaultIndexOperations(MongoOperations mongoOperations, String collectionName, @Nullable Class<?> type) {
Assert.notNull(mongoOperations, "MongoOperations must not be null!");
Assert.hasText(collectionName, "Collection name must not be null or empty!");
this.mongoOperations = mongoOperations;
this.mapper = new QueryMapper(mongoOperations.getConverter());
this.collectionName = collectionName;
this.type = type;
} }
/* /*
@@ -211,10 +187,11 @@ public class DefaultIndexOperations implements IndexOperations {
Assert.notNull(callback, "CollectionCallback must not be null!"); Assert.notNull(callback, "CollectionCallback must not be null!");
if (type != null) { try {
return mongoOperations.execute(type, callback); MongoCollection<Document> collection = mongoDbFactory.getDb().getCollection(collectionName);
return callback.doInCollection(collection);
} catch (RuntimeException e) {
throw potentiallyConvertRuntimeException(e, mongoDbFactory.getExceptionTranslator());
} }
return mongoOperations.execute(collectionName, callback);
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2018 the original author or authors. * Copyright 2010-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import com.mongodb.MongoException;
* about exception handling. {@MongoException}s will be caught and translated by the calling MongoTemplate An * about exception handling. {@MongoException}s will be caught and translated by the calling MongoTemplate An
* DocumentCallbackHandler is typically stateful: It keeps the result state within the object, to be available later for * DocumentCallbackHandler is typically stateful: It keeps the result state within the object, to be available later for
* later inspection. * later inspection.
* *
* @author Mark Pollack * @author Mark Pollack
* @author Grame Rocher * @author Grame Rocher
* @author Oliver Gierke * @author Oliver Gierke

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2017-2018 the original author or authors. * Copyright 2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -19,14 +19,11 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.springframework.dao.DataAccessException;
import org.springframework.data.geo.GeoResults; import org.springframework.data.geo.GeoResults;
import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import com.mongodb.client.MongoCollection;
/** /**
* {@link ExecutableFindOperation} allows creation and execution of MongoDB find operations in a fluent API style. * {@link ExecutableFindOperation} allows creation and execution of MongoDB find operations in a fluent API style.
* <br /> * <br />
@@ -205,7 +202,7 @@ public interface ExecutableFindOperation {
* @author Christoph Strobl * @author Christoph Strobl
* @since 2.0 * @since 2.0
*/ */
interface FindWithProjection<T> extends FindWithQuery<T>, FindDistinct { interface FindWithProjection<T> extends FindWithQuery<T> {
/** /**
* Define the target type fields should be mapped to. <br /> * Define the target type fields should be mapped to. <br />
@@ -217,101 +214,6 @@ public interface ExecutableFindOperation {
* @throws IllegalArgumentException if resultType is {@literal null}. * @throws IllegalArgumentException if resultType is {@literal null}.
*/ */
<R> FindWithQuery<R> as(Class<R> resultType); <R> FindWithQuery<R> as(Class<R> resultType);
}
/**
* Distinct Find support.
*
* @author Christoph Strobl
* @since 2.1
*/
interface FindDistinct {
/**
* Finds the distinct values for a specified {@literal field} across a single {@link MongoCollection} or view.
*
* @param field name of the field. Must not be {@literal null}.
* @return new instance of {@link TerminatingDistinct}.
* @throws IllegalArgumentException if field is {@literal null}.
*/
TerminatingDistinct<Object> distinct(String field);
}
/**
* Result type override. Optional.
*
* @author Christoph Strobl
* @since 2.1
*/
interface DistinctWithProjection {
/**
* Define the target type the result should be mapped to. <br />
* Skip this step if you are anyway fine with the default conversion.
* <dl>
* <dt>{@link Object} (the default)</dt>
* <dd>Result is mapped according to the {@link org.bson.BsonType} converting eg. {@link org.bson.BsonString} into
* plain {@link String}, {@link org.bson.BsonInt64} to {@link Long}, etc. always picking the most concrete type with
* respect to the domain types property.<br />
* Any {@link org.bson.BsonType#DOCUMENT} is run through the {@link org.springframework.data.convert.EntityReader}
* to obtain the domain type. <br />
* Using {@link Object} also works for non strictly typed fields. Eg. a mixture different types like fields using
* {@link String} in one {@link org.bson.Document} while {@link Long} in another.</dd>
* <dt>Any Simple type like {@link String} or {@link Long}.</dt>
* <dd>The result is mapped directly by the MongoDB Java driver and the {@link org.bson.codecs.CodeCodec Codecs} in
* place. This works only for results where all documents considered for the operation use the very same type for
* the field.</dd>
* <dt>Any Domain type</dt>
* <dd>Domain types can only be mapped if the if the result of the actual {@code distinct()} operation returns
* {@link org.bson.BsonType#DOCUMENT}.</dd>
* <dt>{@link org.bson.BsonValue}</dt>
* <dd>Using {@link org.bson.BsonValue} allows retrieval of the raw driver specific format, which returns eg.
* {@link org.bson.BsonString}.</dd>
* </dl>
*
* @param resultType must not be {@literal null}.
* @param <R> result type.
* @return new instance of {@link TerminatingDistinct}.
* @throws IllegalArgumentException if resultType is {@literal null}.
*/
<R> TerminatingDistinct<R> as(Class<R> resultType);
}
/**
* Result restrictions. Optional.
*
* @author Christoph Strobl
* @since 2.1
*/
interface DistinctWithQuery<T> extends DistinctWithProjection {
/**
* Set the filter query to be used.
*
* @param query must not be {@literal null}.
* @return new instance of {@link TerminatingDistinct}.
* @throws IllegalArgumentException if resultType is {@literal null}.
*/
TerminatingDistinct<T> matching(Query query);
}
/**
* Terminating distinct find operations.
*
* @author Christoph Strobl
* @since 2.1
*/
interface TerminatingDistinct<T> extends DistinctWithQuery<T> {
/**
* Get all matching distinct field values.
*
* @return empty {@link List} if not match found. Never {@literal null}.
* @throws DataAccessException if eg. result cannot be converted correctly which may happen if the document contains
* {@link String} whereas the result type is specified as {@link Long}.
*/
List<T> all();
} }
/** /**
@@ -320,5 +222,5 @@ public interface ExecutableFindOperation {
* @author Christoph Strobl * @author Christoph Strobl
* @since 2.0 * @since 2.0
*/ */
interface ExecutableFind<T> extends FindWithCollection<T>, FindWithProjection<T>, FindDistinct {} interface ExecutableFind<T> extends FindWithCollection<T>, FindWithProjection<T> {}
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2017-2018 the original author or authors. * Copyright 2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -205,19 +205,6 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
return template.exists(query, domainType, getCollectionName()); return template.exists(query, domainType, getCollectionName());
} }
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.FindDistinct#distinct(java.lang.String)
*/
@SuppressWarnings("unchecked")
@Override
public TerminatingDistinct<Object> distinct(String field) {
Assert.notNull(field, "Field must not be null!");
return new DistinctOperationSupport(this, field);
}
private List<T> doFind(@Nullable CursorPreparer preparer) { private List<T> doFind(@Nullable CursorPreparer preparer) {
Document queryObject = query.getQueryObject(); Document queryObject = query.getQueryObject();
@@ -227,12 +214,6 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
getCursorPreparer(query, preparer)); getCursorPreparer(query, preparer));
} }
private List<T> doFindDistinct(String field) {
return template.findDistinct(query, field, getCollectionName(), domainType,
returnType == domainType ? (Class<T>) Object.class : returnType);
}
private CloseableIterator<T> doStream() { private CloseableIterator<T> doStream() {
return template.doStream(query, domainType, getCollectionName(), returnType); return template.doStream(query, domainType, getCollectionName(), returnType);
} }
@@ -280,54 +261,4 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
return this; return this;
} }
} }
/**
* @author Christoph Strobl
* @since 2.1
*/
static class DistinctOperationSupport<T> implements TerminatingDistinct<T> {
private final String field;
private final ExecutableFindSupport<T> delegate;
public DistinctOperationSupport(ExecutableFindSupport<T> delegate, String field) {
this.delegate = delegate;
this.field = field;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.DistinctWithProjection#as(java.lang.Class)
*/
@Override
@SuppressWarnings("unchecked")
public <R> TerminatingDistinct<R> as(Class<R> resultType) {
Assert.notNull(resultType, "ResultType must not be null!");
return new DistinctOperationSupport<>((ExecutableFindSupport) delegate.as(resultType), field);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.DistinctWithQuery#matching(org.springframework.data.mongodb.core.query.Query)
*/
@Override
public TerminatingDistinct<T> matching(Query query) {
Assert.notNull(query, "Query must not be null!");
return new DistinctOperationSupport<>((ExecutableFindSupport<T>) delegate.matching(query), field);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.TerminatingDistinct#all()
*/
@Override
public List<T> all() {
return delegate.doFindDistinct(field);
}
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2016-2018 the original author or authors. * Copyright 2016-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import org.springframework.util.Assert;
/** /**
* Value object to mitigate different representations of geo command execution results in MongoDB. * Value object to mitigate different representations of geo command execution results in MongoDB.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Christoph Strobl * @author Christoph Strobl
* @soundtrack Fruitcake - Jeff Coffin (The Inside of the Outside) * @soundtrack Fruitcake - Jeff Coffin (The Inside of the Outside)
@@ -34,7 +34,7 @@ class GeoCommandStatistics {
/** /**
* Creates a new {@link GeoCommandStatistics} instance with the given source document. * Creates a new {@link GeoCommandStatistics} instance with the given source document.
* *
* @param source must not be {@literal null}. * @param source must not be {@literal null}.
*/ */
private GeoCommandStatistics(Document source) { private GeoCommandStatistics(Document source) {
@@ -45,7 +45,7 @@ class GeoCommandStatistics {
/** /**
* Creates a new {@link GeoCommandStatistics} from the given command result extracting the statistics. * Creates a new {@link GeoCommandStatistics} from the given command result extracting the statistics.
* *
* @param commandResult must not be {@literal null}. * @param commandResult must not be {@literal null}.
* @return * @return
*/ */
@@ -60,7 +60,7 @@ class GeoCommandStatistics {
/** /**
* Returns the average distance reported by the command result. Mitigating a removal of the field in case the command * Returns the average distance reported by the command result. Mitigating a removal of the field in case the command
* didn't return any result introduced in MongoDB 3.2 RC1. * didn't return any result introduced in MongoDB 3.2 RC1.
* *
* @return * @return
* @see <a href="https://jira.mongodb.org/browse/SERVER-21024">MongoDB Jira SERVER-21024</a> * @see <a href="https://jira.mongodb.org/browse/SERVER-21024">MongoDB Jira SERVER-21024</a>
*/ */

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import com.mongodb.WriteConcern;
* <li>REMOVE has null document</li> * <li>REMOVE has null document</li>
* <li>INSERT_LIST has null entityType, document, and query</li> * <li>INSERT_LIST has null entityType, document, and query</li>
* </ul> * </ul>
* *
* @author Mark Pollack * @author Mark Pollack
* @author Oliver Gierke * @author Oliver Gierke
* @author Christoph Strobl * @author Christoph Strobl
@@ -46,7 +46,7 @@ public class MongoAction {
/** /**
* Create an instance of a {@link MongoAction}. * Create an instance of a {@link MongoAction}.
* *
* @param defaultWriteConcern the default write concern. Can be {@literal null}. * @param defaultWriteConcern the default write concern. Can be {@literal null}.
* @param mongoActionOperation action being taken against the collection. Must not be {@literal null}. * @param mongoActionOperation action being taken against the collection. Must not be {@literal null}.
* @param collectionName the collection name, must not be {@literal null} or empty. * @param collectionName the collection name, must not be {@literal null} or empty.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package org.springframework.data.mongodb.core;
/** /**
* Enumeration for operations on a collection. Used with {@link MongoAction} to help determine the WriteConcern to use * Enumeration for operations on a collection. Used with {@link MongoAction} to help determine the WriteConcern to use
* for a given mutating operation * for a given mutating operation
* *
* @author Mark Pollack * @author Mark Pollack
* @author Oliver Gierke * @author Oliver Gierke
* @see MongoAction * @see MongoAction

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2011-2018 the original author or authors. * Copyright 2011-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ import com.mongodb.client.MongoDatabase;
/** /**
* Mongo server administration exposed via JMX annotations * Mongo server administration exposed via JMX annotations
* *
* @author Mark Pollack * @author Mark Pollack
* @author Thomas Darimont * @author Thomas Darimont
* @author Mark Paluch * @author Mark Paluch

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2013-2018 the original author or authors. * Copyright 2013-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import com.mongodb.WriteResult;
/** /**
* Mongo-specific {@link DataIntegrityViolationException}. * Mongo-specific {@link DataIntegrityViolationException}.
* *
* @author Oliver Gierke * @author Oliver Gierke
*/ */
public class MongoDataIntegrityViolationException extends DataIntegrityViolationException { public class MongoDataIntegrityViolationException extends DataIntegrityViolationException {
@@ -35,7 +35,7 @@ public class MongoDataIntegrityViolationException extends DataIntegrityViolation
/** /**
* Creates a new {@link MongoDataIntegrityViolationException} using the given message and {@link WriteResult}. * Creates a new {@link MongoDataIntegrityViolationException} using the given message and {@link WriteResult}.
* *
* @param message the exception message * @param message the exception message
* @param writeResult the {@link WriteResult} that causes the exception, must not be {@literal null}. * @param writeResult the {@link WriteResult} that causes the exception, must not be {@literal null}.
* @param actionOperation the {@link MongoActionOperation} that caused the exception, must not be {@literal null}. * @param actionOperation the {@link MongoActionOperation} that caused the exception, must not be {@literal null}.
@@ -54,7 +54,7 @@ public class MongoDataIntegrityViolationException extends DataIntegrityViolation
/** /**
* Returns the {@link WriteResult} that caused the exception. * Returns the {@link WriteResult} that caused the exception.
* *
* @return the writeResult * @return the writeResult
*/ */
public WriteResult getWriteResult() { public WriteResult getWriteResult() {
@@ -63,7 +63,7 @@ public class MongoDataIntegrityViolationException extends DataIntegrityViolation
/** /**
* Returns the {@link MongoActionOperation} in which the current exception occured. * Returns the {@link MongoActionOperation} in which the current exception occured.
* *
* @return the actionOperation * @return the actionOperation
*/ */
public MongoActionOperation getActionOperation() { public MongoActionOperation getActionOperation() {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2018 the original author or authors. * Copyright 2010-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -29,7 +29,6 @@ import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.dao.PermissionDeniedDataAccessException; import org.springframework.dao.PermissionDeniedDataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.BulkOperationException; import org.springframework.data.mongodb.BulkOperationException;
import org.springframework.data.mongodb.ClientSessionException;
import org.springframework.data.mongodb.UncategorizedMongoDbException; import org.springframework.data.mongodb.UncategorizedMongoDbException;
import org.springframework.data.mongodb.util.MongoDbErrorCodes; import org.springframework.data.mongodb.util.MongoDbErrorCodes;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
@@ -45,7 +44,7 @@ import com.mongodb.bulk.BulkWriteError;
* Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate * Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate
* exception from the {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation is * exception from the {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation is
* appropriate: any other exception may have resulted from user code, and should not be translated. * appropriate: any other exception may have resulted from user code, and should not be translated.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Michal Vich * @author Michal Vich
* @author Christoph Strobl * @author Christoph Strobl
@@ -120,28 +119,18 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
int code = ((MongoException) ex).getCode(); int code = ((MongoException) ex).getCode();
if (MongoDbErrorCodes.isDuplicateKeyCode(code)) { if (MongoDbErrorCodes.isDuplicateKeyCode(code)) {
return new DuplicateKeyException(ex.getMessage(), ex); throw new DuplicateKeyException(ex.getMessage(), ex);
} else if (MongoDbErrorCodes.isDataAccessResourceFailureCode(code)) { } else if (MongoDbErrorCodes.isDataAccessResourceFailureCode(code)) {
return new DataAccessResourceFailureException(ex.getMessage(), ex); throw new DataAccessResourceFailureException(ex.getMessage(), ex);
} else if (MongoDbErrorCodes.isInvalidDataAccessApiUsageCode(code) || code == 10003 || code == 12001 } else if (MongoDbErrorCodes.isInvalidDataAccessApiUsageCode(code) || code == 10003 || code == 12001
|| code == 12010 || code == 12011 || code == 12012) { || code == 12010 || code == 12011 || code == 12012) {
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex); throw new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
} else if (MongoDbErrorCodes.isPermissionDeniedCode(code)) { } else if (MongoDbErrorCodes.isPermissionDeniedCode(code)) {
return new PermissionDeniedDataAccessException(ex.getMessage(), ex); throw new PermissionDeniedDataAccessException(ex.getMessage(), ex);
} }
return new UncategorizedMongoDbException(ex.getMessage(), ex); return new UncategorizedMongoDbException(ex.getMessage(), ex);
} }
// may interfere with OmitStackTraceInFastThrow (enabled by default).
// see https://jira.spring.io/browse/DATAMONGO-1905
if (ex instanceof IllegalStateException) {
for (StackTraceElement elm : ex.getStackTrace()) {
if (elm.getClassName().contains("ClientSession")) {
return new ClientSessionException(ex.getMessage(), ex);
}
}
}
// If we get here, we have an exception that resulted from user code, // If we get here, we have an exception that resulted from user code,
// rather than the persistence provider, so we return null to indicate // rather than the persistence provider, so we return null to indicate
// that translation should not occur. // that translation should not occur.

View File

@@ -18,8 +18,6 @@ package org.springframework.data.mongodb.core;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.bson.Document; import org.bson.Document;
import org.springframework.data.geo.GeoResults; import org.springframework.data.geo.GeoResults;
@@ -41,15 +39,12 @@ import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.util.CloseableIterator; import org.springframework.data.util.CloseableIterator;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import com.mongodb.ClientSessionOptions;
import com.mongodb.Cursor; import com.mongodb.Cursor;
import com.mongodb.ReadPreference; import com.mongodb.ReadPreference;
import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCollection;
import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult; import com.mongodb.client.result.UpdateResult;
import com.mongodb.session.ClientSession;
/** /**
* Interface that specifies a basic set of MongoDB operations. Implemented by {@link MongoTemplate}. Not often used but * Interface that specifies a basic set of MongoDB operations. Implemented by {@link MongoTemplate}. Not often used but
@@ -156,64 +151,6 @@ public interface MongoOperations extends FluentMongoOperations {
@Nullable @Nullable
<T> T execute(String collectionName, CollectionCallback<T> action); <T> T execute(String collectionName, CollectionCallback<T> action);
/**
* Obtain a {@link ClientSession session} bound instance of {@link SessionScoped} binding a new {@link ClientSession}
* with given {@literal sessionOptions} to each and every command issued against MongoDB.
*
* @param sessionOptions must not be {@literal null}.
* @return new instance of {@link SessionScoped}. Never {@literal null}.
* @since 2.1
*/
SessionScoped withSession(ClientSessionOptions sessionOptions);
/**
* Obtain a {@link ClientSession session} bound instance of {@link SessionScoped} binding the {@link ClientSession}
* provided by the given {@link Supplier} to each and every command issued against MongoDB.
* <p />
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle. Use the
* {@link SessionScoped#execute(SessionCallback, Consumer)} hook to potentially close the {@link ClientSession}.
*
* @param sessionProvider must not be {@literal null}.
* @since 2.1
*/
default SessionScoped withSession(Supplier<ClientSession> sessionProvider) {
Assert.notNull(sessionProvider, "SessionProvider must not be null!");
return new SessionScoped() {
private final Object lock = new Object();
private @Nullable ClientSession session = null;
@Override
public <T> T execute(SessionCallback<T> action, Consumer<ClientSession> onComplete) {
synchronized (lock) {
if (session == null) {
session = sessionProvider.get();
}
}
try {
return action.doInSession(MongoOperations.this.withSession(session));
} finally {
onComplete.accept(session);
}
}
};
}
/**
* Obtain a {@link ClientSession} bound instance of {@link MongoOperations}.
* <p />
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle.
*
* @param session must not be {@literal null}.
* @return {@link ClientSession} bound instance of {@link MongoOperations}.
* @since 2.1
*/
MongoOperations withSession(ClientSession session);
/** /**
* Executes the given {@link Query} on the entity collection of the specified {@code entityType} backed by a Mongo DB * Executes the given {@link Query} on the entity collection of the specified {@code entityType} backed by a Mongo DB
* {@link Cursor}. * {@link Cursor}.
@@ -773,67 +710,8 @@ public interface MongoOperations extends FluentMongoOperations {
<T> T findById(Object id, Class<T> entityClass, String collectionName); <T> T findById(Object id, Class<T> entityClass, String collectionName);
/** /**
* Finds the distinct values for a specified {@literal field} across a single {@link MongoCollection} or view and * Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify
* returns the results in a {@link List}. * <a/> to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
*
* @param field the name of the field to inspect for distinct values. Must not be {@literal null}.
* @param entityClass the domain type used for determining the actual {@link MongoCollection}. Must not be
* {@literal null}.
* @param resultClass the result type. Must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
default <T> List<T> findDistinct(String field, Class<?> entityClass, Class<T> resultClass) {
return findDistinct(new Query(), field, entityClass, resultClass);
}
/**
* Finds the distinct values for a specified {@literal field} across a single {@link MongoCollection} or view and
* returns the results in a {@link List}.
*
* @param query filter {@link Query} to restrict search. Must not be {@literal null}.
* @param field the name of the field to inspect for distinct values. Must not be {@literal null}.
* @param entityClass the domain type used for determining the actual {@link MongoCollection} and mapping the
* {@link Query} to the domain type fields. Must not be {@literal null}.
* @param resultClass the result type. Must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
<T> List<T> findDistinct(Query query, String field, Class<?> entityClass, Class<T> resultClass);
/**
* Finds the distinct values for a specified {@literal field} across a single {@link MongoCollection} or view and
* returns the results in a {@link List}.
*
* @param query filter {@link Query} to restrict search. Must not be {@literal null}.
* @param field the name of the field to inspect for distinct values. Must not be {@literal null}.
* @param collectionName the explicit name of the actual {@link MongoCollection}. Must not be {@literal null}.
* @param entityClass the domain type used for mapping the {@link Query} to the domain type fields.
* @param resultClass the result type. Must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
<T> List<T> findDistinct(Query query, String field, String collectionName, Class<?> entityClass,
Class<T> resultClass);
/**
* Finds the distinct values for a specified {@literal field} across a single {@link MongoCollection} or view and
* returns the results in a {@link List}.
*
* @param query filter {@link Query} to restrict search. Must not be {@literal null}.
* @param field the name of the field to inspect for distinct values. Must not be {@literal null}.
* @param collection the explicit name of the actual {@link MongoCollection}. Must not be {@literal null}.
* @param resultClass the result type. Must not be {@literal null}.
* @return never {@literal null}.
* @since 2.1
*/
default <T> List<T> findDistinct(Query query, String field, String collection, Class<T> resultClass) {
return findDistinct(query, field, collection, Object.class, resultClass);
}
/**
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify <a/>
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
* *
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional * @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
* fields specification. Must not be {@literal null}. * fields specification. Must not be {@literal null}.
@@ -845,8 +723,8 @@ public interface MongoOperations extends FluentMongoOperations {
<T> T findAndModify(Query query, Update update, Class<T> entityClass); <T> T findAndModify(Query query, Update update, Class<T> entityClass);
/** /**
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify <a/> * Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}. * <a/> to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
* *
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional * @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
* fields specification. Must not be {@literal null}. * fields specification. Must not be {@literal null}.
@@ -859,8 +737,8 @@ public interface MongoOperations extends FluentMongoOperations {
<T> T findAndModify(Query query, Update update, Class<T> entityClass, String collectionName); <T> T findAndModify(Query query, Update update, Class<T> entityClass, String collectionName);
/** /**
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify <a/> * Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking * <a/> to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
* {@link FindAndModifyOptions} into account. * {@link FindAndModifyOptions} into account.
* *
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional * @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
@@ -876,8 +754,8 @@ public interface MongoOperations extends FluentMongoOperations {
<T> T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass); <T> T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass);
/** /**
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify <a/> * Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking * <a/> to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
* {@link FindAndModifyOptions} into account. * {@link FindAndModifyOptions} into account.
* *
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional * @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional

View File

@@ -27,11 +27,8 @@ import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.bson.BsonValue;
import org.bson.Document; import org.bson.Document;
import org.bson.codecs.Codec;
import org.bson.conversions.Bson; import org.bson.conversions.Bson;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -57,8 +54,6 @@ import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metric; import org.springframework.data.geo.Metric;
import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.mapping.PropertyReferenceException;
import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.MongoDbFactory;
@@ -71,7 +66,14 @@ import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.Fields; import org.springframework.data.mongodb.core.aggregation.Fields;
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext; import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation; import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.convert.*; 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.MongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.convert.MongoWriter;
import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.convert.UpdateMapper;
import org.springframework.data.mongodb.core.index.IndexOperations; import org.springframework.data.mongodb.core.index.IndexOperations;
import org.springframework.data.mongodb.core.index.IndexOperationsProvider; import org.springframework.data.mongodb.core.index.IndexOperationsProvider;
import org.springframework.data.mongodb.core.index.MongoMappingEventPublisher; import org.springframework.data.mongodb.core.index.MongoMappingEventPublisher;
@@ -98,7 +100,6 @@ import org.springframework.data.mongodb.core.query.Meta;
import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.core.validation.Validator;
import org.springframework.data.mongodb.util.MongoClientVersion; import org.springframework.data.mongodb.util.MongoClientVersion;
import org.springframework.data.projection.ProjectionInformation; import org.springframework.data.projection.ProjectionInformation;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
@@ -115,7 +116,6 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.ResourceUtils; import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.mongodb.ClientSessionOptions;
import com.mongodb.Cursor; import com.mongodb.Cursor;
import com.mongodb.DBCollection; import com.mongodb.DBCollection;
import com.mongodb.DBCursor; import com.mongodb.DBCursor;
@@ -125,17 +125,21 @@ import com.mongodb.MongoException;
import com.mongodb.ReadPreference; import com.mongodb.ReadPreference;
import com.mongodb.WriteConcern; import com.mongodb.WriteConcern;
import com.mongodb.client.AggregateIterable; import com.mongodb.client.AggregateIterable;
import com.mongodb.client.DistinctIterable;
import com.mongodb.client.FindIterable; import com.mongodb.client.FindIterable;
import com.mongodb.client.MapReduceIterable; import com.mongodb.client.MapReduceIterable;
import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable; import com.mongodb.client.model.CountOptions;
import com.mongodb.client.model.*; import com.mongodb.client.model.CreateCollectionOptions;
import com.mongodb.client.model.DeleteOptions;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.FindOneAndDeleteOptions;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult; import com.mongodb.client.result.UpdateResult;
import com.mongodb.session.ClientSession;
import com.mongodb.util.JSONParseException; import com.mongodb.util.JSONParseException;
/** /**
@@ -158,8 +162,6 @@ import com.mongodb.util.JSONParseException;
* @author Laszlo Csontos * @author Laszlo Csontos
* @author Maninder Singh * @author Maninder Singh
* @author Borislav Rangelov * @author Borislav Rangelov
* @author duozhilin
* @author Andreas Zink
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class MongoTemplate implements MongoOperations, ApplicationContextAware, IndexOperationsProvider { public class MongoTemplate implements MongoOperations, ApplicationContextAware, IndexOperationsProvider {
@@ -185,7 +187,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
private final PersistenceExceptionTranslator exceptionTranslator; private final PersistenceExceptionTranslator exceptionTranslator;
private final QueryMapper queryMapper; private final QueryMapper queryMapper;
private final UpdateMapper updateMapper; private final UpdateMapper updateMapper;
private final JsonSchemaMapper schemaMapper;
private final SpelAwareProxyProjectionFactory projectionFactory; private final SpelAwareProxyProjectionFactory projectionFactory;
private @Nullable WriteConcern writeConcern; private @Nullable WriteConcern writeConcern;
@@ -203,7 +204,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* @param databaseName must not be {@literal null} or empty. * @param databaseName must not be {@literal null} or empty.
*/ */
public MongoTemplate(MongoClient mongoClient, String databaseName) { public MongoTemplate(MongoClient mongoClient, String databaseName) {
this(new SimpleMongoDbFactory(mongoClient, databaseName), (MongoConverter) null); this(new SimpleMongoDbFactory(mongoClient, databaseName), null);
} }
/** /**
@@ -212,7 +213,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* @param mongoDbFactory must not be {@literal null}. * @param mongoDbFactory must not be {@literal null}.
*/ */
public MongoTemplate(MongoDbFactory mongoDbFactory) { public MongoTemplate(MongoDbFactory mongoDbFactory) {
this(mongoDbFactory, (MongoConverter) null); this(mongoDbFactory, null);
} }
/** /**
@@ -230,7 +231,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
this.mongoConverter = mongoConverter == null ? getDefaultMongoConverter(mongoDbFactory) : mongoConverter; this.mongoConverter = mongoConverter == null ? getDefaultMongoConverter(mongoDbFactory) : mongoConverter;
this.queryMapper = new QueryMapper(this.mongoConverter); this.queryMapper = new QueryMapper(this.mongoConverter);
this.updateMapper = new UpdateMapper(this.mongoConverter); this.updateMapper = new UpdateMapper(this.mongoConverter);
this.schemaMapper = new MongoJsonSchemaMapper(this.mongoConverter);
this.projectionFactory = new SpelAwareProxyProjectionFactory(); this.projectionFactory = new SpelAwareProxyProjectionFactory();
// We always have a mapping context in the converter, whether it's a simple one or not // We always have a mapping context in the converter, whether it's a simple one or not
@@ -245,19 +245,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
} }
} }
private MongoTemplate(MongoDbFactory dbFactory, MongoTemplate that) {
this.mongoDbFactory = dbFactory;
this.exceptionTranslator = that.exceptionTranslator;
this.mongoConverter = that.mongoConverter instanceof MappingMongoConverter ? getDefaultMongoConverter(dbFactory)
: that.mongoConverter;
this.queryMapper = that.queryMapper;
this.updateMapper = that.updateMapper;
this.schemaMapper = that.schemaMapper;
this.projectionFactory = that.projectionFactory;
this.mappingContext = that.mappingContext;
}
/** /**
* Configures the {@link WriteResultChecking} to be used with the template. Setting {@literal null} will reset the * Configures the {@link WriteResultChecking} to be used with the template. Setting {@literal null} will reset the
* default of {@link #DEFAULT_WRITE_RESULT_CHECKING}. * default of {@link #DEFAULT_WRITE_RESULT_CHECKING}.
@@ -391,7 +378,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), persistentEntity); Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), persistentEntity);
FindIterable<Document> cursor = new QueryCursorPreparer(query, entityType) FindIterable<Document> cursor = new QueryCursorPreparer(query, entityType)
.prepare(collection.find(mappedQuery, Document.class).projection(mappedFields)); .prepare(collection.find(mappedQuery).projection(mappedFields));
return new CloseableIterableCursorAdapter<T>(cursor, exceptionTranslator, return new CloseableIterableCursorAdapter<T>(cursor, exceptionTranslator,
new ProjectingReadCallback<>(mongoConverter, entityType, returnType, collectionName)); new ProjectingReadCallback<>(mongoConverter, entityType, returnType, collectionName));
@@ -503,10 +490,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
*/ */
public <T> T execute(DbCallback<T> action) { public <T> T execute(DbCallback<T> action) {
Assert.notNull(action, "DbCallback must not be null!"); Assert.notNull(action, "DbCallbackmust not be null!");
try { try {
MongoDatabase db = prepareDatabase(this.doGetDatabase()); MongoDatabase db = this.getDb();
return action.doInDB(db); return action.doInDB(db);
} catch (RuntimeException e) { } catch (RuntimeException e) {
throw potentiallyConvertRuntimeException(e, exceptionTranslator); throw potentiallyConvertRuntimeException(e, exceptionTranslator);
@@ -533,37 +520,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
Assert.notNull(callback, "CollectionCallback must not be null!"); Assert.notNull(callback, "CollectionCallback must not be null!");
try { try {
MongoCollection<Document> collection = getAndPrepareCollection(doGetDatabase(), collectionName); MongoCollection<Document> collection = getAndPrepareCollection(getDb(), collectionName);
return callback.doInCollection(collection); return callback.doInCollection(collection);
} catch (RuntimeException e) { } catch (RuntimeException e) {
throw potentiallyConvertRuntimeException(e, exceptionTranslator); throw potentiallyConvertRuntimeException(e, exceptionTranslator);
} }
} }
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#withSession(com.mongodb.ClientSessionOptions)
*/
@Override
public SessionScoped withSession(ClientSessionOptions options) {
Assert.notNull(options, "ClientSessionOptions must not be null!");
return withSession(() -> mongoDbFactory.getSession(options));
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#withSession(com.mongodb.session.ClientSession)
*/
@Override
public MongoTemplate withSession(ClientSession session) {
Assert.notNull(session, "ClientSession must not be null!");
return new SessionBoundMongoTemplate(session, MongoTemplate.this);
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#createCollection(java.lang.Class) * @see org.springframework.data.mongodb.core.MongoOperations#createCollection(java.lang.Class)
@@ -578,9 +541,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
*/ */
public <T> MongoCollection<Document> createCollection(Class<T> entityClass, public <T> MongoCollection<Document> createCollection(Class<T> entityClass,
@Nullable CollectionOptions collectionOptions) { @Nullable CollectionOptions collectionOptions) {
return createCollection(determineCollectionName(entityClass), collectionOptions);
Assert.notNull(entityClass, "EntityClass must not be null!");
return doCreateCollection(determineCollectionName(entityClass), convertToDocument(collectionOptions, entityClass));
} }
/* /*
@@ -607,7 +568,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#getCollection(java.lang.String) * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#getCollection(java.lang.String)
*/ */
public MongoCollection<Document> getCollection(final String collectionName) { public MongoCollection<Document> getCollection(final String collectionName) {
@@ -638,7 +599,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return execute(new DbCallback<Boolean>() { return execute(new DbCallback<Boolean>() {
public Boolean doInDB(MongoDatabase db) throws MongoException, DataAccessException { public Boolean doInDB(MongoDatabase db) throws MongoException, DataAccessException {
for (String name : db.listCollectionNames()) { for (String name : db.listCollectionNames()) {
if (name.equals(collectionName)) { if (name.equals(collectionName)) {
return true; return true;
@@ -681,7 +641,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#indexOps(java.lang.String) * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#indexOps(java.lang.String)
*/ */
public IndexOperations indexOps(String collectionName) { public IndexOperations indexOps(String collectionName) {
return new DefaultIndexOperations(this, collectionName, null); return new DefaultIndexOperations(getMongoDbFactory(), collectionName, queryMapper);
} }
/* /*
@@ -689,7 +649,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#indexOps(java.lang.Class) * @see org.springframework.data.mongodb.core.ExecutableInsertOperation#indexOps(java.lang.Class)
*/ */
public IndexOperations indexOps(Class<?> entityClass) { public IndexOperations indexOps(Class<?> entityClass) {
return new DefaultIndexOperations(this, determineCollectionName(entityClass), entityClass); return new DefaultIndexOperations(getMongoDbFactory(), determineCollectionName(entityClass), queryMapper,
entityClass);
} }
/* /*
@@ -836,87 +797,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return doFindOne(collectionName, new Document(idKey, id), new Document(), entityClass); return doFindOne(collectionName, new Document(idKey, id), new Document(), entityClass);
} }
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#findDistinct(org.springframework.data.mongodb.core.query.Query, java.lang.String, java.lang.Class, java.lang.Class)
*/
@Override
public <T> List<T> findDistinct(Query query, String field, Class<?> entityClass, Class<T> resultClass) {
return findDistinct(query, field, determineCollectionName(entityClass), entityClass, resultClass);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#findDistinct(org.springframework.data.mongodb.core.query.Query, java.lang.String, java.lang.String, java.lang.Class, java.lang.Class)
*/
@Override
@SuppressWarnings("unchecked")
public <T> List<T> findDistinct(Query query, String field, String collectionName, Class<?> entityClass,
Class<T> resultClass) {
Assert.notNull(query, "Query must not be null!");
Assert.notNull(field, "Field must not be null!");
Assert.notNull(collectionName, "CollectionName must not be null!");
Assert.notNull(entityClass, "EntityClass must not be null!");
Assert.notNull(resultClass, "ResultClass must not be null!");
MongoPersistentEntity<?> entity = entityClass != Object.class ? getPersistentEntity(entityClass) : null;
Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), entity);
String mappedFieldName = queryMapper.getMappedFields(new Document(field, 1), entity).keySet().iterator().next();
Class<T> mongoDriverCompatibleType = getMongoDbFactory().getCodecFor(resultClass).map(Codec::getEncoderClass)
.orElse((Class) BsonValue.class);
MongoIterable<?> result = execute(collectionName, (collection) -> {
DistinctIterable<T> iterable = collection.distinct(mappedFieldName, mappedQuery, mongoDriverCompatibleType);
return query.getCollation().map(Collation::toMongoCollation).map(iterable::collation).orElse(iterable);
});
if (resultClass == Object.class || mongoDriverCompatibleType != resultClass) {
MongoConverter converter = getConverter();
DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
result = result.map((source) -> converter.mapValueToTargetType(source,
getMostSpecificConversionTargetType(resultClass, entityClass, field), dbRefResolver));
}
try {
return (List<T>) result.into(new ArrayList<>());
} catch (RuntimeException e) {
throw potentiallyConvertRuntimeException(e, exceptionTranslator);
}
}
/**
* @param userType must not be {@literal null}.
* @param domainType must not be {@literal null}.
* @param field must not be {@literal null}.
* @return the most specific conversion target type depending on user preference and domain type property.
* @since 2.1
*/
private static Class<?> getMostSpecificConversionTargetType(Class<?> userType, Class<?> domainType, String field) {
Class<?> conversionTargetType = userType;
try {
Class<?> propertyType = PropertyPath.from(field, domainType).getLeafProperty().getLeafType();
// use the more specific type but favor UserType over property one
if (ClassUtils.isAssignable(userType, propertyType)) {
conversionTargetType = propertyType;
}
} catch (PropertyReferenceException e) {
// just don't care about it as we default to Object.class anyway.
}
return conversionTargetType;
}
@Override @Override
public <T> GeoResults<T> geoNear(NearQuery near, Class<T> entityClass) { public <T> GeoResults<T> geoNear(NearQuery near, Class<T> entityClass) {
return geoNear(near, entityClass, determineCollectionName(entityClass)); return geoNear(near, entityClass, determineCollectionName(entityClass));
@@ -1075,13 +955,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
Assert.notNull(query, "Query must not be null!"); Assert.notNull(query, "Query must not be null!");
Assert.hasText(collectionName, "Collection name must not be null or empty!"); Assert.hasText(collectionName, "Collection name must not be null or empty!");
CountOptions options = new CountOptions();
query.getCollation().map(Collation::toMongoCollation).ifPresent(options::collation);
Document document = queryMapper.getMappedObject(query.getQueryObject(), Document document = queryMapper.getMappedObject(query.getQueryObject(),
Optional.ofNullable(entityClass).map(it -> mappingContext.getPersistentEntity(entityClass))); Optional.ofNullable(entityClass).map(it -> mappingContext.getPersistentEntity(entityClass)));
return execute(collectionName, collection -> collection.count(document, options)); return execute(collectionName, collection -> collection.count(document));
} }
/* /*
@@ -1128,9 +1005,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
protected MongoCollection<Document> prepareCollection(MongoCollection<Document> collection) { protected MongoCollection<Document> prepareCollection(MongoCollection<Document> collection) {
if (this.readPreference != null) { if (this.readPreference != null) {
collection = collection.withReadPreference(readPreference); return collection.withReadPreference(readPreference);
} }
return collection; return collection;
} }
@@ -1396,7 +1272,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT, collectionName, MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT, collectionName,
entityClass, document, null); entityClass, document, null);
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction); WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
if (writeConcernToUse == null) { if (writeConcernToUse == null) {
collection.insertOne(document); collection.insertOne(document);
} else { } else {
@@ -1751,6 +1626,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
} }
if (writeConcernToUse == null) { if (writeConcernToUse == null) {
dr = collection.deleteMany(removeQuery, options); dr = collection.deleteMany(removeQuery, options);
} else { } else {
dr = collection.withWriteConcern(writeConcernToUse).deleteMany(removeQuery, options); dr = collection.withWriteConcern(writeConcernToUse).deleteMany(removeQuery, options);
@@ -1806,10 +1682,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
String mapFunc = replaceWithResourceIfNecessary(mapFunction); String mapFunc = replaceWithResourceIfNecessary(mapFunction);
String reduceFunc = replaceWithResourceIfNecessary(reduceFunction); String reduceFunc = replaceWithResourceIfNecessary(reduceFunction);
MongoCollection<Document> inputCollection = getAndPrepareCollection(doGetDatabase(), inputCollectionName); MongoCollection<Document> inputCollection = getCollection(inputCollectionName);
// MapReduceOp // MapReduceOp
MapReduceIterable<Document> result = inputCollection.mapReduce(mapFunc, reduceFunc, Document.class); MapReduceIterable<Document> result = inputCollection.mapReduce(mapFunc, reduceFunc);
if (query != null && result != null) { if (query != null && result != null) {
if (query.getLimit() > 0 && mapReduceOptions.getLimit() == null) { if (query.getLimit() > 0 && mapReduceOptions.getLimit() == null) {
@@ -1892,13 +1768,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
} }
if (document.containsKey("$reduce")) { if (document.containsKey("$reduce")) {
document.put("$reduce", replaceWithResourceIfNecessary(ObjectUtils.nullSafeToString(document.get("$reduce")))); document.put("$reduce", replaceWithResourceIfNecessary(document.get("$reduce").toString()));
} }
if (document.containsKey("$keyf")) { if (document.containsKey("$keyf")) {
document.put("$keyf", replaceWithResourceIfNecessary(ObjectUtils.nullSafeToString(document.get("$keyf")))); document.put("$keyf", replaceWithResourceIfNecessary(document.get("$keyf").toString()));
} }
if (document.containsKey("finalize")) { if (document.containsKey("finalize")) {
document.put("finalize", replaceWithResourceIfNecessary(ObjectUtils.nullSafeToString(document.get("finalize")))); document.put("finalize", replaceWithResourceIfNecessary(document.get("finalize").toString()));
} }
Document commandObject = new Document("group", document); Document commandObject = new Document("group", document);
@@ -1907,7 +1783,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
LOGGER.debug("Executing Group with Document [{}]", serializeToJsonSafely(commandObject)); LOGGER.debug("Executing Group with Document [{}]", serializeToJsonSafely(commandObject));
} }
Document commandResult = executeCommand(commandObject, this.readPreference); Document commandResult = executeCommand(commandObject);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Group command result = [{}]", commandResult); LOGGER.debug("Group command result = [{}]", commandResult);
@@ -2057,94 +1933,82 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
Assert.notNull(aggregation, "Aggregation pipeline must not be null!"); Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
Assert.notNull(outputType, "Output type must not be null!"); Assert.notNull(outputType, "Output type must not be null!");
AggregationOperationContext rootContext = context == null ? Aggregation.DEFAULT_CONTEXT : context; Document commandResult = new BatchAggregationLoader(this, readPreference, Integer.MAX_VALUE)
.aggregate(collectionName, aggregation, context);
return doAggregate(aggregation, collectionName, outputType, rootContext); return new AggregationResults<>(returnPotentiallyMappedResults(outputType, commandResult, collectionName),
commandResult);
} }
@SuppressWarnings("ConstantConditions") /**
protected <O> AggregationResults<O> doAggregate(Aggregation aggregation, String collectionName, Class<O> outputType, * Returns the potentially mapped results of the given {@code commandResult}.
AggregationOperationContext context) { *
* @param outputType
* @param commandResult
* @return
*/
private <O> List<O> returnPotentiallyMappedResults(Class<O> outputType, Document commandResult,
String collectionName) {
DocumentCallback<O> callback = new UnwrapAndReadDocumentCallback<>(mongoConverter, outputType, collectionName); @SuppressWarnings("unchecked")
Iterable<Document> resultSet = (Iterable<Document>) commandResult.get("result");
AggregationOptions options = aggregation.getOptions(); if (resultSet == null) {
if (options.isExplain()) { return Collections.emptyList();
Document command = aggregation.toDocument(collectionName, context);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Executing aggregation: {}", serializeToJsonSafely(command));
}
Document commandResult = executeCommand(command);
return new AggregationResults<>(commandResult.get("results", new ArrayList<Document>(0)).stream()
.map(callback::doWith).collect(Collectors.toList()), commandResult);
} }
List<Document> pipeline = aggregation.toPipeline(context); DocumentCallback<O> callback = new UnwrapAndReadDocumentCallback<O>(mongoConverter, outputType, collectionName);
if (LOGGER.isDebugEnabled()) { List<O> mappedResults = new ArrayList<O>();
LOGGER.debug("Executing aggregation: {} in collection {}", serializeToJsonSafely(pipeline), collectionName); for (Document document : resultSet) {
mappedResults.add(callback.doWith(document));
} }
return execute(collectionName, collection -> { return mappedResults;
List<Document> rawResult = new ArrayList<>();
AggregateIterable<Document> aggregateIterable = collection.aggregate(pipeline, Document.class) //
.collation(options.getCollation().map(Collation::toMongoCollation).orElse(null)) //
.allowDiskUse(options.isAllowDiskUse());
if (options.getCursorBatchSize() != null) {
aggregateIterable = aggregateIterable.batchSize(options.getCursorBatchSize());
}
MongoIterable<O> iterable = aggregateIterable.map(val -> {
rawResult.add(val);
return callback.doWith(val);
});
return new AggregationResults<>(iterable.into(new ArrayList<>()),
new Document("results", rawResult).append("ok", 1.0D));
});
} }
@SuppressWarnings("ConstantConditions")
protected <O> CloseableIterator<O> aggregateStream(Aggregation aggregation, String collectionName, protected <O> CloseableIterator<O> aggregateStream(Aggregation aggregation, String collectionName,
Class<O> outputType, @Nullable AggregationOperationContext context) { Class<O> outputType, @Nullable AggregationOperationContext context) {
Assert.hasText(collectionName, "Collection name must not be null or empty!"); Assert.hasText(collectionName, "Collection name must not be null or empty!");
Assert.notNull(aggregation, "Aggregation pipeline must not be null!"); Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
Assert.notNull(outputType, "Output type must not be null!"); Assert.notNull(outputType, "Output type must not be null!");
Assert.isTrue(!aggregation.getOptions().isExplain(), "Can't use explain option with streaming!");
AggregationOperationContext rootContext = context == null ? Aggregation.DEFAULT_CONTEXT : context; AggregationOperationContext rootContext = context == null ? Aggregation.DEFAULT_CONTEXT : context;
AggregationOptions options = aggregation.getOptions();
List<Document> pipeline = aggregation.toPipeline(rootContext); Document command = aggregation.toDocument(collectionName, rootContext);
assertNotExplain(command);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Streaming aggregation: {} in collection {}", serializeToJsonSafely(pipeline), collectionName); LOGGER.debug("Streaming aggregation: {}", serializeToJsonSafely(command));
} }
ReadDocumentCallback<O> readCallback = new ReadDocumentCallback<>(mongoConverter, outputType, collectionName); ReadDocumentCallback<O> readCallback = new ReadDocumentCallback<O>(mongoConverter, outputType, collectionName);
return execute(collectionName, (CollectionCallback<CloseableIterator<O>>) collection -> { return execute(collectionName, new CollectionCallback<CloseableIterator<O>>() {
AggregateIterable<Document> cursor = collection.aggregate(pipeline, Document.class) // @Override
.allowDiskUse(options.isAllowDiskUse()) // public CloseableIterator<O> doInCollection(MongoCollection<Document> collection)
.useCursor(true); throws MongoException, DataAccessException {
if (options.getCursorBatchSize() != null) { List<Document> pipeline = (List<Document>) command.get("pipeline");
cursor = cursor.batchSize(options.getCursorBatchSize());
AggregationOptions options = AggregationOptions.fromDocument(command);
AggregateIterable<Document> cursor = collection.aggregate(pipeline).allowDiskUse(options.isAllowDiskUse())
.useCursor(true);
Integer cursorBatchSize = options.getCursorBatchSize();
if (cursorBatchSize != null) {
cursor = cursor.batchSize(cursorBatchSize);
}
if (options.getCollation().isPresent()) {
cursor = cursor.collation(options.getCollation().map(Collation::toMongoCollation).get());
}
return new CloseableIterableCursorAdapter<O>(cursor.iterator(), exceptionTranslator, readCallback);
} }
if (options.getCollation().isPresent()) {
cursor = cursor.collation(options.getCollation().map(Collation::toMongoCollation).get());
}
return new CloseableIterableCursorAdapter<>(cursor.iterator(), exceptionTranslator, readCallback);
}); });
} }
@@ -2193,6 +2057,20 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return new ExecutableInsertOperationSupport(this).insert(domainType); return new ExecutableInsertOperationSupport(this).insert(domainType);
} }
/**
* Assert that the {@link Document} does not enable Aggregation explain mode.
*
* @param command the command {@link Document}.
*/
private void assertNotExplain(Document command) {
Boolean explain = command.get("explain", Boolean.class);
if (explain != null && explain) {
throw new IllegalArgumentException("Can't use explain option with streaming!");
}
}
protected String replaceWithResourceIfNecessary(String function) { protected String replaceWithResourceIfNecessary(String function) {
String func = function; String func = function;
@@ -2239,17 +2117,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
} }
public MongoDatabase getDb() { public MongoDatabase getDb() {
return doGetDatabase();
}
protected MongoDatabase doGetDatabase() {
return mongoDbFactory.getDb(); return mongoDbFactory.getDb();
} }
protected MongoDatabase prepareDatabase(MongoDatabase database) {
return database;
}
protected <T> void maybeEmitEvent(MongoMappingEvent<T> event) { protected <T> void maybeEmitEvent(MongoMappingEvent<T> event) {
if (null != eventPublisher) { if (null != eventPublisher) {
eventPublisher.publishEvent(event); eventPublisher.publishEvent(event);
@@ -2284,21 +2154,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
co.collation(IndexConverters.fromDocument(collectionOptions.get("collation", Document.class))); co.collation(IndexConverters.fromDocument(collectionOptions.get("collation", Document.class)));
} }
if (collectionOptions.containsKey("validator")) {
com.mongodb.client.model.ValidationOptions options = new com.mongodb.client.model.ValidationOptions();
if (collectionOptions.containsKey("validationLevel")) {
options.validationLevel(ValidationLevel.fromString(collectionOptions.getString("validationLevel")));
}
if (collectionOptions.containsKey("validationAction")) {
options.validationAction(ValidationAction.fromString(collectionOptions.getString("validationAction")));
}
options.validator(collectionOptions.get("validator", Document.class));
co.validationOptions(options);
}
db.createCollection(collectionName, co); db.createCollection(collectionName, co);
MongoCollection<Document> coll = db.getCollection(collectionName, Document.class); MongoCollection<Document> coll = db.getCollection(collectionName, Document.class);
@@ -2411,70 +2266,19 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
new ProjectingReadCallback<>(mongoConverter, sourceClass, targetClass, collectionName), collectionName); new ProjectingReadCallback<>(mongoConverter, sourceClass, targetClass, collectionName), collectionName);
} }
/**
* Convert given {@link CollectionOptions} to a document and take the domain type information into account when
* creating a mapped schema for validation. <br />
* This method calls {@link #convertToDocument(CollectionOptions)} for backwards compatibility and potentially
* overwrites the validator with the mapped validator document. In the long run
* {@link #convertToDocument(CollectionOptions)} will be removed so that this one becomes the only source of truth.
*
* @param collectionOptions can be {@literal null}.
* @param targetType must not be {@literal null}. Use {@link Object} type instead.
* @return never {@literal null}.
* @since 2.1
*/
protected Document convertToDocument(@Nullable CollectionOptions collectionOptions, Class<?> targetType) {
Document doc = convertToDocument(collectionOptions);
if (collectionOptions != null) {
collectionOptions.getValidationOptions().ifPresent(it -> it.getValidator() //
.ifPresent(val -> doc.put("validator", getMappedValidator(val, targetType))));
}
return doc;
}
/**
* @param collectionOptions can be {@literal null}.
* @return never {@literal null}.
* @deprecated since 2.1 in favor of {@link #convertToDocument(CollectionOptions, Class)}.
*/
@Deprecated
protected Document convertToDocument(@Nullable CollectionOptions collectionOptions) { protected Document convertToDocument(@Nullable CollectionOptions collectionOptions) {
Document document = new Document(); Document document = new Document();
if (collectionOptions != null) { if (collectionOptions != null) {
collectionOptions.getCapped().ifPresent(val -> document.put("capped", val)); collectionOptions.getCapped().ifPresent(val -> document.put("capped", val));
collectionOptions.getSize().ifPresent(val -> document.put("size", val)); collectionOptions.getSize().ifPresent(val -> document.put("size", val));
collectionOptions.getMaxDocuments().ifPresent(val -> document.put("max", val)); collectionOptions.getMaxDocuments().ifPresent(val -> document.put("max", val));
collectionOptions.getCollation().ifPresent(val -> document.append("collation", val.toDocument())); collectionOptions.getCollation().ifPresent(val -> document.append("collation", val.toDocument()));
collectionOptions.getValidationOptions().ifPresent(it -> {
it.getValidationLevel().ifPresent(val -> document.append("validationLevel", val.getValue()));
it.getValidationAction().ifPresent(val -> document.append("validationAction", val.getValue()));
it.getValidator().ifPresent(val -> document.append("validator", getMappedValidator(val, Object.class)));
});
} }
return document; return document;
} }
Document getMappedValidator(Validator validator, Class<?> domainType) {
Document validationRules = validator.toDocument();
if (validationRules.containsKey("$jsonSchema")) {
return schemaMapper.mapSchema(validationRules, domainType);
}
return queryMapper.getMappedObject(validationRules, mappingContext.getPersistentEntity(domainType));
}
/** /**
* Map the results of an ad-hoc query on the default MongoDB collection to an object using the template's converter. * Map the results of an ad-hoc query on the default MongoDB collection to an object using the template's converter.
* The first document that matches the query is returned and also removed from the collection in the database. * The first document that matches the query is returned and also removed from the collection in the database.
@@ -2536,18 +2340,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* @param savedObject * @param savedObject
* @param id * @param id
*/ */
@SuppressWarnings("unchecked")
protected void populateIdIfNecessary(Object savedObject, Object id) { protected void populateIdIfNecessary(Object savedObject, Object id) {
if (id == null) { if (id == null) {
return; return;
} }
if (savedObject instanceof Map) { if (savedObject instanceof Document) {
Document document = (Document) savedObject;
Map<String, Object> map = (Map<String, Object>) savedObject; document.put(ID_FIELD, id);
map.put(ID_FIELD, id);
return; return;
} }
@@ -2595,7 +2396,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
try { try {
T result = objectCallback T result = objectCallback
.doWith(collectionCallback.doInCollection(getAndPrepareCollection(doGetDatabase(), collectionName))); .doWith(collectionCallback.doInCollection(getAndPrepareCollection(getDb(), collectionName)));
return result; return result;
} catch (RuntimeException e) { } catch (RuntimeException e) {
throw potentiallyConvertRuntimeException(e, exceptionTranslator); throw potentiallyConvertRuntimeException(e, exceptionTranslator);
@@ -2630,7 +2431,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
try { try {
FindIterable<Document> iterable = collectionCallback FindIterable<Document> iterable = collectionCallback
.doInCollection(getAndPrepareCollection(doGetDatabase(), collectionName)); .doInCollection(getAndPrepareCollection(getDb(), collectionName));
if (preparer != null) { if (preparer != null) {
iterable = preparer.prepare(iterable); iterable = preparer.prepare(iterable);
@@ -2666,7 +2467,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
try { try {
FindIterable<Document> iterable = collectionCallback FindIterable<Document> iterable = collectionCallback
.doInCollection(getAndPrepareCollection(doGetDatabase(), collectionName)); .doInCollection(getAndPrepareCollection(getDb(), collectionName));
if (preparer != null) { if (preparer != null) {
iterable = preparer.prepare(iterable); iterable = preparer.prepare(iterable);
@@ -2811,7 +2612,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
public Document doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException { public Document doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
FindIterable<Document> iterable = collection.find(query, Document.class); FindIterable<Document> iterable = collection.find(query);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
@@ -2856,7 +2657,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
public FindIterable<Document> doInCollection(MongoCollection<Document> collection) public FindIterable<Document> doInCollection(MongoCollection<Document> collection)
throws MongoException, DataAccessException { throws MongoException, DataAccessException {
return collection.find(query, Document.class).projection(fields); return collection.find(query).projection(fields);
} }
} }
@@ -3410,52 +3211,4 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return ((Document) commandResult.get(CURSOR_FIELD)).get("id"); return ((Document) commandResult.get(CURSOR_FIELD)).get("id");
} }
} }
/**
* {@link MongoTemplate} extension bound to a specific {@link ClientSession} that is applied when interacting with the
* server through the driver API.
* <p />
* The prepare steps for {@link MongoDatabase} and {@link MongoCollection} proxy the target and invoke the desired
* target method matching the actual arguments plus a {@link ClientSession}.
*
* @author Christoph Strobl
* @since 2.1
*/
static class SessionBoundMongoTemplate extends MongoTemplate {
private final MongoTemplate delegate;
/**
* @param session must not be {@literal null}.
* @param that must not be {@literal null}.
*/
SessionBoundMongoTemplate(ClientSession session, MongoTemplate that) {
super(that.getMongoDbFactory().withSession(session), that);
this.delegate = that;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoTemplate#getCollection(java.lang.String)
*/
@Override
public MongoCollection<Document> getCollection(String collectionName) {
// native MongoDB objects that offer methods with ClientSession must not be proxied.
return delegate.getCollection(collectionName);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoTemplate#getDb()
*/
@Override
public MongoDatabase getDb() {
// native MongoDB objects that offer methods with ClientSession must not be proxied.
return delegate.getDb();
}
}
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2017-2018 the original author or authors. * Copyright 2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -156,7 +156,7 @@ public interface ReactiveFindOperation {
/** /**
* Result type override (optional). * Result type override (optional).
*/ */
interface FindWithProjection<T> extends FindWithQuery<T>, FindDistinct { interface FindWithProjection<T> extends FindWithQuery<T> {
/** /**
* Define the target type fields should be mapped to. <br /> * Define the target type fields should be mapped to. <br />
@@ -170,101 +170,8 @@ public interface ReactiveFindOperation {
<R> FindWithQuery<R> as(Class<R> resultType); <R> FindWithQuery<R> as(Class<R> resultType);
} }
/**
* Distinct Find support.
*
* @author Christoph Strobl
* @since 2.1
*/
interface FindDistinct {
/**
* Finds the distinct values for a specified {@literal field} across a single
* {@link com.mongodb.reactivestreams.client.MongoCollection} or view.
*
* @param field name of the field. Must not be {@literal null}.
* @return new instance of {@link TerminatingDistinct}.
* @throws IllegalArgumentException if field is {@literal null}.
*/
TerminatingDistinct<Object> distinct(String field);
}
/**
* Result type override. Optional.
*
* @author Christoph Strobl
* @since 2.1
*/
interface DistinctWithProjection {
/**
* Define the target type the result should be mapped to. <br />
* Skip this step if you are anyway fine with the default conversion.
* <dl>
* <dt>{@link Object} (the default)</dt>
* <dd>Result is mapped according to the {@link org.bson.BsonType} converting eg. {@link org.bson.BsonString} into
* plain {@link String}, {@link org.bson.BsonInt64} to {@link Long}, etc. always picking the most concrete type with
* respect to the domain types property.<br />
* Any {@link org.bson.BsonType#DOCUMENT} is run through the {@link org.springframework.data.convert.EntityReader}
* to obtain the domain type. <br />
* Using {@link Object} also works for non strictly typed fields. Eg. a mixture different types like fields using
* {@link String} in one {@link org.bson.Document} while {@link Long} in another.</dd>
* <dt>Any Simple type like {@link String}, {@link Long}, ...</dt>
* <dd>The result is mapped directly by the MongoDB Java driver and the {@link org.bson.codecs.CodeCodec Codecs} in
* place. This works only for results where all documents considered for the operation use the very same type for
* the field.</dd>
* <dt>Any Domain type</dt>
* <dd>Domain types can only be mapped if the if the result of the actual {@code distinct()} operation returns
* {@link org.bson.BsonType#DOCUMENT}.</dd>
* <dt>{@link org.bson.BsonValue}</dt>
* <dd>Using {@link org.bson.BsonValue} allows retrieval of the raw driver specific format, which returns eg.
* {@link org.bson.BsonString}.</dd>
* </dl>
*
* @param resultType must not be {@literal null}.
* @param <R> result type.
* @return new instance of {@link TerminatingDistinct}.
* @throws IllegalArgumentException if resultType is {@literal null}.
*/
<R> TerminatingDistinct<R> as(Class<R> resultType);
}
/**
* Result restrictions. Optional.
*
* @author Christoph Strobl
* @since 2.1
*/
interface DistinctWithQuery<T> extends DistinctWithProjection {
/**
* Set the filter query to be used.
*
* @param query must not be {@literal null}.
* @return new instance of {@link TerminatingDistinct}.
* @throws IllegalArgumentException if resultType is {@literal null}.
*/
TerminatingDistinct<T> matching(Query query);
}
/**
* Terminating distinct find operations.
*
* @author Christoph Strobl
* @since 2.1
*/
interface TerminatingDistinct<T> extends DistinctWithQuery<T> {
/**
* Get all matching distinct field values.
*
* @return empty {@link Flux} if not match found. Never {@literal null}.
*/
Flux<T> all();
}
/** /**
* {@link ReactiveFind} provides methods for constructing lookup operations in a fluent way. * {@link ReactiveFind} provides methods for constructing lookup operations in a fluent way.
*/ */
interface ReactiveFind<T> extends FindWithCollection<T>, FindWithProjection<T>, FindDistinct {} interface ReactiveFind<T> extends FindWithCollection<T>, FindWithProjection<T> {}
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2017-2018 the original author or authors. * Copyright 2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import lombok.AccessLevel;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import org.springframework.lang.Nullable;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@@ -27,7 +28,6 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.SerializationUtils; import org.springframework.data.mongodb.core.query.SerializationUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@@ -196,18 +196,6 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
return template.exists(query, domainType, getCollectionName()); return template.exists(query, domainType, getCollectionName());
} }
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.FindDistinct#distinct(java.lang.String)
*/
@Override
public TerminatingDistinct<Object> distinct(String field) {
Assert.notNull(field, "Field must not be null!");
return new DistinctOperationSupport<>(this, field);
}
private Flux<T> doFind(@Nullable FindPublisherPreparer preparer) { private Flux<T> doFind(@Nullable FindPublisherPreparer preparer) {
Document queryObject = query.getQueryObject(); Document queryObject = query.getQueryObject();
@@ -217,13 +205,6 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
preparer != null ? preparer : getCursorPreparer(query)); preparer != null ? preparer : getCursorPreparer(query));
} }
@SuppressWarnings("unchecked")
private Flux<T> doFindDistinct(String field) {
return template.findDistinct(query, field, getCollectionName(), domainType,
returnType == domainType ? (Class<T>) Object.class : returnType);
}
private FindPublisherPreparer getCursorPreparer(Query query) { private FindPublisherPreparer getCursorPreparer(Query query) {
return template.new QueryFindPublisherPreparer(query, domainType); return template.new QueryFindPublisherPreparer(query, domainType);
} }
@@ -235,55 +216,5 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
private String asString() { private String asString() {
return SerializationUtils.serializeToJsonSafely(query); return SerializationUtils.serializeToJsonSafely(query);
} }
/**
* @author Christoph Strobl
* @since 2.1
*/
static class DistinctOperationSupport<T> implements TerminatingDistinct<T> {
private final String field;
private final ReactiveFindSupport delegate;
public DistinctOperationSupport(ReactiveFindSupport delegate, String field) {
this.delegate = delegate;
this.field = field;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.DistinctWithProjection#as(java.lang.Class)
*/
@Override
public <R> TerminatingDistinct<R> as(Class<R> resultType) {
Assert.notNull(resultType, "ResultType must not be null!");
return new DistinctOperationSupport<>((ReactiveFindSupport) delegate.as(resultType), field);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.DistinctWithQuery#matching(org.springframework.data.mongodb.core.query.Query)
*/
@Override
@SuppressWarnings("unchecked")
public TerminatingDistinct<T> matching(Query query) {
Assert.notNull(query, "Query must not be null!");
return new DistinctOperationSupport<>((ReactiveFindSupport<T>) delegate.matching(query), field);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core..ReactiveFindOperation.TerminatingDistinct#all()
*/
@Override
public Flux<T> all() {
return delegate.doFindDistinct(field);
}
}
} }
} }

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2017-2018 the original author or authors. * Copyright 2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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