Compare commits

..

69 Commits

Author SHA1 Message Date
Mark Paluch
4bca0ca015 Release version 3.3.10 (2021.1.10).
See #4206
2022-11-18 10:22:09 +01:00
Mark Paluch
80d63a576c Prepare 3.3.10 (2021.1.10).
See #4206
2022-11-18 10:21:05 +01:00
Mark Paluch
0f6ee3ddbc Upgrade to Java 8u345-b01-jdk-focal and pin base image distribution.
See #4206
2022-10-31 13:20:07 +01:00
Mark Paluch
c3a5f325d2 Use correct boolean type for JSON Schema creation.
We now use the correct JSON type boolean again when creating schemas. Furthermore, we use the bool type for MongoDB $type queries.

Closes #4220
2022-10-27 10:17:55 +02:00
Spring Builds
957397eff9 After release cleanups.
See #4205
2022-10-13 12:37:05 +00:00
Spring Builds
f322d5b18f Prepare next development iteration.
See #4205
2022-10-13 12:36:52 +00:00
Spring Builds
24e423b8d1 Release version 3.3.9 (2021.1.9).
See #4205
2022-10-13 11:54:15 +00:00
Spring Builds
4d5f3c66d5 Prepare 3.3.9 (2021.1.9).
See #4205
2022-10-13 11:51:37 +00:00
Spring Builds
f29d03f9c8 After release cleanups.
See #4172
2022-10-13 07:52:07 +00:00
Spring Builds
fbf4726e56 Prepare next development iteration.
See #4172
2022-10-13 07:51:54 +00:00
Spring Builds
85382f0dd8 Release version 3.3.8 (2021.1.8).
See #4172
2022-10-13 07:28:21 +00:00
Spring Builds
739b44f6e5 Prepare 3.3.8 (2021.1.8).
See #4172
2022-10-13 07:25:55 +00:00
Christoph Strobl
49cd518647 Update tests.
Original Pull Request: #4196
2022-10-11 09:55:54 +02:00
gongxuanzhang
b59c7f774f Fix json schema type name for boolean.
Was boolean should have been bool.

Closes: #4196
2022-10-11 09:55:08 +02:00
Christoph Strobl
b7ac5f7970 Update reactive transaction sample in reference documentation.
Closes: #4190
2022-10-06 13:18:44 +02:00
Christoph Ahlers
9af1689fbf Fix javadoc parameter names.
Closes: #4179
2022-10-04 12:39:48 +02:00
Wan Bachtiar
51ca3be48f Fix typo in reference documentation.
Closes: #4180
2022-10-04 12:25:43 +02:00
Seungwoo Jo
8f8e9c6585 Fix documentation typo in BasicQuery.
Closes #4169
Original pull request: #4170.
2022-09-21 10:58:22 +02:00
Spring Builds
092217e425 After release cleanups.
See #4115
2022-09-19 09:04:54 +00:00
Spring Builds
9d1e1b8c17 Prepare next development iteration.
See #4115
2022-09-19 09:04:41 +00:00
Spring Builds
5cf73168f7 Release version 3.3.7 (2021.1.7).
See #4115
2022-09-19 08:40:19 +00:00
Spring Builds
792d7199f0 Prepare 3.3.7 (2021.1.7).
See #4115
2022-09-19 08:38:01 +00:00
Christoph Strobl
34a2d09303 Fix issue with reference conversion in updates.
We now make sure to convert references in update operations targeting collection like fields when using eg. the push modifier.

Closes #4041
Original pull request: #4045.
2022-09-19 08:53:43 +02:00
Mark Paluch
26554e3031 Polishing.
See #4061
Original pull request: #4062.
2022-09-16 14:53:08 +02:00
Christoph Strobl
018fe623c0 Improve exception message when deriving collection name from type.
We now provide a better worded exception message when trying to derive the collection name for a type that is not considered a user types (such as org.bson.Document).
Update the Javadoc to hint to the error.

Closes #4061
Original pull request: #4062.
2022-09-16 14:53:06 +02:00
Christoph Strobl
27e6b5a9be Initialize lists with size where possible.
Closes #3941
Original pull request: #3974.
2022-09-16 14:44:11 +02:00
Mark Paluch
c9be849e62 Polishing.
Reformat code.

See #4167.
Original pull request: #4168.
2022-09-16 14:41:29 +02:00
Christoph Strobl
da5f24981c Fix usage of change stream option startAfter.
We now make sure to apply the token to startAfter method of the driver. Before this change it had been incorrectly applied to resumeAfter.

Closes #4167.
Original pull request: #4168.
2022-09-16 14:41:29 +02:00
Mark Paluch
7c7b05f10d Polishing.
Fix generics. Add warning suppressions for nullability checks.

See: #4104
Original pull request: #4156.
2022-09-14 14:07:27 +02:00
Christoph Strobl
ed4f30ab07 Fix GeoJson polygon conversion for polygons with inner ring.
Closes: #4104
Original pull request: #4156.
2022-09-14 14:07:26 +02:00
Christoph Strobl
cf38ba15bf Allow referencing the $id field of dbrefs within an aggregation pipeline.
Closes: #4123
Original pull request: #4125.
2022-08-05 14:10:58 +02:00
Sojin
daf12a6e2b Fix AKNOWLEDGED typo in reference documentation.
Two typos found have been updated

Closes #4135
2022-08-05 14:08:15 +02:00
Christoph Strobl
d0481d089e After release cleanups.
See #4090
2022-07-15 10:47:35 +02:00
Christoph Strobl
169c35789d Prepare next development iteration.
See #4090
2022-07-15 10:47:31 +02:00
Christoph Strobl
0de55deb03 Release version 3.3.6 (2021.1.6).
See #4090
2022-07-15 10:34:16 +02:00
Christoph Strobl
01ac35fa31 Prepare 3.3.6 (2021.1.6).
See #4090
2022-07-15 10:33:37 +02:00
Mark Paluch
f5c0318a14 Avoid duplicate bean registrations in MappingMongoConverterParser.
We now ensure to not override `ValidatingMongoEventListener` and `LocalValidatorFactoryBean` bean definitions by avoiding duplicate registrations and checking whether a bean with the given name is already registered.

Closes #4087
2022-06-28 10:25:15 +02:00
Mark Paluch
7a0debe335 After release cleanups.
See #4029
2022-06-20 11:12:22 +02:00
Mark Paluch
0a79ad6585 Prepare next development iteration.
See #4029
2022-06-20 11:12:19 +02:00
Mark Paluch
404ce6a987 Release version 3.3.5 (2021.1.5).
See #4029
2022-06-20 10:59:10 +02:00
Mark Paluch
232a9c9943 Prepare 3.3.5 (2021.1.5).
See #4029
2022-06-20 10:58:43 +02:00
Christoph Strobl
7c5ac764b3 Retain parameter type when binding parameters in annotated Query/Aggregation.
This commit ensures the parameter type is preserved when binding parameters used within the value of the Query or Aggregation annotation

Closes: #4089
2022-06-20 10:37:13 +02:00
Mark Paluch
864c94f490 Wrap SpEL documentation with admonition.
Closes #4085
2022-06-14 09:19:25 +02:00
Mark Paluch
ebc4678aa3 Polishing.
Reformat asciidoc source.

See #4085
2022-06-14 09:19:22 +02:00
Mark Paluch
28d6e67686 Upgrade to Maven Wrapper 3.8.5.
See #4075
2022-06-03 14:40:37 +02:00
John Blum
ca229cdb99 Remove Docker Registry login.
Closes #4056.
2022-05-16 13:00:16 -07:00
Mark Paluch
611100e6f4 Update driver compatibility matrix.
Closes #4052
2022-05-16 15:12:29 +02:00
Christoph Strobl
3a6d6bbfed Polishing.
Update Query javadoc.

Original Pull Request: #3999
2022-05-10 16:34:11 +02:00
Raul Mello Silva
286ff1c4a1 Update Query.limit javadoc.
This commit explains usage of Query.limit(int), which will be set to unlimited when set to zero or a negative value.

Closes: #3999
2022-05-10 16:33:50 +02:00
Christoph Strobl
5df195db15 Provide additional meta information via pom.xml
Add scm & issueManagement.

Closes: #4048
2022-05-10 12:39:52 +02:00
nniesen
e437865707 Update spring.io project urls.
This commit updates outdated projects.spring.io links to spring.io/projects.

Closes: #4042
2022-05-09 13:59:05 +02:00
Christoph Strobl
13888ab7cd After release cleanups.
See #4001
2022-04-19 12:13:23 +02:00
Christoph Strobl
ced6a1b190 Prepare next development iteration.
See #4001
2022-04-19 12:13:20 +02:00
Christoph Strobl
e704f147ad Release version 3.3.4 (2021.1.4).
See #4001
2022-04-19 12:03:13 +02:00
Christoph Strobl
67ea27d9e4 Prepare 3.3.4 (2021.1.4).
See #4001
2022-04-19 12:02:43 +02:00
Mark Paluch
a9ed00530f After release cleanups.
See #3972
2022-03-21 15:06:37 +01:00
Mark Paluch
75f73756c9 Prepare next development iteration.
See #3972
2022-03-21 15:06:35 +01:00
Mark Paluch
4b137cfd55 Release version 3.3.3 (2021.1.3).
See #3972
2022-03-21 14:58:52 +01:00
Mark Paluch
762aa62b2a Prepare 3.3.3 (2021.1.3).
See #3972
2022-03-21 14:58:27 +01:00
Mark Paluch
8f4a8dcbee Use Java 8 to build snapshots for Artifactory.
Closes #3976
2022-03-15 14:33:04 +01:00
Mark Paluch
0aa92031a3 Polishing.
Add missing Override annotations to template API methods.

See #3984
2022-03-11 15:17:52 +01:00
Christoph Strobl
8aa52c129c Modify visibility of methods in TypedJsonSchemaObject.
Change visibility to public as it should have been in first place.

Closes: #3989
2022-03-10 09:23:13 +01:00
sangyongchoi
03ac725080 Remove duplicate condition in GeoConverters.
Closes: #3981
2022-03-03 12:51:25 +01:00
Mark Paluch
5258b36080 Update CI properties.
See #3972
2022-02-22 14:09:14 +01:00
Mark Paluch
ddbec07643 Upgrade to Maven Wrapper 3.8.4.
See #3978
2022-02-22 13:56:07 +01:00
Mark Paluch
f4375fc54d Polishing.
Externalize artifactory credentials identifier.

See #3976
2022-02-22 09:17:10 +01:00
Mark Paluch
ccbd18ff6a Use Java 17 to build snapshots for Artifactory.
Closes #3976
2022-02-22 09:17:08 +01:00
Mark Paluch
490ef81d7b After release cleanups.
See #3935
2022-02-18 10:49:01 +01:00
Mark Paluch
92668635b1 Prepare next development iteration.
See #3935
2022-02-18 10:48:59 +01:00
57 changed files with 874 additions and 335 deletions

View File

@@ -1,2 +1,2 @@
#Mon Oct 11 14:30:24 CEST 2021
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip
#Fri Jun 03 09:42:19 CEST 2022
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip

94
Jenkinsfile vendored
View File

@@ -112,19 +112,17 @@ pipeline {
}
options { timeout(time: 30, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
}
steps {
script {
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
docker.image("harbor-repo.vmware.com/dockerhub-proxy-cache/springci/spring-data-with-mongodb-4.0:${p['java.main.tag']}").inside(p['docker.java.inside.basic']) {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
docker.image("harbor-repo.vmware.com/dockerhub-proxy-cache/springci/spring-data-with-mongodb-4.0:${p['java.main.tag']}").inside(p['docker.java.inside.basic']) {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
}
@@ -145,19 +143,17 @@ pipeline {
}
options { timeout(time: 30, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
}
steps {
script {
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
docker.image("harbor-repo.vmware.com/dockerhub-proxy-cache/springci/spring-data-with-mongodb-4.4:${p['java.main.tag']}").inside(p['docker.java.inside.basic']) {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
docker.image("harbor-repo.vmware.com/dockerhub-proxy-cache/springci/spring-data-with-mongodb-4.4:${p['java.main.tag']}").inside(p['docker.java.inside.basic']) {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
}
@@ -169,19 +165,17 @@ pipeline {
}
options { timeout(time: 30, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
}
steps {
script {
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
docker.image("harbor-repo.vmware.com/dockerhub-proxy-cache/springci/spring-data-with-mongodb-5.0:${p['java.main.tag']}").inside(p['docker.java.inside.basic']) {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
docker.image("harbor-repo.vmware.com/dockerhub-proxy-cache/springci/spring-data-with-mongodb-5.0:${p['java.main.tag']}").inside(p['docker.java.inside.basic']) {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
}
@@ -193,19 +187,17 @@ pipeline {
}
options { timeout(time: 30, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
}
steps {
script {
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
docker.image("harbor-repo.vmware.com/dockerhub-proxy-cache/springci/spring-data-with-mongodb-4.4:${p['java.lts.tag']}").inside(p['docker.java.inside.basic']) {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pjava11 clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
docker.image("harbor-repo.vmware.com/dockerhub-proxy-cache/springci/spring-data-with-mongodb-4.4:${p['java.lts.tag']}").inside(p['docker.java.inside.basic']) {
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
}
}
}
@@ -227,22 +219,20 @@ pipeline {
options { timeout(time: 20, unit: 'MINUTES') }
environment {
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
}
steps {
script {
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) {
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory ' +
'-Dartifactory.server=https://repo.spring.io ' +
"-Dartifactory.username=${ARTIFACTORY_USR} " +
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
"-Dartifactory.staging-repository=libs-snapshot-local " +
"-Dartifactory.build-name=spring-data-mongodb " +
"-Dartifactory.build-number=${BUILD_NUMBER} " +
'-Dmaven.test.skip=true clean deploy -U -B'
}
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) {
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory ' +
'-Dartifactory.server=https://repo.spring.io ' +
"-Dartifactory.username=${ARTIFACTORY_USR} " +
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
"-Dartifactory.staging-repository=libs-snapshot-local " +
"-Dartifactory.build-name=spring-data-mongodb " +
"-Dartifactory.build-number=${BUILD_NUMBER} " +
'-Dmaven.test.skip=true clean deploy -U -B'
}
}
}

View File

@@ -1,8 +1,8 @@
image:https://spring.io/badges/spring-data-mongodb/ga.svg[Spring Data MongoDB,link=https://projects.spring.io/spring-data-mongodb#quick-start] image:https://spring.io/badges/spring-data-mongodb/snapshot.svg[Spring Data MongoDB,link=https://projects.spring.io/spring-data-mongodb#quick-start]
image:https://spring.io/badges/spring-data-mongodb/ga.svg[Spring Data MongoDB,link=https://spring.io/projects/spring-data-mongodb#quick-start] image:https://spring.io/badges/spring-data-mongodb/snapshot.svg[Spring Data MongoDB,link=https://spring.io/projects/spring-data-mongodb#quick-start]
= Spring Data MongoDB image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-mongodb%2Fmain&subject=Build[link=https://jenkins.spring.io/view/SpringData/job/spring-data-mongodb/] https://gitter.im/spring-projects/spring-data[image:https://badges.gitter.im/spring-projects/spring-data.svg[Gitter]]
The primary goal of the https://projects.spring.io/spring-data[Spring Data] project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services.
The primary goal of the https://spring.io/projects/spring-data[Spring Data] project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services.
The Spring Data MongoDB project aims to provide a familiar and consistent Spring-based programming model for new datastores while retaining store-specific features and capabilities.
The Spring Data MongoDB project provides integration with the MongoDB document database.
@@ -115,7 +115,7 @@ Use `<mongo:client-settings cluster-hosts="..." />` instead
| `<mongo:db-factory writeConcern="..." />`
| NONE, NORMAL, SAFE, FSYNC_SAFE, REPLICAS_SAFE, MAJORITY
| W1, W2, W3, UNAKNOWLEDGED, AKNOWLEDGED, JOURNALED, MAJORITY
| W1, W2, W3, UNACKNOWLEDGED, ACKNOWLEDGED, JOURNALED, MAJORITY
|===
.Removed XML Namespace Elements and Attributes:

View File

@@ -7,15 +7,16 @@ ENV TZ=Etc/UTC
ENV DEBIAN_FRONTEND=noninteractive
RUN set -eux; \
sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list; \
sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list; \
sed -i -e 's/http/https/g' /etc/apt/sources.list ; \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 656408E390CFB1F5 ; \
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list; \
echo ${TZ} > /etc/timezone;
sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \
sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \
sed -i -e 's/ports.ubuntu.com/mirrors.ocf.berkeley.edu/g' /etc/apt/sources.list && \
sed -i -e 's/http/https/g' /etc/apt/sources.list && \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 && \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 656408E390CFB1F5 && \
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list && \
echo ${TZ} > /etc/timezone
RUN apt-get update ; \
apt-get install -y mongodb-org=${MONGODB} mongodb-org-server=${MONGODB} mongodb-org-shell=${MONGODB} mongodb-org-mongos=${MONGODB} mongodb-org-tools=${MONGODB} ; \
apt-get clean; \
rm -rf /var/lib/apt/lists/*;
RUN apt-get update && \
apt-get install -y mongodb-org=${MONGODB} mongodb-org-server=${MONGODB} mongodb-org-shell=${MONGODB} mongodb-org-mongos=${MONGODB} mongodb-org-tools=${MONGODB} && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

View File

@@ -7,15 +7,16 @@ ENV TZ=Etc/UTC
ENV DEBIAN_FRONTEND=noninteractive
RUN set -eux; \
sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list; \
sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list; \
sed -i -e 's/http/https/g' /etc/apt/sources.list ; \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 656408E390CFB1F5 ; \
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list; \
echo ${TZ} > /etc/timezone;
sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \
sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \
sed -i -e 's/ports.ubuntu.com/mirrors.ocf.berkeley.edu/g' /etc/apt/sources.list && \
sed -i -e 's/http/https/g' /etc/apt/sources.list && \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 && \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 656408E390CFB1F5 && \
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list && \
echo ${TZ} > /etc/timezone
RUN apt-get update ; \
apt-get install -y mongodb-org=${MONGODB} mongodb-org-server=${MONGODB} mongodb-org-shell=${MONGODB} mongodb-org-mongos=${MONGODB} mongodb-org-tools=${MONGODB} ; \
apt-get clean; \
rm -rf /var/lib/apt/lists/*;
RUN apt-get update && \
apt-get install -y mongodb-org=${MONGODB} mongodb-org-server=${MONGODB} mongodb-org-shell=${MONGODB} mongodb-org-mongos=${MONGODB} mongodb-org-tools=${MONGODB} && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

View File

@@ -6,16 +6,17 @@ ARG MONGODB
ENV TZ=Etc/UTC
ENV DEBIAN_FRONTEND=noninteractive
RUN RUN set -eux; \
sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list; \
sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list; \
sed -i -e 's/http/https/g' /etc/apt/sources.list ; \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4 ; \
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list; \
echo ${TZ} > /etc/timezone;
RUN set -eux; \
sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \
sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \
sed -i -e 's/ports.ubuntu.com/mirrors.ocf.berkeley.edu/g' /etc/apt/sources.list && \
sed -i -e 's/http/https/g' /etc/apt/sources.list && \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 && \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4 && \
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list && \
echo ${TZ} > /etc/timezone
RUN apt-get update ; \
apt-get install -y mongodb-org=${MONGODB} mongodb-org-server=${MONGODB} mongodb-org-shell=${MONGODB} mongodb-org-mongos=${MONGODB} mongodb-org-tools=${MONGODB} ; \
apt-get clean; \
rm -rf /var/lib/apt/lists/*;
RUN apt-get update && \
apt-get install -y mongodb-org=${MONGODB} mongodb-org-server=${MONGODB} mongodb-org-shell=${MONGODB} mongodb-org-mongos=${MONGODB} mongodb-org-tools=${MONGODB} && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

View File

@@ -7,17 +7,18 @@ ENV TZ=Etc/UTC
ENV DEBIAN_FRONTEND=noninteractive
RUN set -eux; \
sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list; \
sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list; \
sed -i -e 's/http/https/g' /etc/apt/sources.list ; \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 656408E390CFB1F5 ; \
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list; \
echo ${TZ} > /etc/timezone;
sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \
sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \
sed -i -e 's/ports.ubuntu.com/mirrors.ocf.berkeley.edu/g' /etc/apt/sources.list && \
sed -i -e 's/http/https/g' /etc/apt/sources.list && \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 && \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 656408E390CFB1F5 && \
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list && \
echo ${TZ} > /etc/timezone
RUN apt-get update ; \
ln -T /bin/true /usr/bin/systemctl ; \
apt-get install -y mongodb-org=${MONGODB} mongodb-org-server=${MONGODB} mongodb-org-shell=${MONGODB} mongodb-org-mongos=${MONGODB} mongodb-org-tools=${MONGODB} ; \
rm /usr/bin/systemctl ; \
apt-get clean ; \
rm -rf /var/lib/apt/lists/* ;
RUN apt-get update && \
ln -T /bin/true /usr/bin/systemctl && \
apt-get install -y mongodb-org=${MONGODB} mongodb-org-server=${MONGODB} mongodb-org-shell=${MONGODB} mongodb-org-mongos=${MONGODB} mongodb-org-tools=${MONGODB} && \
rm /usr/bin/systemctl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

View File

@@ -7,17 +7,18 @@ ENV TZ=Etc/UTC
ENV DEBIAN_FRONTEND=noninteractive
RUN set -eux; \
sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list; \
sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list; \
sed -i -e 's/http/https/g' /etc/apt/sources.list ; \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 wget ; \
sed -i -e 's/archive.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \
sed -i -e 's/security.ubuntu.com/mirror.one.com/g' /etc/apt/sources.list && \
sed -i -e 's/ports.ubuntu.com/mirrors.ocf.berkeley.edu/g' /etc/apt/sources.list && \
sed -i -e 's/http/https/g' /etc/apt/sources.list && \
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 wget && \
# MongoDB 5.0 release signing key
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv B00A0BD1E2C63C11 ; \
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv B00A0BD1E2C63C11 && \
# Needed when MongoDB creates a 5.0 folder.
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/5.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list; \
echo ${TZ} > /etc/timezone;
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list && \
echo ${TZ} > /etc/timezone
RUN apt-get update; \
apt-get install -y mongodb-org=${MONGODB} mongodb-org-server=${MONGODB} mongodb-org-shell=${MONGODB} mongodb-org-mongos=${MONGODB} mongodb-org-tools=${MONGODB} ; \
apt-get clean; \
rm -rf /var/lib/apt/lists/*;
RUN apt-get update && \
apt-get install -y mongodb-org=${MONGODB} mongodb-org-server=${MONGODB} mongodb-org-shell=${MONGODB} mongodb-org-mongos=${MONGODB} mongodb-org-tools=${MONGODB} && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

View File

@@ -1,7 +1,7 @@
# Java versions
java.main.tag=8u312-b07-jdk
java.next.tag=11.0.13_8-jdk
java.lts.tag=17.0.1_12-jdk
java.main.tag=8u345-b01-jdk-focal
java.next.tag=11.0.16.1_1-jdk-focal
java.lts.tag=17.0.4.1_1-jdk-focal
# Docker container images - standard
docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag}
@@ -9,15 +9,15 @@ docker.java.next.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/ecli
docker.java.lts.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.lts.tag}
# Supported versions of MongoDB
docker.mongodb.4.0.version=4.0.23
docker.mongodb.4.4.version=4.4.4
docker.mongodb.5.0.version=5.0.3
docker.mongodb.4.0.version=4.0.28
docker.mongodb.4.4.version=4.4.12
docker.mongodb.5.0.version=5.0.6
# Supported versions of Redis
docker.redis.6.version=6.2.4
docker.redis.6.version=6.2.6
# Supported versions of Cassandra
docker.cassandra.3.version=3.11.10
docker.cassandra.3.version=3.11.12
# Docker environment settings
docker.java.inside.basic=-v $HOME:/tmp/jenkins-home

19
pom.xml
View File

@@ -5,17 +5,17 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.3.2</version>
<version>3.3.10</version>
<packaging>pom</packaging>
<name>Spring Data MongoDB</name>
<description>MongoDB support for Spring Data</description>
<url>https://projects.spring.io/spring-data-mongodb</url>
<url>https://spring.io/projects/spring-data-mongodb</url>
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>2.6.2</version>
<version>2.6.10</version>
</parent>
<modules>
@@ -26,7 +26,7 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.6.2</springdata.commons>
<springdata.commons>2.6.10</springdata.commons>
<mongo>4.4.2</mongo>
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
<jmh.version>1.19</jmh.version>
@@ -112,6 +112,17 @@
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/spring-projects/spring-data-mongodb.git</connection>
<developerConnection>scm:git:git@github.com:spring-projects/spring-data-mongodb.git</developerConnection>
<url>https://github.com/spring-projects/spring-data-mongodb</url>
</scm>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/spring-projects/spring-data-mongodb/issues</url>
</issueManagement>
<profiles>
<profile>
<id>benchmarks</id>

View File

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

View File

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

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.3.2</version>
<version>3.3.10</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -24,7 +24,6 @@ import java.util.List;
import java.util.Set;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
@@ -64,6 +63,7 @@ import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
/**
@@ -135,9 +135,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
new BeanComponentDefinition(indexOperationsProviderBuilder.getBeanDefinition(), "indexOperationsProvider"));
}
try {
registry.getBeanDefinition(INDEX_HELPER_BEAN_NAME);
} catch (NoSuchBeanDefinitionException ignored) {
if (!registry.containsBeanDefinition(INDEX_HELPER_BEAN_NAME)) {
BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder
.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
@@ -151,7 +149,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
BeanDefinition validatingMongoEventListener = potentiallyCreateValidatingMongoEventListener(element, parserContext);
if (validatingMongoEventListener != null) {
if (validatingMongoEventListener != null && !registry.containsBeanDefinition(VALIDATING_EVENT_LISTENER_BEAN_NAME)) {
parserContext.registerBeanComponent(
new BeanComponentDefinition(validatingMongoEventListener, VALIDATING_EVENT_LISTENER_BEAN_NAME));
}
@@ -165,15 +163,16 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
private BeanDefinition potentiallyCreateValidatingMongoEventListener(Element element, ParserContext parserContext) {
String disableValidation = element.getAttribute("disable-validation");
boolean validationDisabled = StringUtils.hasText(disableValidation) && Boolean.valueOf(disableValidation);
boolean validationDisabled = StringUtils.hasText(disableValidation) && Boolean.parseBoolean(disableValidation);
if (!validationDisabled) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
RuntimeBeanReference validator = getValidator(builder, parserContext);
RuntimeBeanReference validator = getValidator(element, parserContext);
if (validator != null) {
builder.getRawBeanDefinition().setBeanClass(ValidatingMongoEventListener.class);
builder.getRawBeanDefinition().setSource(element);
builder.addConstructorArgValue(validator);
return builder.getBeanDefinition();
@@ -195,7 +194,6 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
validatorDef.setSource(source);
validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String validatorName = parserContext.getReaderContext().registerWithGeneratedName(validatorDef);
parserContext.registerBeanComponent(new BeanComponentDefinition(validatorDef, validatorName));
return new RuntimeBeanReference(validatorName);
}

View File

@@ -176,16 +176,20 @@ class CountQuery {
Document $geoWithinMin = new Document("$geoWithin",
new Document(spheric ? "$centerSphere" : "$center", $centerMin));
List<Document> criteria = new ArrayList<>();
List<Document> criteria;
if ($and != null) {
if ($and instanceof Collection) {
criteria.addAll((Collection) $and);
Collection andElements = (Collection) $and;
criteria = new ArrayList<>(andElements.size() + 2);
criteria.addAll(andElements);
} else {
throw new IllegalArgumentException(
"Cannot rewrite query as it contains an '$and' element that is not a Collection!: Offending element: "
+ $and);
}
} else {
criteria = new ArrayList<>(2);
}
criteria.add(new Document("$nor", Collections.singletonList(new Document(key, $geoWithinMin))));

View File

@@ -188,7 +188,8 @@ public class DefaultIndexOperations implements IndexOperations {
private List<IndexInfo> getIndexData(MongoCursor<Document> cursor) {
List<IndexInfo> indexInfoList = new ArrayList<>();
int available = cursor.available();
List<IndexInfo> indexInfoList = available > 0 ? new ArrayList<>(available) : new ArrayList<>();
while (cursor.hasNext()) {

View File

@@ -138,7 +138,14 @@ class EntityOperations {
"No class parameter provided, entity collection can't be determined!");
}
return context.getRequiredPersistentEntity(entityClass).getCollection();
MongoPersistentEntity<?> persistentEntity = context.getPersistentEntity(entityClass);
if (persistentEntity == null) {
throw new MappingException(String.format(
"Cannot determine collection name from type '%s'. Is it a store native type?", entityClass.getName()));
}
return persistentEntity.getCollection();
}
public Query getByIdInQuery(Collection<?> entities) {

View File

@@ -80,6 +80,7 @@ public interface MongoOperations extends FluentMongoOperations {
*
* @param entityClass must not be {@literal null}.
* @return never {@literal null}.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be derived from the type.
*/
String getCollectionName(Class<?> entityClass);
@@ -968,6 +969,8 @@ public interface MongoOperations extends FluentMongoOperations {
* fields specification. Must not be {@literal null}.
* @param replacement the replacement document. Must not be {@literal null}.
* @return the converted object that was updated or {@literal null}, if not found.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
@Nullable
@@ -1009,6 +1012,8 @@ public interface MongoOperations extends FluentMongoOperations {
* @return the converted object that was updated or {@literal null}, if not found. Depending on the value of
* {@link FindAndReplaceOptions#isReturnNew()} this will either be the object as it was before the update or
* as it is after the update.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
@Nullable
@@ -1082,6 +1087,8 @@ public interface MongoOperations extends FluentMongoOperations {
* @return the converted object that was updated or {@literal null}, if not found. Depending on the value of
* {@link FindAndReplaceOptions#isReturnNew()} this will either be the object as it was before the update or
* as it is after the update.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
@Nullable
@@ -1171,6 +1178,8 @@ public interface MongoOperations extends FluentMongoOperations {
* {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the count of matching documents.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
long count(Query query, Class<?> entityClass);
@@ -1205,6 +1214,8 @@ public interface MongoOperations extends FluentMongoOperations {
*
* @param entityClass must not be {@literal null}.
* @return the estimated number of documents.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.1
*/
default long estimatedCount(Class<?> entityClass) {
@@ -1265,6 +1276,8 @@ public interface MongoOperations extends FluentMongoOperations {
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the inserted object.
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
<T> T insert(T objectToSave);
@@ -1291,6 +1304,8 @@ public interface MongoOperations extends FluentMongoOperations {
* @param batchToSave the batch of objects to save. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the inserted objects that.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
<T> Collection<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass);
@@ -1309,6 +1324,8 @@ public interface MongoOperations extends FluentMongoOperations {
*
* @param objectsToSave the list of objects to save. Must not be {@literal null}.
* @return the inserted objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} for the given objects.
*/
<T> Collection<T> insertAll(Collection<? extends T> objectsToSave);
@@ -1330,6 +1347,8 @@ public interface MongoOperations extends FluentMongoOperations {
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the saved object.
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
<T> T save(T objectToSave);
@@ -1366,9 +1385,11 @@ public interface MongoOperations extends FluentMongoOperations {
* the existing object. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @since 3.0
* @see Update
* @see AggregationUpdate
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.0
*/
UpdateResult upsert(Query query, UpdateDefinition update, Class<?> entityClass);
@@ -1420,9 +1441,11 @@ public interface MongoOperations extends FluentMongoOperations {
* the existing. Must not be {@literal null}.
* @param entityClass class that determines the collection to use.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @since 3.0
* @see Update
* @see AggregationUpdate
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.0
*/
UpdateResult updateFirst(Query query, UpdateDefinition update, Class<?> entityClass);
@@ -1474,9 +1497,11 @@ public interface MongoOperations extends FluentMongoOperations {
* the existing. Must not be {@literal null}.
* @param entityClass class of the pojo to be operated on. Must not be {@literal null}.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @since 3.0
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @see Update
* @see AggregationUpdate
* @since 3.0
*/
UpdateResult updateMulti(Query query, UpdateDefinition update, Class<?> entityClass);
@@ -1524,6 +1549,8 @@ public interface MongoOperations extends FluentMongoOperations {
*
* @param object must not be {@literal null}.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
DeleteResult remove(Object object);
@@ -1547,6 +1574,8 @@ public interface MongoOperations extends FluentMongoOperations {
* @param entityClass class that determines the collection to use.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
* @throws IllegalArgumentException when {@literal query} or {@literal entityClass} is {@literal null}.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
DeleteResult remove(Query query, Class<?> entityClass);
@@ -1594,6 +1623,8 @@ public interface MongoOperations extends FluentMongoOperations {
* @param query the query document that specifies the criteria used to find and remove documents.
* @param entityClass class of the pojo to be operated on.
* @return the {@link List} converted objects deleted by this operation.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 1.5
*/
<T> List<T> findAllAndRemove(Query query, Class<T> entityClass);

View File

@@ -315,6 +315,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
prepareIndexCreator(applicationContext);
@@ -380,6 +381,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
*
* @return
*/
@Override
public MongoConverter getConverter() {
return this.mongoConverter;
}
@@ -519,6 +521,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#execute(org.springframework.data.mongodb.core.DbCallback)
*/
@Override
public <T> T execute(DbCallback<T> action) {
Assert.notNull(action, "DbCallback must not be null!");
@@ -535,6 +538,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#execute(java.lang.Class, org.springframework.data.mongodb.core.DbCallback)
*/
@Override
public <T> T execute(Class<?> entityClass, CollectionCallback<T> callback) {
Assert.notNull(entityClass, "EntityClass must not be null!");
@@ -545,6 +549,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#execute(java.lang.String, org.springframework.data.mongodb.core.DbCallback)
*/
@Override
public <T> T execute(String collectionName, CollectionCallback<T> callback) {
Assert.notNull(collectionName, "CollectionName must not be null!");
@@ -597,6 +602,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#createCollection(java.lang.Class)
*/
@Override
public <T> MongoCollection<Document> createCollection(Class<T> entityClass) {
return createCollection(entityClass, operations.forType(entityClass).getCollectionOptions());
}
@@ -605,6 +611,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#createCollection(java.lang.Class, org.springframework.data.mongodb.core.CollectionOptions)
*/
@Override
public <T> MongoCollection<Document> createCollection(Class<T> entityClass,
@Nullable CollectionOptions collectionOptions) {
@@ -623,6 +630,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#createCollection(java.lang.String)
*/
@Override
public MongoCollection<Document> createCollection(String collectionName) {
Assert.notNull(collectionName, "CollectionName must not be null!");
@@ -634,6 +642,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#createCollection(java.lang.String, org.springframework.data.mongodb.core.CollectionOptions)
*/
@Override
public MongoCollection<Document> createCollection(String collectionName,
@Nullable CollectionOptions collectionOptions) {
@@ -645,6 +654,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#getCollection(java.lang.String)
*/
@Override
@SuppressWarnings("ConstantConditions")
public MongoCollection<Document> getCollection(String collectionName) {
@@ -657,6 +667,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#getCollection(java.lang.Class)
*/
@Override
public <T> boolean collectionExists(Class<T> entityClass) {
return collectionExists(getCollectionName(entityClass));
}
@@ -665,6 +676,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#getCollection(java.lang.String)
*/
@Override
@SuppressWarnings("ConstantConditions")
public boolean collectionExists(String collectionName) {
@@ -685,6 +697,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#dropCollection(java.lang.Class)
*/
@Override
public <T> void dropCollection(Class<T> entityClass) {
dropCollection(getCollectionName(entityClass));
}
@@ -693,6 +706,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#dropCollection(java.lang.String)
*/
@Override
public void dropCollection(String collectionName) {
Assert.notNull(collectionName, "CollectionName must not be null!");
@@ -716,6 +730,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#indexOps(java.lang.String)
*/
@Override
public IndexOperations indexOps(String collectionName, @Nullable Class<?> type) {
return new DefaultIndexOperations(this, collectionName, type);
}
@@ -724,6 +739,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#indexOps(java.lang.Class)
*/
@Override
public IndexOperations indexOps(Class<?> entityClass) {
return indexOps(getCollectionName(entityClass), entityClass);
}
@@ -732,6 +748,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#bulkOps(org.springframework.data.mongodb.core.BulkMode, java.lang.String)
*/
@Override
public BulkOperations bulkOps(BulkMode bulkMode, String collectionName) {
return bulkOps(bulkMode, null, collectionName);
}
@@ -740,6 +757,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#bulkOps(org.springframework.data.mongodb.core.BulkMode, java.lang.Class)
*/
@Override
public BulkOperations bulkOps(BulkMode bulkMode, Class<?> entityClass) {
return bulkOps(bulkMode, entityClass, getCollectionName(entityClass));
}
@@ -748,6 +766,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#bulkOps(org.springframework.data.mongodb.core.BulkMode, java.lang.Class, java.lang.String)
*/
@Override
public BulkOperations bulkOps(BulkMode mode, @Nullable Class<?> entityType, String collectionName) {
Assert.notNull(mode, "BulkMode must not be null!");
@@ -968,7 +987,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
DocumentCallback<GeoResult<T>> callback = new GeoNearResultDocumentCallback<>(distanceField,
new ProjectingReadCallback<>(mongoConverter, domainType, returnType, collection), near.getMetric());
List<GeoResult<T>> result = new ArrayList<>();
List<GeoResult<T>> result = new ArrayList<>(results.getMappedResults().size());
BigDecimal aggregate = BigDecimal.ZERO;
for (Document element : results) {
@@ -1109,6 +1128,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#count(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String)
*/
@Override
public long count(Query query, @Nullable Class<?> entityClass, String collectionName) {
Assert.notNull(query, "Query must not be null!");
@@ -1325,7 +1345,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
Assert.notNull(writer, "MongoWriter must not be null!");
List<Document> documentList = new ArrayList<>();
List<Document> documentList = new ArrayList<>(batchToSave.size());
List<T> initializedBatchToSave = new ArrayList<>(batchToSave.size());
for (T uninitialized : batchToSave) {
@@ -1915,10 +1935,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return mappedResults;
}
@Override
public <T> GroupByResults<T> group(String inputCollectionName, GroupBy groupBy, Class<T> entityClass) {
return group(null, inputCollectionName, groupBy, entityClass);
}
@Override
public <T> GroupByResults<T> group(@Nullable Criteria criteria, String inputCollectionName, GroupBy groupBy,
Class<T> entityClass) {
@@ -2325,6 +2347,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#getCollectionNames()
*/
@Override
@SuppressWarnings("ConstantConditions")
public Set<String> getCollectionNames() {
return execute(db -> {
@@ -2829,7 +2852,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
.initiateFind(getAndPrepareCollection(doGetDatabase(), collectionName), collectionCallback::doInCollection)
.iterator()) {
List<T> result = new ArrayList<>();
int available = cursor.available();
List<T> result = available > 0 ? new ArrayList<>(available) : new ArrayList<>();
while (cursor.hasNext()) {
Document object = cursor.next();
@@ -2974,6 +2998,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
this.collation = collation;
}
@Override
public FindIterable<Document> doInCollection(MongoCollection<Document> collection)
throws MongoException, DataAccessException {
@@ -3033,6 +3058,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
this.collation = Optional.ofNullable(collation);
}
@Override
public Document doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
FindOneAndDeleteOptions opts = new FindOneAndDeleteOptions().sort(sort).projection(fields);
@@ -3062,6 +3088,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
this.options = options;
}
@Override
public Document doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
FindOneAndUpdateOptions opts = new FindOneAndUpdateOptions();
@@ -3174,6 +3201,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
this.collectionName = collectionName;
}
@Override
public T doWith(Document document) {
maybeEmitEvent(new AfterLoadEvent<>(document, type, collectionName));
@@ -3218,6 +3246,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoTemplate.DocumentCallback#doWith(org.bson.Document)
*/
@Override
@SuppressWarnings("unchecked")
public T doWith(Document document) {
@@ -3258,6 +3287,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.CursorPreparer#prepare(com.mongodb.DBCursor)
*/
@Override
public FindIterable<Document> prepare(FindIterable<Document> iterable) {
FindIterable<Document> cursorToUse = iterable;
@@ -3376,6 +3406,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
this.metric = metric;
}
@Override
public GeoResult<T> doWith(Document object) {
double distance = Double.NaN;

View File

@@ -756,6 +756,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* fields specification. Must not be {@literal null}.
* @param replacement the replacement document. Must not be {@literal null}.
* @return the converted object that was updated or {@link Mono#empty()}, if not found.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
default <T> Mono<T> findAndReplace(Query query, T replacement) {
@@ -795,6 +797,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* @return the converted object that was updated or {@link Mono#empty()}, if not found. Depending on the value of
* {@link FindAndReplaceOptions#isReturnNew()} this will either be the object as it was before the update or
* as it is after the update.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
default <T> Mono<T> findAndReplace(Query query, T replacement, FindAndReplaceOptions options) {
@@ -865,6 +869,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* @return the converted object that was updated or {@link Mono#empty()}, if not found. Depending on the value of
* {@link FindAndReplaceOptions#isReturnNew()} this will either be the object as it was before the update or
* as it is after the update.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given replacement value.
* @since 2.1
*/
default <S, T> Mono<T> findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class<S> entityType,
@@ -951,6 +957,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the count of matching documents.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
Mono<Long> count(Query query, Class<?> entityClass);
@@ -1007,6 +1015,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
*
* @param entityClass must not be {@literal null}.
* @return a {@link Mono} emitting the estimated number of documents.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.1
*/
default Mono<Long> estimatedCount(Class<?> entityClass) {
@@ -1045,6 +1055,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the inserted object.
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
<T> Mono<T> insert(T objectToSave);
@@ -1070,7 +1082,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
*
* @param batchToSave the batch of objects to save. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the inserted objects .
* @return the inserted objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
<T> Flux<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass);
@@ -1089,6 +1103,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
*
* @param objectsToSave the list of objects to save. Must not be {@literal null}.
* @return the saved objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} for the given objects.
*/
<T> Flux<T> insertAll(Collection<? extends T> objectsToSave);
@@ -1116,6 +1132,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* @param batchToSave the publisher which provides objects to save. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the inserted objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} for the type.
*/
<T> Flux<T> insertAll(Mono<? extends Collection<? extends T>> batchToSave, Class<?> entityClass);
@@ -1155,6 +1173,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the saved object.
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
<T> Mono<T> save(T objectToSave);
@@ -1191,6 +1211,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
*
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the saved object.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
<T> Mono<T> save(Mono<? extends T> objectToSave);
@@ -1224,6 +1246,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* the existing object. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.0
* @see Update
* @see AggregationUpdate
@@ -1278,6 +1302,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* the existing. Must not be {@literal null}.
* @param entityClass class that determines the collection to use.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @since 3.0
* @see Update
* @see AggregationUpdate
@@ -1333,6 +1359,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* @param entityClass class of the pojo to be operated on. Must not be {@literal null}.
* @return the {@link UpdateResult} which lets you access the results of the previous write.
* @since 3.0
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
* @see Update
* @see AggregationUpdate
*/
@@ -1379,6 +1407,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
*
* @param object must not be {@literal null}.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
Mono<DeleteResult> remove(Object object);
@@ -1396,6 +1426,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
*
* @param objectToRemove must not be {@literal null}.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given object type.
*/
Mono<DeleteResult> remove(Mono<? extends Object> objectToRemove);
@@ -1415,6 +1447,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* @param query the query document that specifies the criteria used to remove a record.
* @param entityClass class that determines the collection to use.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
Mono<DeleteResult> remove(Query query, Class<?> entityClass);
@@ -1458,6 +1492,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* @param query the query document that specifies the criteria used to find and remove documents.
* @param entityClass class of the pojo to be operated on.
* @return the {@link Flux} converted objects deleted by this operation.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
<T> Flux<T> findAllAndRemove(Query query, Class<T> entityClass);
@@ -1489,6 +1525,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* specification.
* @param entityClass the parametrized type of the returned {@link Flux}.
* @return the {@link Flux} of converted objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
<T> Flux<T> tail(Query query, Class<T> entityClass);
@@ -1633,6 +1671,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
*
* @param entityClass must not be {@literal null}.
* @return never {@literal null}.
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be derived from the type.
* @since 2.1
*/
String getCollectionName(Class<?> entityClass);

View File

@@ -340,6 +340,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
prepareIndexCreator(applicationContext);
@@ -406,6 +407,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
*
* @return
*/
@Override
public MongoConverter getConverter() {
return this.mongoConverter;
}
@@ -414,6 +416,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#reactiveIndexOps(java.lang.String)
*/
@Override
public ReactiveIndexOperations indexOps(String collectionName) {
return new DefaultReactiveIndexOperations(this, collectionName, this.queryMapper);
}
@@ -422,10 +425,12 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#reactiveIndexOps(java.lang.Class)
*/
@Override
public ReactiveIndexOperations indexOps(Class<?> entityClass) {
return new DefaultReactiveIndexOperations(this, getCollectionName(entityClass), this.queryMapper, entityClass);
}
@Override
public String getCollectionName(Class<?> entityClass) {
return operations.determineCollectionName(entityClass);
}
@@ -434,6 +439,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#executeCommand(java.lang.String)
*/
@Override
public Mono<Document> executeCommand(String jsonCommand) {
Assert.notNull(jsonCommand, "Command must not be empty!");
@@ -445,6 +451,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#executeCommand(org.bson.Document)
*/
@Override
public Mono<Document> executeCommand(Document command) {
return executeCommand(command, null);
}
@@ -453,6 +460,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#executeCommand(org.bson.Document, com.mongodb.ReadPreference)
*/
@Override
public Mono<Document> executeCommand(Document command, @Nullable ReadPreference readPreference) {
Assert.notNull(command, "Command must not be null!");
@@ -483,6 +491,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#execute(java.lang.String, org.springframework.data.mongodb.core.ReactiveCollectionCallback)
*/
@Override
public <T> Flux<T> execute(String collectionName, ReactiveCollectionCallback<T> callback) {
Assert.notNull(callback, "ReactiveCollectionCallback must not be null!");
@@ -580,6 +589,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#withSession(com.mongodb.session.ClientSession)
*/
@Override
public ReactiveMongoOperations withSession(ClientSession session) {
return new ReactiveSessionBoundMongoTemplate(session, ReactiveMongoTemplate.this);
}
@@ -665,6 +675,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#createCollection(java.lang.Class)
*/
@Override
public <T> Mono<MongoCollection<Document>> createCollection(Class<T> entityClass) {
return createCollection(entityClass, operations.forType(entityClass).getCollectionOptions());
}
@@ -673,6 +684,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#createCollection(java.lang.Class, org.springframework.data.mongodb.core.CollectionOptions)
*/
@Override
public <T> Mono<MongoCollection<Document>> createCollection(Class<T> entityClass,
@Nullable CollectionOptions collectionOptions) {
@@ -691,6 +703,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#createCollection(java.lang.String)
*/
@Override
public Mono<MongoCollection<Document>> createCollection(String collectionName) {
return doCreateCollection(collectionName, new CreateCollectionOptions());
}
@@ -699,6 +712,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#createCollection(java.lang.String, org.springframework.data.mongodb.core.CollectionOptions)
*/
@Override
public Mono<MongoCollection<Document>> createCollection(String collectionName,
@Nullable CollectionOptions collectionOptions) {
return doCreateCollection(collectionName, convertToCreateCollectionOptions(collectionOptions));
@@ -708,6 +722,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#getCollection(java.lang.String)
*/
@Override
public Mono<MongoCollection<Document>> getCollection(String collectionName) {
Assert.notNull(collectionName, "Collection name must not be null!");
@@ -719,6 +734,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#collectionExists(java.lang.Class)
*/
@Override
public <T> Mono<Boolean> collectionExists(Class<T> entityClass) {
return collectionExists(getCollectionName(entityClass));
}
@@ -727,6 +743,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#collectionExists(java.lang.String)
*/
@Override
public Mono<Boolean> collectionExists(String collectionName) {
return createMono(db -> Flux.from(db.listCollectionNames()) //
.filter(s -> s.equals(collectionName)) //
@@ -738,6 +755,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#dropCollection(java.lang.Class)
*/
@Override
public <T> Mono<Void> dropCollection(Class<T> entityClass) {
return dropCollection(getCollectionName(entityClass));
}
@@ -746,6 +764,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#dropCollection(java.lang.String)
*/
@Override
public Mono<Void> dropCollection(String collectionName) {
return createMono(collectionName, MongoCollection::drop).doOnSuccess(success -> {
@@ -759,6 +778,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#getCollectionNames()
*/
@Override
public Flux<String> getCollectionNames() {
return createFlux(MongoDatabase::listCollectionNames);
}
@@ -775,6 +795,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findOne(org.springframework.data.mongodb.core.query.Query, java.lang.Class)
*/
@Override
public <T> Mono<T> findOne(Query query, Class<T> entityClass) {
return findOne(query, entityClass, getCollectionName(entityClass));
}
@@ -783,6 +804,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findOne(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String)
*/
@Override
public <T> Mono<T> findOne(Query query, Class<T> entityClass, String collectionName) {
if (ObjectUtils.isEmpty(query.getSortObject())) {
@@ -798,6 +820,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#exists(org.springframework.data.mongodb.core.query.Query, java.lang.Class)
*/
@Override
public Mono<Boolean> exists(Query query, Class<?> entityClass) {
return exists(query, entityClass, getCollectionName(entityClass));
}
@@ -806,6 +829,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#exists(org.springframework.data.mongodb.core.query.Query, java.lang.String)
*/
@Override
public Mono<Boolean> exists(Query query, String collectionName) {
return exists(query, null, collectionName);
}
@@ -814,6 +838,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#exists(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String)
*/
@Override
public Mono<Boolean> exists(Query query, @Nullable Class<?> entityClass, String collectionName) {
if (query == null) {
@@ -842,6 +867,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#find(org.springframework.data.mongodb.core.query.Query, java.lang.Class)
*/
@Override
public <T> Flux<T> find(Query query, Class<T> entityClass) {
return find(query, entityClass, getCollectionName(entityClass));
}
@@ -850,6 +876,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#find(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String)
*/
@Override
public <T> Flux<T> find(@Nullable Query query, Class<T> entityClass, String collectionName) {
if (query == null) {
@@ -864,6 +891,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findById(java.lang.Object, java.lang.Class)
*/
@Override
public <T> Mono<T> findById(Object id, Class<T> entityClass) {
return findById(id, entityClass, getCollectionName(entityClass));
}
@@ -872,6 +900,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findById(java.lang.Object, java.lang.Class, java.lang.String)
*/
@Override
public <T> Mono<T> findById(Object id, Class<T> entityClass, String collectionName) {
String idKey = operations.getIdPropertyName(entityClass);
@@ -883,6 +912,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findDistinct(org.springframework.data.mongodb.core.query.Query, java.lang.String, java.lang.Class, java.lang.Class)
*/
@Override
public <T> Flux<T> findDistinct(Query query, String field, Class<?> entityClass, Class<T> resultClass) {
return findDistinct(query, field, getCollectionName(entityClass), entityClass, resultClass);
}
@@ -891,6 +921,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#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> Flux<T> findDistinct(Query query, String field, String collectionName, Class<?> entityClass,
Class<T> resultClass) {
@@ -1073,6 +1104,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findAndModify(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.Class)
*/
@Override
public <T> Mono<T> findAndModify(Query query, UpdateDefinition update, Class<T> entityClass) {
return findAndModify(query, update, new FindAndModifyOptions(), entityClass, getCollectionName(entityClass));
}
@@ -1081,6 +1113,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findAndModify(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.Class, java.lang.String)
*/
@Override
public <T> Mono<T> findAndModify(Query query, UpdateDefinition update, Class<T> entityClass, String collectionName) {
return findAndModify(query, update, new FindAndModifyOptions(), entityClass, collectionName);
}
@@ -1089,6 +1122,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findAndModify(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, org.springframework.data.mongodb.core.FindAndModifyOptions, java.lang.Class)
*/
@Override
public <T> Mono<T> findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options,
Class<T> entityClass) {
return findAndModify(query, update, options, entityClass, getCollectionName(entityClass));
@@ -1098,6 +1132,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findAndModify(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, org.springframework.data.mongodb.core.FindAndModifyOptions, java.lang.Class, java.lang.String)
*/
@Override
public <T> Mono<T> findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options,
Class<T> entityClass, String collectionName) {
@@ -1174,6 +1209,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findAndRemove(org.springframework.data.mongodb.core.query.Query, java.lang.Class)
*/
@Override
public <T> Mono<T> findAndRemove(Query query, Class<T> entityClass) {
return findAndRemove(query, entityClass, getCollectionName(entityClass));
}
@@ -1182,6 +1218,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findAndRemove(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String)
*/
@Override
public <T> Mono<T> findAndRemove(Query query, Class<T> entityClass, String collectionName) {
operations.forType(entityClass).getCollation(query);
@@ -1194,6 +1231,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#count(org.springframework.data.mongodb.core.query.Query, java.lang.Class)
*/
@Override
public Mono<Long> count(Query query, Class<?> entityClass) {
Assert.notNull(entityClass, "Entity class must not be null!");
@@ -1205,6 +1243,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#count(org.springframework.data.mongodb.core.query.Query, java.lang.String)
*/
@Override
public Mono<Long> count(Query query, String collectionName) {
return count(query, null, collectionName);
}
@@ -1213,6 +1252,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#count(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String)
*/
@Override
public Mono<Long> count(Query query, @Nullable Class<?> entityClass, String collectionName) {
Assert.notNull(query, "Query must not be null!");
@@ -1298,6 +1338,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#insert(java.lang.Object)
*/
@Override
public <T> Mono<T> insert(T objectToSave) {
Assert.notNull(objectToSave, "Object to insert must not be null!");
@@ -1310,6 +1351,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#insert(java.lang.Object, java.lang.String)
*/
@Override
public <T> Mono<T> insert(T objectToSave, String collectionName) {
Assert.notNull(objectToSave, "Object to insert must not be null!");
@@ -1352,6 +1394,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#insert(java.util.Collection, java.lang.Class)
*/
@Override
public <T> Flux<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass) {
return doInsertBatch(getCollectionName(entityClass), batchToSave, this.mongoConverter);
}
@@ -1360,6 +1403,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#insert(java.util.Collection, java.lang.String)
*/
@Override
public <T> Flux<T> insert(Collection<? extends T> batchToSave, String collectionName) {
return doInsertBatch(collectionName, batchToSave, this.mongoConverter);
}
@@ -1368,6 +1412,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#insertAll(java.util.Collection)
*/
@Override
public <T> Flux<T> insertAll(Collection<? extends T> objectsToSave) {
return doInsertAll(objectsToSave, this.mongoConverter);
}
@@ -1468,6 +1513,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#save(java.lang.Object)
*/
@Override
public <T> Mono<T> save(T objectToSave) {
Assert.notNull(objectToSave, "Object to save must not be null!");
@@ -1478,6 +1524,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#save(java.lang.Object, java.lang.String)
*/
@Override
public <T> Mono<T> save(T objectToSave, String collectionName) {
Assert.notNull(objectToSave, "Object to save must not be null!");
@@ -1585,7 +1632,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
LOGGER.debug("Inserting list of Documents containing " + dbDocList.size() + " items");
}
List<Document> documents = new ArrayList<>();
List<Document> documents = new ArrayList<>(dbDocList.size());
return execute(collectionName, collection -> {
@@ -1672,6 +1719,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#upsert(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.Class)
*/
@Override
public Mono<UpdateResult> upsert(Query query, UpdateDefinition update, Class<?> entityClass) {
return doUpdate(getCollectionName(entityClass), query, update, entityClass, true, false);
}
@@ -1680,6 +1728,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#upsert(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.String)
*/
@Override
public Mono<UpdateResult> upsert(Query query, UpdateDefinition update, String collectionName) {
return doUpdate(collectionName, query, update, null, true, false);
}
@@ -1688,6 +1737,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#upsert(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.Class, java.lang.String)
*/
@Override
public Mono<UpdateResult> upsert(Query query, UpdateDefinition update, Class<?> entityClass, String collectionName) {
return doUpdate(collectionName, query, update, entityClass, true, false);
}
@@ -1696,6 +1746,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc))
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#updateFirst(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.Class)
*/
@Override
public Mono<UpdateResult> updateFirst(Query query, UpdateDefinition update, Class<?> entityClass) {
return doUpdate(getCollectionName(entityClass), query, update, entityClass, false, false);
}
@@ -1704,6 +1755,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#updateFirst(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.String)
*/
@Override
public Mono<UpdateResult> updateFirst(Query query, UpdateDefinition update, String collectionName) {
return doUpdate(collectionName, query, update, null, false, false);
}
@@ -1712,6 +1764,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#updateFirst(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.Class, java.lang.String)
*/
@Override
public Mono<UpdateResult> updateFirst(Query query, UpdateDefinition update, Class<?> entityClass,
String collectionName) {
return doUpdate(collectionName, query, update, entityClass, false, false);
@@ -1721,6 +1774,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#updateMulti(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.Class)
*/
@Override
public Mono<UpdateResult> updateMulti(Query query, UpdateDefinition update, Class<?> entityClass) {
return doUpdate(getCollectionName(entityClass), query, update, entityClass, false, true);
}
@@ -1729,6 +1783,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#updateMulti(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.String)
*/
@Override
public Mono<UpdateResult> updateMulti(Query query, UpdateDefinition update, String collectionName) {
return doUpdate(collectionName, query, update, null, false, true);
}
@@ -1737,6 +1792,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#updateMulti(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.UpdateDefinition, java.lang.Class, java.lang.String)
*/
@Override
public Mono<UpdateResult> updateMulti(Query query, UpdateDefinition update, Class<?> entityClass,
String collectionName) {
return doUpdate(collectionName, query, update, entityClass, false, true);
@@ -1870,6 +1926,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#remove(java.lang.Object)
*/
@Override
public Mono<DeleteResult> remove(Object object) {
Assert.notNull(object, "Object must not be null!");
@@ -1881,6 +1938,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#remove(java.lang.Object, java.lang.String)
*/
@Override
public Mono<DeleteResult> remove(Object object, String collectionName) {
Assert.notNull(object, "Object must not be null!");
@@ -1914,6 +1972,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#remove(org.springframework.data.mongodb.core.query.Query, java.lang.String)
*/
@Override
public Mono<DeleteResult> remove(Query query, String collectionName) {
return remove(query, null, collectionName);
}
@@ -1922,6 +1981,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#remove(org.springframework.data.mongodb.core.query.Query, java.lang.Class)
*/
@Override
public Mono<DeleteResult> remove(Query query, Class<?> entityClass) {
return remove(query, entityClass, getCollectionName(entityClass));
}
@@ -1930,6 +1990,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#remove(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String)
*/
@Override
public Mono<DeleteResult> remove(Query query, @Nullable Class<?> entityClass, String collectionName) {
return doRemove(collectionName, query, entityClass);
}
@@ -1988,6 +2049,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findAll(java.lang.Class)
*/
@Override
public <T> Flux<T> findAll(Class<T> entityClass) {
return findAll(entityClass, getCollectionName(entityClass));
}
@@ -1996,6 +2058,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#findAll(java.lang.Class, java.lang.String)
*/
@Override
public <T> Flux<T> findAll(Class<T> entityClass, String collectionName) {
return executeFindMultiInternal(new FindCallback(null), FindPublisherPreparer.NO_OP_PREPARER,
new ReadDocumentCallback<>(mongoConverter, entityClass, collectionName), collectionName);
@@ -2078,7 +2141,13 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
publisher = filter.isEmpty() ? db.watch(Document.class) : db.watch(filter, Document.class);
}
publisher = options.getResumeToken().map(BsonValue::asDocument).map(publisher::resumeAfter).orElse(publisher);
if (options.isResumeAfter()) {
publisher = options.getResumeToken().map(BsonValue::asDocument).map(publisher::resumeAfter)
.orElse(publisher);
} else if (options.isStartAfter()) {
publisher = options.getResumeToken().map(BsonValue::asDocument).map(publisher::startAfter)
.orElse(publisher);
}
publisher = options.getCollation().map(Collation::toMongoCollation).map(publisher::collation)
.orElse(publisher);
publisher = options.getResumeBsonTimestamp().map(publisher::startAtOperationTime).orElse(publisher);
@@ -2115,6 +2184,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#mapReduce(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.Class, java.lang.String, java.lang.String, org.springframework.data.mongodb.core.mapreduce.MapReduceOptions)
*/
@Override
public <T> Flux<T> mapReduce(Query filterQuery, Class<?> domainType, Class<T> resultType, String mapFunction,
String reduceFunction, MapReduceOptions options) {
@@ -2126,6 +2196,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#mapReduce(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String, java.lang.Class, java.lang.String, java.lang.String, org.springframework.data.mongodb.core.mapreduce.MapReduceOptions)
*/
@Override
public <T> Flux<T> mapReduce(Query filterQuery, Class<?> domainType, String inputCollectionName, Class<T> resultType,
String mapFunction, String reduceFunction, MapReduceOptions options) {
@@ -3147,6 +3218,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
*/
interface ReactiveCollectionQueryCallback<T> extends ReactiveCollectionCallback<T> {
@Override
FindPublisher<T> doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException;
}
@@ -3173,6 +3245,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
this.collectionName = collectionName;
}
@Override
public Mono<T> doWith(Document document) {
maybeEmitEvent(new AfterLoadEvent<>(document, type, collectionName));
@@ -3213,6 +3286,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
this.collectionName = collectionName;
}
@Override
@SuppressWarnings("unchecked")
public Mono<T> doWith(Document document) {
@@ -3267,6 +3341,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
this.metric = metric;
}
@Override
public Mono<GeoResult<T>> doWith(Document object) {
double distance = getDistance(object);
@@ -3298,6 +3373,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
this.type = type;
}
@Override
public FindPublisher<Document> prepare(FindPublisher<Document> findPublisher) {
FindPublisher<Document> findPublisherToUse = operations.forType(type) //

View File

@@ -675,10 +675,7 @@ public class ConditionalOperators {
if (value instanceof CriteriaDefinition) {
Document mappedObject = context.getMappedObject(((CriteriaDefinition) value).getCriteriaObject());
List<Object> clauses = new ArrayList<Object>();
clauses.addAll(getClauses(context, mappedObject));
List<Object> clauses = getClauses(context, mappedObject);
return clauses.size() == 1 ? clauses.get(0) : clauses;
}
@@ -705,7 +702,9 @@ public class ConditionalOperators {
if (predicate instanceof List) {
List<Object> args = new ArrayList<Object>();
List<?> predicates = (List<?>) predicate;
List<Object> args = new ArrayList<Object>(predicates.size());
for (Object clause : (List<?>) predicate) {
if (clause instanceof Document) {
args.addAll(getClauses(context, (Document) clause));
@@ -723,14 +722,14 @@ public class ConditionalOperators {
continue;
}
List<Object> args = new ArrayList<Object>();
List<Object> args = new ArrayList<Object>(2);
args.add("$" + key);
args.add(nested.get(s));
clauses.add(new Document(s, args));
}
} else if (!isKeyword(key)) {
List<Object> args = new ArrayList<Object>();
List<Object> args = new ArrayList<Object>(2);
args.add("$" + key);
args.add(predicate);
clauses.add(new Document("$eq", args));

View File

@@ -110,7 +110,7 @@ public final class ExposedFields implements Iterable<ExposedField> {
private static ExposedFields createFields(Fields fields, boolean synthetic) {
Assert.notNull(fields, "Fields must not be null!");
List<ExposedField> result = new ArrayList<ExposedField>();
List<ExposedField> result = new ArrayList<ExposedField>(fields.size());
for (Field field : fields) {
result.add(new ExposedField(field, synthetic));

View File

@@ -167,6 +167,10 @@ public final class Fields implements Iterable<Field> {
return result;
}
public int size() {
return fields.size();
}
@Nullable
public Field getField(String name) {
@@ -267,7 +271,7 @@ public final class Fields implements Iterable<Field> {
*/
public String getTarget() {
if (isLocalVar()) {
if (isLocalVar() || pointsToDBRefId()) {
return this.getRaw();
}
@@ -296,6 +300,10 @@ public final class Fields implements Iterable<Field> {
return raw.startsWith("$$") && !raw.startsWith("$$$");
}
protected boolean pointsToDBRefId() { // see https://jira.mongodb.org/browse/SERVER-14466
return raw.endsWith(".$id");
}
/**
* @return
* @since 1.10

View File

@@ -126,7 +126,7 @@ public class GeoNearOperation implements AggregationOperation {
Document command = toDocument(context);
Number limit = (Number) command.get("$geoNear", Document.class).remove("num");
List<Document> stages = new ArrayList<>();
List<Document> stages = new ArrayList<>(3);
stages.add(command);
if (nearQuery.getSkip() != null && nearQuery.getSkip() > 0) {

View File

@@ -446,7 +446,7 @@ public class ScriptOperators {
/**
* Define the optional {@code initArgs} for the {@link #init(String)} function.
*
* @param function must not be {@literal null}.
* @param args must not be {@literal null}.
* @return this.
*/
@Override

View File

@@ -138,7 +138,7 @@ public class DefaultDbRefResolver extends DefaultReferenceResolver implements Db
List<Document> result = mongoCollection //
.find(new Document(BasicMongoPersistentProperty.ID_FIELD_NAME, new Document("$in", ids))) //
.into(new ArrayList<>());
.into(new ArrayList<>(ids.size()));
return ids.stream() //
.flatMap(id -> documentWithId(id, result)) //

View File

@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.TreeMap;
import org.bson.Document;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
@@ -44,12 +45,10 @@ import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon;
import org.springframework.data.mongodb.core.geo.Sphere;
import org.springframework.data.mongodb.core.query.GeoCommand;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
import org.springframework.util.ObjectUtils;
import com.mongodb.BasicDBList;
import com.mongodb.Function;
/**
@@ -61,9 +60,9 @@ import com.mongodb.Function;
* @author Thiago Diniz da Silveira
* @since 1.5
*/
@SuppressWarnings("ConstantConditions")
abstract class GeoConverters {
private final static Map<String, Function<Document, GeoJson<?>>> converters;
static {
@@ -93,7 +92,6 @@ abstract class GeoConverters {
*
* @return never {@literal null}.
*/
@SuppressWarnings("unchecked")
public static Collection<? extends Object> getConvertersToRegister() {
return Arrays.asList( //
BoxToDocumentConverter.INSTANCE //
@@ -464,7 +462,7 @@ abstract class GeoConverters {
return null;
}
List argument = new ArrayList();
List<Object> argument = new ArrayList<>(2);
Shape shape = source.getShape();
@@ -482,14 +480,11 @@ abstract class GeoConverters {
argument.add(toList(((Circle) shape).getCenter()));
argument.add(((Circle) shape).getRadius().getNormalizedValue());
} else if (shape instanceof Circle) {
argument.add(toList(((Circle) shape).getCenter()));
argument.add(((Circle) shape).getRadius());
} else if (shape instanceof Polygon) {
for (Point point : ((Polygon) shape).getPoints()) {
List<Point> points = ((Polygon) shape).getPoints();
argument = new ArrayList(points.size());
for (Point point : points) {
argument.add(toList(point));
}
@@ -507,8 +502,7 @@ abstract class GeoConverters {
* @author Christoph Strobl
* @since 1.7
*/
@SuppressWarnings("rawtypes")
enum GeoJsonToDocumentConverter implements Converter<GeoJson, Document> {
enum GeoJsonToDocumentConverter implements Converter<GeoJson<?>, Document> {
INSTANCE;
@@ -517,7 +511,7 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public Document convert(GeoJson source) {
public Document convert(GeoJson<?> source) {
if (source == null) {
return null;
@@ -527,33 +521,33 @@ abstract class GeoConverters {
if (source instanceof GeoJsonGeometryCollection) {
List dbl = new ArrayList();
List<Object> dbl = new ArrayList<>();
for (GeoJson geometry : ((GeoJsonGeometryCollection) source).getCoordinates()) {
for (GeoJson<?> geometry : ((GeoJsonGeometryCollection) source).getCoordinates()) {
dbl.add(convert(geometry));
}
dbo.put("geometries", dbl);
} else {
dbo.put("coordinates", convertIfNecessarry(source.getCoordinates()));
dbo.put("coordinates", convertIfNecessary(source.getCoordinates()));
}
return dbo;
}
private Object convertIfNecessarry(Object candidate) {
private Object convertIfNecessary(Object candidate) {
if (candidate instanceof GeoJson) {
return convertIfNecessarry(((GeoJson) candidate).getCoordinates());
return convertIfNecessary(((GeoJson<?>) candidate).getCoordinates());
}
if (candidate instanceof Iterable) {
if (candidate instanceof Iterable<?>) {
List dbl = new ArrayList();
List<Object> dbl = new ArrayList<>();
for (Object element : (Iterable) candidate) {
dbl.add(convertIfNecessarry(element));
for (Object element : (Iterable<?>) candidate) {
dbl.add(convertIfNecessary(element));
}
return dbl;
@@ -653,7 +647,7 @@ abstract class GeoConverters {
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "Polygon"),
String.format("Cannot convert type '%s' to Polygon.", source.get("type")));
return toGeoJsonPolygon((List) source.get("coordinates"));
return toGeoJsonPolygon((List<?>) source.get("coordinates"));
}
}
@@ -679,11 +673,11 @@ abstract class GeoConverters {
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "MultiPolygon"),
String.format("Cannot convert type '%s' to MultiPolygon.", source.get("type")));
List dbl = (List) source.get("coordinates");
List<?> dbl = (List<?>) source.get("coordinates");
List<GeoJsonPolygon> polygones = new ArrayList<>();
for (Object polygon : dbl) {
polygones.add(toGeoJsonPolygon((List) polygon));
polygones.add(toGeoJsonPolygon((List<?>) polygon));
}
return new GeoJsonMultiPolygon(polygones);
@@ -712,7 +706,7 @@ abstract class GeoConverters {
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "LineString"),
String.format("Cannot convert type '%s' to LineString.", source.get("type")));
List cords = (List) source.get("coordinates");
List<?> cords = (List<?>) source.get("coordinates");
return new GeoJsonLineString(toListOfPoint(cords));
}
@@ -740,7 +734,7 @@ abstract class GeoConverters {
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "MultiPoint"),
String.format("Cannot convert type '%s' to MultiPoint.", source.get("type")));
List cords = (List) source.get("coordinates");
List<?> cords = (List<?>) source.get("coordinates");
return new GeoJsonMultiPoint(toListOfPoint(cords));
}
@@ -768,11 +762,11 @@ abstract class GeoConverters {
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "MultiLineString"),
String.format("Cannot convert type '%s' to MultiLineString.", source.get("type")));
List<GeoJsonLineString> lines = new ArrayList<GeoJsonLineString>();
List cords = (List) source.get("coordinates");
List<GeoJsonLineString> lines = new ArrayList<>();
List<?> cords = (List<?>) source.get("coordinates");
for (Object line : cords) {
lines.add(new GeoJsonLineString(toListOfPoint((List) line)));
lines.add(new GeoJsonLineString(toListOfPoint((List<?>) line)));
}
return new GeoJsonMultiLineString(lines);
}
@@ -815,16 +809,16 @@ abstract class GeoConverters {
}
/**
* Converts a coordinate pairs nested in in {@link BasicDBList} into {@link GeoJsonPoint}s.
* Converts a coordinate pairs nested in {@link List} into {@link GeoJsonPoint}s.
*
* @param listOfCoordinatePairs must not be {@literal null}.
* @return never {@literal null}.
* @since 1.7
*/
@SuppressWarnings("unchecked")
static List<Point> toListOfPoint(List listOfCoordinatePairs) {
static List<Point> toListOfPoint(List<?> listOfCoordinatePairs) {
List<Point> points = new ArrayList<>();
List<Point> points = new ArrayList<>(listOfCoordinatePairs.size());
for (Object point : listOfCoordinatePairs) {
@@ -839,14 +833,16 @@ abstract class GeoConverters {
}
/**
* Converts a coordinate pairs nested in in {@link BasicDBList} into {@link GeoJsonPolygon}.
* Converts a coordinate pairs nested in {@link List} into {@link GeoJsonPolygon}.
*
* @param dbList must not be {@literal null}.
* @return never {@literal null}.
* @since 1.7
*/
static GeoJsonPolygon toGeoJsonPolygon(List dbList) {
return new GeoJsonPolygon(toListOfPoint((List) dbList.get(0)));
static GeoJsonPolygon toGeoJsonPolygon(List<?> dbList) {
GeoJsonPolygon polygon = new GeoJsonPolygon(toListOfPoint((List<?>) dbList.get(0)));
return dbList.size() > 1 ? polygon.withInnerRing(toListOfPoint((List<?>) dbList.get(1))) : polygon;
}
/**
@@ -857,17 +853,11 @@ abstract class GeoConverters {
* @author Christoph Strobl
*/
@ReadingConverter
enum DocumentToGeoJsonConverter implements Converter<Document, GeoJson> {
enum DocumentToGeoJsonConverter implements Converter<Document, GeoJson<?>> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Nullable
@Override
public GeoJson convert(Document source) {
public GeoJson<?> convert(Document source) {
return toGenericGeoJson(source);
}
}
@@ -876,22 +866,21 @@ abstract class GeoConverters {
String type = source.get("type", String.class);
if(type != null) {
if (type != null) {
Function<Document, GeoJson<?>> converter = converters.get(type);
if(converter != null){
if (converter != null) {
return converter.apply(source);
}
}
throw new IllegalArgumentException(
String.format("No converter found capable of converting GeoJson type %s.", type));
throw new IllegalArgumentException(String.format("No converter found capable of converting GeoJson type %s.", type));
}
private static double toPrimitiveDoubleValue(Object value) {
Assert.isInstanceOf(Number.class, value, "Argument must be a Number.");
return NumberUtils.convertNumberToTargetClass((Number) value, Double.class).doubleValue();
return NumberUtils.convertNumberToTargetClass((Number) value, Double.class);
}
}

View File

@@ -886,14 +886,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}).collect(Collectors.toList());
return writeCollectionInternal(targetCollection, ClassTypeInformation.from(DocumentPointer.class),
new ArrayList<>());
new ArrayList<>(targetCollection.size()));
}
if (property.hasExplicitWriteTarget()) {
return writeCollectionInternal(collection, new FieldTypeInformation<>(property), new ArrayList<>());
return writeCollectionInternal(collection, new FieldTypeInformation<>(property), new ArrayList<>(collection.size()));
}
return writeCollectionInternal(collection, property.getTypeInformation(), new ArrayList<>());
return writeCollectionInternal(collection, property.getTypeInformation(), new ArrayList<>(collection.size()));
}
List<Object> dbList = new ArrayList<>(collection.size());
@@ -978,7 +978,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
collection.add(getPotentiallyConvertedSimpleWrite(element,
componentType != null ? componentType.getType() : Object.class));
} else if (element instanceof Collection || elementType.isArray()) {
collection.add(writeCollectionInternal(BsonUtils.asCollection(element), componentType, new ArrayList<>()));
Collection<?> objects = BsonUtils.asCollection(element);
collection.add(writeCollectionInternal(objects, componentType, new ArrayList<>(objects.size())));
} else {
Document document = new Document();
writeInternal(element, document, componentType);

View File

@@ -363,7 +363,7 @@ public class QueryMapper {
if (keyword.isOrOrNor() || (keyword.hasIterableValue() && !keyword.isGeometry())) {
Iterable<?> conditions = keyword.getValue();
List<Object> newConditions = new ArrayList<>();
List<Object> newConditions = conditions instanceof Collection ? new ArrayList<>(((Collection<?>) conditions).size()) : new ArrayList<>();
for (Object condition : conditions) {
newConditions.add(isDocument(condition) ? getMappedObject((Document) condition, entity)

View File

@@ -15,8 +15,10 @@
*/
package org.springframework.data.mongodb.core.convert;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import org.bson.Document;
@@ -34,6 +36,7 @@ import org.springframework.data.mongodb.core.query.Update.Modifiers;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
* A subclass of {@link QueryMapper} that retains type information on the mongo types.
@@ -221,8 +224,18 @@ public class UpdateMapper extends QueryMapper {
: getMappedSort(sortObject, field.getPropertyEntity());
}
TypeInformation<?> typeHint = field == null ? ClassTypeInformation.OBJECT : field.getTypeHint();
if (isAssociationConversionNecessary(field, value)) {
if (ObjectUtils.isArray(value) || value instanceof Collection) {
List<Object> targetPointers = new ArrayList<>();
for (Object val : converter.getConversionService().convert(value, List.class)) {
targetPointers.add(getMappedValue(field, val));
}
return targetPointers;
}
return super.getMappedValue(field, value);
}
TypeInformation<?> typeHint = field == null ? ClassTypeInformation.OBJECT : field.getTypeHint();
return converter.convertToMongoType(value, typeHint);
}

View File

@@ -24,6 +24,7 @@ import java.util.List;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* {@link GeoJson} representation of {@link Polygon}. Unlike {@link Polygon} the {@link GeoJsonPolygon} requires a
@@ -142,4 +143,28 @@ public class GeoJsonPolygon extends Polygon implements GeoJson<List<GeoJsonLineS
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
GeoJsonPolygon that = (GeoJsonPolygon) o;
return ObjectUtils.nullSafeEquals(this.coordinates, that.coordinates);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + ObjectUtils.nullSafeHashCode(coordinates);
return result;
}
}

View File

@@ -73,7 +73,7 @@ public class BasicQuery extends Query {
*
* @param queryObject must not be {@literal null}.
* @param fieldsObject must not be {@literal null}.
* @throws IllegalArgumentException when {@code sortObject} or {@code fieldsObject} is {@literal null}.
* @throws IllegalArgumentException when {@code queryObject} or {@code fieldsObject} is {@literal null}.
*/
public BasicQuery(Document queryObject, Document fieldsObject) {

View File

@@ -337,7 +337,7 @@ public class Criteria implements CriteriaDefinition {
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/mod/">MongoDB Query operator: $mod</a>
*/
public Criteria mod(Number value, Number remainder) {
List<Object> l = new ArrayList<Object>();
List<Object> l = new ArrayList<Object>(2);
l.add(value);
l.add(remainder);
criteria.put("$mod", l);
@@ -450,7 +450,7 @@ public class Criteria implements CriteriaDefinition {
Assert.notNull(types, "Types must not be null!");
criteria.put("$type", types.stream().map(Type::value).collect(Collectors.toList()));
criteria.put("$type", types.stream().map(Type::toBsonType).map(Type::value).collect(Collectors.toList()));
return this;
}

View File

@@ -124,9 +124,10 @@ public class Query {
}
/**
* Set number of documents to skip before returning results.
* Set number of documents to skip before returning results. Use {@literal zero} or a {@literal negative} value to
* avoid skipping.
*
* @param skip
* @param skip number of documents to skip. Use {@literal zero} or a {@literal negative} value to avoid skipping.
* @return this.
*/
public Query skip(long skip) {
@@ -135,9 +136,10 @@ public class Query {
}
/**
* Limit the number of returned documents to {@code limit}.
* Limit the number of returned documents to {@code limit}. A {@literal zero} or {@literal negative} value is
* considered as unlimited.
*
* @param limit
* @param limit number of documents to return. Use {@literal zero} or {@literal negative} for unlimited.
* @return this.
*/
public Query limit(int limit) {
@@ -314,7 +316,7 @@ public class Query {
}
/**
* Get the number of documents to skip.
* Get the number of documents to skip. {@literal Zero} or a {@literal negative} value indicates no skip.
*
* @return number of documents to skip
*/
@@ -323,7 +325,8 @@ public class Query {
}
/**
* Get the maximum number of documents to be return.
* Get the maximum number of documents to be return. {@literal Zero} or a {@literal negative} value indicates no
* limit.
*
* @return number of documents to return.
*/

View File

@@ -587,7 +587,7 @@ public class TypedJsonSchemaObject extends UntypedJsonSchemaObject {
* @param value must not be {@literal null}.
* @return must not be {@literal null}.
*/
NumericJsonSchemaObject multipleOf(Number value) {
public NumericJsonSchemaObject multipleOf(Number value) {
Assert.notNull(value, "Value must not be null!");
NumericJsonSchemaObject newInstance = newInstance(description, generateDescription, restrictions);
@@ -665,7 +665,7 @@ public class TypedJsonSchemaObject extends UntypedJsonSchemaObject {
* @return new instance of {@link NumericJsonSchemaObject}.
*/
@SuppressWarnings("unchecked")
NumericJsonSchemaObject lte(Number max) {
public NumericJsonSchemaObject lte(Number max) {
Assert.notNull(max, "Max must not be null!");

View File

@@ -223,8 +223,10 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
if (property.isAssociation()) {
if (next.getClass().isArray() || next instanceof Iterable) {
List<DBRef> dbRefs = new ArrayList<DBRef>();
for (Object element : asCollection(next)) {
Collection<?> values = asCollection(next);
List<DBRef> dbRefs = new ArrayList<DBRef>(values.size());
for (Object element : values) {
dbRefs.add(writer.toDBRef(element, property));
}
@@ -258,11 +260,14 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
if (source instanceof Iterable) {
List<Object> result = new ArrayList<Object>();
if(source instanceof Collection) {
return new ArrayList<>((Collection<?>) source);
}
List<Object> result = new ArrayList<>();
for (Object element : (Iterable<?>) source) {
result.add(element);
}
return result;
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.util.json;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import org.springframework.data.mapping.model.SpELExpressionEvaluator;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.lang.Nullable;
/**
* @author Christoph Strobl
* @since 3.3.5
*/
class EvaluationContextExpressionEvaluator implements SpELExpressionEvaluator {
ValueProvider valueProvider;
ExpressionParser expressionParser;
Supplier<EvaluationContext> evaluationContext;
public EvaluationContextExpressionEvaluator(ValueProvider valueProvider, ExpressionParser expressionParser,
Supplier<EvaluationContext> evaluationContext) {
this.valueProvider = valueProvider;
this.expressionParser = expressionParser;
this.evaluationContext = evaluationContext;
}
@Nullable
@Override
public <T> T evaluate(String expression) {
return evaluateExpression(expression, Collections.emptyMap());
}
public EvaluationContext getEvaluationContext(String expressionString) {
return evaluationContext != null ? evaluationContext.get() : new StandardEvaluationContext();
}
public SpelExpression getParsedExpression(String expressionString) {
return (SpelExpression) (expressionParser != null ? expressionParser : new SpelExpressionParser())
.parseExpression(expressionString);
}
public <T> T evaluateExpression(String expressionString, Map<String, Object> variables) {
SpelExpression expression = getParsedExpression(expressionString);
EvaluationContext ctx = getEvaluationContext(expressionString);
variables.entrySet().forEach(entry -> ctx.setVariable(entry.getKey(), entry.getValue()));
Object result = expression.getValue(ctx, Object.class);
return (T) result;
}
}

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.mongodb.util.json;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -58,13 +59,7 @@ public class ParameterBindingContext {
*/
public ParameterBindingContext(ValueProvider valueProvider, ExpressionParser expressionParser,
Supplier<EvaluationContext> evaluationContext) {
this(valueProvider, new SpELExpressionEvaluator() {
@Override
public <T> T evaluate(String expressionString) {
return (T) expressionParser.parseExpression(expressionString).getValue(evaluationContext.get(), Object.class);
}
});
this(valueProvider, new EvaluationContextExpressionEvaluator(valueProvider, expressionParser, evaluationContext));
}
/**
@@ -87,20 +82,20 @@ public class ParameterBindingContext {
* @return
* @since 3.1
*/
public static ParameterBindingContext forExpressions(ValueProvider valueProvider,
ExpressionParser expressionParser, Function<ExpressionDependencies, EvaluationContext> contextFunction) {
public static ParameterBindingContext forExpressions(ValueProvider valueProvider, ExpressionParser expressionParser,
Function<ExpressionDependencies, EvaluationContext> contextFunction) {
return new ParameterBindingContext(valueProvider, new SpELExpressionEvaluator() {
@Override
public <T> T evaluate(String expressionString) {
return new ParameterBindingContext(valueProvider,
new EvaluationContextExpressionEvaluator(valueProvider, expressionParser, null) {
Expression expression = expressionParser.parseExpression(expressionString);
ExpressionDependencies dependencies = ExpressionDependencies.discover(expression);
EvaluationContext evaluationContext = contextFunction.apply(dependencies);
@Override
public EvaluationContext getEvaluationContext(String expressionString) {
return (T) expression.getValue(evaluationContext, Object.class);
}
});
Expression expression = getParsedExpression(expressionString);
ExpressionDependencies dependencies = ExpressionDependencies.discover(expression);
return contextFunction.apply(dependencies);
}
});
}
@Nullable
@@ -113,6 +108,16 @@ public class ParameterBindingContext {
return expressionEvaluator.evaluate(expressionString);
}
@Nullable
public Object evaluateExpression(String expressionString, Map<String, Object> variables) {
if (expressionEvaluator instanceof EvaluationContextExpressionEvaluator) {
return ((EvaluationContextExpressionEvaluator) expressionEvaluator).evaluateExpression(expressionString,
variables);
}
return expressionEvaluator.evaluate(expressionString);
}
public ValueProvider getValueProvider() {
return valueProvider;
}

View File

@@ -20,8 +20,12 @@ import static java.lang.String.*;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
@@ -64,6 +68,7 @@ public class ParameterBindingJsonReader extends AbstractBsonReader {
private static final Pattern PARAMETER_ONLY_BINDING_PATTERN = Pattern.compile("^\\?(\\d+)$");
private static final Pattern PARAMETER_BINDING_PATTERN = Pattern.compile("\\?(\\d+)");
private static final Pattern EXPRESSION_BINDING_PATTERN = Pattern.compile("[\\?:]#\\{.*\\}");
private static final Pattern SPEL_PARAMETER_BINDING_PATTERN = Pattern.compile("('\\?(\\d+)'|\\?(\\d+))");
private final ParameterBindingContext bindingContext;
@@ -379,14 +384,24 @@ public class ParameterBindingJsonReader extends AbstractBsonReader {
String binding = regexMatcher.group();
String expression = binding.substring(3, binding.length() - 1);
Matcher inSpelMatcher = PARAMETER_BINDING_PATTERN.matcher(expression);
Matcher inSpelMatcher = SPEL_PARAMETER_BINDING_PATTERN.matcher(expression); // ?0 '?0'
Map<String, Object> innerSpelVariables = new HashMap<>();
while (inSpelMatcher.find()) {
int index = computeParameterIndex(inSpelMatcher.group());
expression = expression.replace(inSpelMatcher.group(), getBindableValueForIndex(index).toString());
String group = inSpelMatcher.group();
int index = computeParameterIndex(group);
Object value = getBindableValueForIndex(index);
String varName = "__QVar" + innerSpelVariables.size();
expression = expression.replace(group, "#" + varName);
if(group.startsWith("'")) { // retain the string semantic
innerSpelVariables.put(varName, nullSafeToString(value));
} else {
innerSpelVariables.put(varName, value);
}
}
Object value = evaluateExpression(expression);
Object value = evaluateExpression(expression, innerSpelVariables);
bindableValue.setValue(value);
bindableValue.setType(bsonTypeForValue(value));
return bindableValue;
@@ -415,14 +430,24 @@ public class ParameterBindingJsonReader extends AbstractBsonReader {
String binding = regexMatcher.group();
String expression = binding.substring(3, binding.length() - 1);
Matcher inSpelMatcher = PARAMETER_BINDING_PATTERN.matcher(expression);
Matcher inSpelMatcher = SPEL_PARAMETER_BINDING_PATTERN.matcher(expression);
Map<String, Object> innerSpelVariables = new HashMap<>();
while (inSpelMatcher.find()) {
int index = computeParameterIndex(inSpelMatcher.group());
expression = expression.replace(inSpelMatcher.group(), getBindableValueForIndex(index).toString());
String group = inSpelMatcher.group();
int index = computeParameterIndex(group);
Object value = getBindableValueForIndex(index);
String varName = "__QVar" + innerSpelVariables.size();
expression = expression.replace(group, "#" + varName);
if(group.startsWith("'")) { // retain the string semantic
innerSpelVariables.put(varName, nullSafeToString(value));
} else {
innerSpelVariables.put(varName, value);
}
}
computedValue = computedValue.replace(binding, nullSafeToString(evaluateExpression(expression)));
computedValue = computedValue.replace(binding, nullSafeToString(evaluateExpression(expression, innerSpelVariables)));
bindableValue.setValue(computedValue);
bindableValue.setType(BsonType.STRING);
@@ -459,7 +484,7 @@ public class ParameterBindingJsonReader extends AbstractBsonReader {
}
private static int computeParameterIndex(String parameter) {
return NumberUtils.parseNumber(parameter.replace("?", ""), Integer.class);
return NumberUtils.parseNumber(parameter.replace("?", "").replace("'", ""), Integer.class);
}
private Object getBindableValueForIndex(int index) {
@@ -511,7 +536,12 @@ public class ParameterBindingJsonReader extends AbstractBsonReader {
@Nullable
private Object evaluateExpression(String expressionString) {
return bindingContext.evaluateExpression(expressionString);
return bindingContext.evaluateExpression(expressionString, Collections.emptyMap());
}
@Nullable
private Object evaluateExpression(String expressionString, Map<String,Object> variables) {
return bindingContext.evaluateExpression(expressionString, variables);
}
// Spring Data Customization END

View File

@@ -131,13 +131,15 @@ public class MappingMongoConverterParserIntegrationTests {
private void loadConfiguration(String configLocation) {
factory = new DefaultListableBeanFactory();
factory.setAllowBeanDefinitionOverriding(false);
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new ClassPathResource(configLocation));
}
private static void assertStrategyReferenceSetFor(String beanId) {
BeanDefinitionRegistry factory = new DefaultListableBeanFactory();
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.setAllowBeanDefinitionOverriding(false);
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-custom-fieldnamingstrategy.xml"));

View File

@@ -29,6 +29,8 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.schema.JsonSchemaProperty;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
import org.springframework.data.mongodb.test.util.Client;
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
@@ -83,6 +85,28 @@ public class JsonSchemaQueryTests {
template.save(jellyBelly);
template.save(roseSpringHeart);
template.save(kazmardBoombub);
}
@Test // DATAMONGO-1835
public void createsWorkingSchema() {
try {
template.dropCollection("person_schema");
} catch (Exception e) {}
MongoJsonSchema schema = MongoJsonSchemaCreator.create(template.getConverter()).createSchemaFor(Person.class);
template.createCollection("person_schema", CollectionOptions.empty().schema(schema));
}
@Test // DATAMONGO-1835
public void queriesBooleanType() {
MongoJsonSchema schema = MongoJsonSchema.builder().properties(JsonSchemaProperty.bool("alive")).build();
assertThat(template.find(query(matchingDocumentStructure(schema)), Person.class)).hasSize(3);
assertThat(template.find(query(Criteria.where("alive").type(Type.BOOLEAN)), Person.class)).hasSize(3);
}
@Test // DATAMONGO-1835
@@ -201,6 +225,8 @@ public class JsonSchemaQueryTests {
Gender gender;
Address address;
Object value;
boolean alive;
}
@Data

View File

@@ -903,6 +903,29 @@ public class MongoTemplateDocumentReferenceTests {
assertThat(target).containsEntry("toB", "b");
}
@Test // GH-4041
void updateReferenceWithPushToCollection() {
WithListOfRefs a = new WithListOfRefs();
a.id = "a";
template.save(a);
WithListOfRefs b = new WithListOfRefs();
b.id = "b";
template.save(b);
template.update(WithListOfRefs.class).matching(where("id").is(a.id))
.apply(new Update().push("refs").each(new Object[] { b })).first();
String collection = template.getCollectionName(WithListOfRefs.class);
Document target = template.execute(db -> {
return db.getCollection(collection).find(Filters.eq("_id", "a")).first();
});
assertThat(target).containsEntry("refs", Collections.singletonList("b"));
}
@Test // GH-3782
void updateReferenceHavingCustomizedIdTargetType() {
@@ -1584,4 +1607,11 @@ public class MongoTemplateDocumentReferenceTests {
return publisher;
}
}
@Data
public static class WithListOfRefs {
@Id private String id;
@DocumentReference private List<WithListOfRefs> refs;
}
}

View File

@@ -39,6 +39,8 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.assertj.core.api.Assertions;
import org.bson.BsonDocument;
import org.bson.BsonString;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
@@ -110,6 +112,7 @@ import com.mongodb.client.result.InsertManyResult;
import com.mongodb.client.result.InsertOneResult;
import com.mongodb.client.result.UpdateResult;
import com.mongodb.reactivestreams.client.AggregatePublisher;
import com.mongodb.reactivestreams.client.ChangeStreamPublisher;
import com.mongodb.reactivestreams.client.DistinctPublisher;
import com.mongodb.reactivestreams.client.FindPublisher;
import com.mongodb.reactivestreams.client.MapReducePublisher;
@@ -145,6 +148,7 @@ public class ReactiveMongoTemplateUnitTests {
@Mock DistinctPublisher distinctPublisher;
@Mock Publisher deletePublisher;
@Mock MapReducePublisher mapReducePublisher;
@Mock ChangeStreamPublisher changeStreamPublisher;
private MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
private MappingMongoConverter converter;
@@ -1455,6 +1459,24 @@ public class ReactiveMongoTemplateUnitTests {
.granularity(TimeSeriesGranularity.HOURS).toString());
}
@Test // GH-4167
void changeStreamOptionStartAftershouldApplied() {
when(factory.getMongoDatabase(anyString())).thenReturn(Mono.just(db));
when(collection.watch(any(Class.class))).thenReturn(changeStreamPublisher);
when(changeStreamPublisher.batchSize(anyInt())).thenReturn(changeStreamPublisher);
when(changeStreamPublisher.startAfter(any())).thenReturn(changeStreamPublisher);
when(changeStreamPublisher.fullDocument(any())).thenReturn(changeStreamPublisher);
BsonDocument token = new BsonDocument("token", new BsonString("id"));
template
.changeStream("database", "collection", ChangeStreamOptions.builder().startAfter(token).build(), Object.class)
.subscribe();
verify(changeStreamPublisher).startAfter(eq(token));
}
private void stubFindSubscribe(Document document) {
Publisher<Document> realPublisher = Flux.just(document);

View File

@@ -66,6 +66,7 @@ import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.Person;
import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion;
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
import org.springframework.data.mongodb.test.util.MongoVersion;
@@ -315,6 +316,7 @@ public class AggregationTests {
}
@Test // DATAMONGO-1391
@EnableIfMongoServerVersion(isLessThan = "6.0")
void shouldUnwindPreserveEmpty() {
MongoCollection<Document> coll = mongoTemplate.getCollection(INPUT_COLLECTION);

View File

@@ -117,6 +117,13 @@ public class FieldsUnitTests {
assertThat(Fields.field("$$$$target").getTarget()).isEqualTo("target");
}
@Test // GH-4123
public void keepsRawMappingToDbRefId() {
assertThat(Fields.field("$id").getName()).isEqualTo("id");
assertThat(Fields.field("person.$id").getTarget()).isEqualTo("person.$id");
}
private static void verify(Field field, String name, String target) {
assertThat(field).isNotNull();

View File

@@ -117,8 +117,8 @@ public class GeoSpatialIndexTests extends AbstractIntegrationTests {
/**
* Returns whether an index with the given name exists for the given entity type.
*
* @param indexName
* @param entityType
* @param type
* @return
*/
private boolean hasIndexOfType(Class<?> entityType, final String type) {

View File

@@ -45,7 +45,7 @@ class SubscriptionUtils {
* Wait for all {@link Subscription Subscriptions} to {@link Subscription#isActive() become active} but not longer
* than {@link #DEFAULT_TIMEOUT}.
*
* @param subscription
* @param subscriptions
* @throws InterruptedException
*/
static void awaitSubscriptions(Subscription... subscriptions) throws InterruptedException {
@@ -131,7 +131,8 @@ class SubscriptionUtils {
/**
* {@link MessageListener} implementation collecting received {@link Message messages}.
*
* @param <M>
* @param <S> source message type.
* @param <T> target message type.
*/
static class CollectingMessageListener<S, T> implements MessageListener<S, T> {

View File

@@ -23,11 +23,11 @@ import java.util.Collections;
import org.bson.Document;
import org.junit.Test;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
import org.springframework.data.mongodb.core.geo.GeoJsonLineString;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
/**
@@ -90,8 +90,7 @@ public class CriteriaUnitTests {
@Test // GH-3286
public void shouldBuildCorrectAndOperator() {
Collection<Criteria> operatorCriteria = Arrays.asList(Criteria.where("x").is(true),
Criteria.where("y").is(42),
Collection<Criteria> operatorCriteria = Arrays.asList(Criteria.where("x").is(true), Criteria.where("y").is(42),
Criteria.where("z").is("value"));
Criteria criteria = Criteria.where("foo").is("bar").andOperator(operatorCriteria);
@@ -103,8 +102,7 @@ public class CriteriaUnitTests {
@Test // GH-3286
public void shouldBuildCorrectOrOperator() {
Collection<Criteria> operatorCriteria = Arrays.asList(Criteria.where("x").is(true),
Criteria.where("y").is(42),
Collection<Criteria> operatorCriteria = Arrays.asList(Criteria.where("x").is(true), Criteria.where("y").is(42),
Criteria.where("z").is("value"));
Criteria criteria = Criteria.where("foo").is("bar").orOperator(operatorCriteria);
@@ -116,8 +114,7 @@ public class CriteriaUnitTests {
@Test // GH-3286
public void shouldBuildCorrectNorOperator() {
Collection<Criteria> operatorCriteria = Arrays.asList(Criteria.where("x").is(true),
Criteria.where("y").is(42),
Collection<Criteria> operatorCriteria = Arrays.asList(Criteria.where("x").is(true), Criteria.where("y").is(42),
Criteria.where("z").is("value"));
Criteria criteria = Criteria.where("foo").is("bar").norOperator(operatorCriteria);
@@ -205,6 +202,14 @@ public class CriteriaUnitTests {
assertThat(document).isEqualTo(new Document().append("$not", new Document("$lt", "foo")));
}
@Test // GH-4220
public void usesCorrectBsonType() {
Document document = new Criteria("foo").type(Type.BOOLEAN).getCriteriaObject();
assertThat(document).containsEntry("foo.$type", Collections.singletonList("bool"));
}
@Test // DATAMONGO-1135
public void geoJsonTypesShouldBeWrappedInGeometry() {
@@ -302,8 +307,7 @@ public class CriteriaUnitTests {
Criteria numericBitmaskCriteria = new Criteria("field").bits().allClear(0b101);
assertThat(numericBitmaskCriteria.getCriteriaObject())
.isEqualTo("{ \"field\" : { \"$bitsAllClear\" : 5} }");
assertThat(numericBitmaskCriteria.getCriteriaObject()).isEqualTo("{ \"field\" : { \"$bitsAllClear\" : 5} }");
}
@Test // DATAMONGO-1808
@@ -320,8 +324,7 @@ public class CriteriaUnitTests {
Criteria numericBitmaskCriteria = new Criteria("field").bits().allSet(0b101);
assertThat(numericBitmaskCriteria.getCriteriaObject())
.isEqualTo("{ \"field\" : { \"$bitsAllSet\" : 5} }");
assertThat(numericBitmaskCriteria.getCriteriaObject()).isEqualTo("{ \"field\" : { \"$bitsAllSet\" : 5} }");
}
@Test // DATAMONGO-1808
@@ -338,8 +341,7 @@ public class CriteriaUnitTests {
Criteria numericBitmaskCriteria = new Criteria("field").bits().anyClear(0b101);
assertThat(numericBitmaskCriteria.getCriteriaObject())
.isEqualTo("{ \"field\" : { \"$bitsAnyClear\" : 5} }");
assertThat(numericBitmaskCriteria.getCriteriaObject()).isEqualTo("{ \"field\" : { \"$bitsAnyClear\" : 5} }");
}
@Test // DATAMONGO-1808
@@ -356,8 +358,7 @@ public class CriteriaUnitTests {
Criteria numericBitmaskCriteria = new Criteria("field").bits().anySet(0b101);
assertThat(numericBitmaskCriteria.getCriteriaObject())
.isEqualTo("{ \"field\" : { \"$bitsAnySet\" : 5} }");
assertThat(numericBitmaskCriteria.getCriteriaObject()).isEqualTo("{ \"field\" : { \"$bitsAnySet\" : 5} }");
}
@Test // DATAMONGO-1808
@@ -429,14 +430,10 @@ public class CriteriaUnitTests {
@Test // GH-3414
public void shouldEqualForNestedPattern() {
Criteria left = new Criteria("a").orOperator(
new Criteria("foo").regex("value", "i"),
new Criteria("bar").regex("value")
);
Criteria right = new Criteria("a").orOperator(
new Criteria("foo").regex("value", "i"),
new Criteria("bar").regex("value")
);
Criteria left = new Criteria("a").orOperator(new Criteria("foo").regex("value", "i"),
new Criteria("bar").regex("value"));
Criteria right = new Criteria("a").orOperator(new Criteria("foo").regex("value", "i"),
new Criteria("bar").regex("value"));
assertThat(left).isEqualTo(right);
}

View File

@@ -32,7 +32,7 @@ public abstract class Assertions extends org.assertj.core.api.Assertions {
/**
* Create assertion for {@link Document}.
*
* @param actual the actual value.
* @param document the actual value.
* @return the created assertion object.
*/
public static DocumentAssert assertThat(Document document) {

View File

@@ -25,6 +25,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.bson.Document;
import org.bson.codecs.DecoderContext;
@@ -32,6 +33,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.data.spel.EvaluationContextProvider;
import org.springframework.data.spel.ExpressionDependencies;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ParseException;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
@@ -390,6 +392,55 @@ class ParameterBindingJsonReaderUnitTests {
assertThat(target).isEqualTo(new Document("parent", null));
}
@Test // GH-4089
void retainsSpelArgumentTypeViaArgumentIndex() {
String source = "new java.lang.Object()";
Document target = parse("{ arg0 : ?#{[0]} }", source);
assertThat(target.get("arg0")).isEqualTo(source);
}
@Test // GH-4089
void retainsSpelArgumentTypeViaParameterPlaceholder() {
String source = "new java.lang.Object()";
Document target = parse("{ arg0 : :#{?0} }", source);
assertThat(target.get("arg0")).isEqualTo(source);
}
@Test // GH-4089
void enforcesStringSpelArgumentTypeViaParameterPlaceholderWhenQuoted() {
Integer source = 10;
Document target = parse("{ arg0 : :#{'?0'} }", source);
assertThat(target.get("arg0")).isEqualTo("10");
}
@Test // GH-4089
void enforcesSpelArgumentTypeViaParameterPlaceholderWhenQuoted() {
String source = "new java.lang.Object()";
Document target = parse("{ arg0 : :#{'?0'} }", source);
assertThat(target.get("arg0")).isEqualTo(source);
}
@Test // GH-4089
void retainsSpelArgumentTypeViaParameterPlaceholderWhenValueContainsSingleQuotes() {
String source = "' + new java.lang.Object() + '";
Document target = parse("{ arg0 : :#{?0} }", source);
assertThat(target.get("arg0")).isEqualTo(source);
}
@Test // GH-4089
void retainsSpelArgumentTypeViaParameterPlaceholderWhenValueContainsDoubleQuotes() {
String source = "\\\" + new java.lang.Object() + \\\"";
Document target = parse("{ arg0 : :#{?0} }", source);
assertThat(target.get("arg0")).isEqualTo(source);
}
private static Document parse(String json, Object... args) {
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json, args);

View File

@@ -49,6 +49,7 @@ In terms of document stores, you need at least version 3.6 of https://www.mongod
The following compatibility matrix summarizes Spring Data versions to MongoDB driver/database versions.
Database versions show the highest supported server version that pass the Spring Data test suite.
You can use newer server versions unless your application uses functionality that is affected by <<compatibility.changes,changes in the MongoDB server>>.
See also the https://www.mongodb.com/docs/drivers/java/sync/current/compatibility/[official MongoDB driver compatibility matrix] for driver- and server version compatibility.
[cols="h,m,m,m", options="header"]
|===
@@ -58,6 +59,11 @@ You can use newer server versions unless your application uses functionality tha
|Driver Version
|Server Version
|2021.1
|3.3.x
|4.4.x
|5.0.x
|2021.0
|3.2.x
|4.1.x
@@ -115,4 +121,4 @@ Professional Support :: Professional, from-the-source support, with guaranteed r
[[get-started:up-to-date]]
== Following Development
For information on the Spring Data Mongo source code repository, nightly builds, and snapshot artifacts, see the Spring Data Mongo https://projects.spring.io/spring-data-mongodb/[homepage]. You can help make Spring Data best serve the needs of the Spring community by interacting with developers through the Community on https://stackoverflow.com/questions/tagged/spring-data[Stack Overflow]. To follow developer activity, look for the mailing list information on the Spring Data Mongo https://projects.spring.io/spring-data-mongodb/[homepage]. If you encounter a bug or want to suggest an improvement, please create a ticket on the Spring Data https://github.com/spring-projects/spring-data-mongodb/issues[issue tracker]. To stay up to date with the latest news and announcements in the Spring eco system, subscribe to the Spring Community https://spring.io[Portal]. You can also follow the Spring https://spring.io/blog[blog] or the project team on Twitter (https://twitter.com/SpringData[SpringData]).
For information on the Spring Data Mongo source code repository, nightly builds, and snapshot artifacts, see the Spring Data Mongo https://spring.io/projects/spring-data-mongodb/[homepage]. You can help make Spring Data best serve the needs of the Spring community by interacting with developers through the Community on https://stackoverflow.com/questions/tagged/spring-data[Stack Overflow]. To follow developer activity, look for the mailing list information on the Spring Data Mongo https://spring.io/projects/spring-data-mongodb/[homepage]. If you encounter a bug or want to suggest an improvement, please create a ticket on the Spring Data https://github.com/spring-projects/spring-data-mongodb/issues[issue tracker]. To stay up to date with the latest news and announcements in the Spring eco system, subscribe to the Spring Community https://spring.io[Portal]. You can also follow the Spring https://spring.io/blog[blog] or the project team on Twitter (https://twitter.com/SpringData[SpringData]).

View File

@@ -302,10 +302,10 @@ The following example shows how to create and use transactions with a `ReactiveM
[source,java]
----
@Configuration
static class Config extends AbstractMongoClientConfiguration {
public class Config extends AbstractReactiveMongoConfiguration {
@Bean
ReactiveMongoTransactionManager transactionManager(ReactiveDatabaseFactory factory) { <1>
ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory factory) { <1>
return new ReactiveMongoTransactionManager(factory);
}

View File

@@ -162,7 +162,7 @@ calling `get()` before the actual conversion
| `URL`
| converter
| `{"website" : "https://projects.spring.io/spring-data-mongodb/" }`
| `{"website" : "https://spring.io/projects/spring-data-mongodb/" }`
| `Locale`
| converter

View File

@@ -252,7 +252,7 @@ static class Patient {
[TIP]
====
The `@Encrypted` Annoation supports resolving keyIds via SpEL Expressions.
The `@Encrypted` Annotation supports resolving keyIds via SpEL Expressions.
To do so additional environment metadata (via the `MappingContext`) is required and must be provided.
[source,java]

View File

@@ -4,12 +4,15 @@
[[mongo-repo-intro]]
== Introduction
This chapter points out the specialties for repository support for MongoDB. This chapter builds on the core repository support explained in <<repositories>>. You should have a sound understanding of the basic concepts explained there.
This chapter points out the specialties for repository support for MongoDB.
This chapter builds on the core repository support explained in <<repositories>>.
You should have a sound understanding of the basic concepts explained there.
[[mongo-repo-usage]]
== Usage
To access domain entities stored in a MongoDB, you can use our sophisticated repository support that eases implementation quite significantly.To do so, create an interface for your repository, as the following example shows:
To access domain entities stored in a MongoDB, you can use our sophisticated repository support that eases implementation quite significantly.
To do so, create an interface for your repository, as the following example shows:
.Sample Person entity
====
@@ -28,7 +31,8 @@ public class Person {
----
====
Note that the domain type shown in the preceding example has a property named `id` of type `String`.The default serialization mechanism used in `MongoTemplate` (which backs the repository support) regards properties named `id` as the document ID. Currently, we support `String`, `ObjectId`, and `BigInteger` as ID types.
Note that the domain type shown in the preceding example has a property named `id` of type `String`.The default serialization mechanism used in `MongoTemplate` (which backs the repository support) regards properties named `id` as the document ID.
Currently, we support `String`, `ObjectId`, and `BigInteger` as ID types.
Please see <<mongo-template.id-handling, ID mapping>> for more information about on how the `id` field is handled in the mapping layer.
Now that we have a domain object, we can define an interface that uses it, as follows:
@@ -44,12 +48,12 @@ public interface PersonRepository extends PagingAndSortingRepository<Person, Str
----
====
Right now this interface serves only to provide type information, but we can add additional methods to it later.
To start using the repository, use the `@EnableMongoRepositories` annotation.
That annotation carries the same attributes as the namespace element.If no base package is configured, the infrastructure scans the package of the annotated configuration class.The following example shows how to use Java configuration for a repository:
That annotation carries the same attributes as the namespace element.
If no base package is configured, the infrastructure scans the package of the annotated configuration class.
The following example shows how to use Java configuration for a repository:
.Java configuration for repositories
====
@@ -100,11 +104,12 @@ If you would rather go with XML based configuration add the following content:
----
====
This namespace element causes the base packages to be scanned for interfaces that extend `MongoRepository` and create Spring beans for each one found.By default, the repositories get a `MongoTemplate` Spring bean wired that is called `mongoTemplate`, so you only need to configure `mongo-template-ref` explicitly if you deviate from this convention.
This namespace element causes the base packages to be scanned for interfaces that extend `MongoRepository` and create Spring beans for each one found.
By default, the repositories get a `MongoTemplate` Spring bean wired that is called `mongoTemplate`, so you only need to configure `mongo-template-ref` explicitly if you deviate from this convention.
Because our domain repository extends `PagingAndSortingRepository`, it provides you with CRUD operations as well as methods for paginated and sorted access to the entities.Working with the repository instance is just a matter of dependency injecting it into a client.Consequently, accessing the second page of `Person` objects at a page size of 10 would resemble the following code:
Because our domain repository extends `PagingAndSortingRepository`, it provides you with CRUD operations as well as methods for paginated and sorted access to the entities.
Working with the repository instance is just a matter of dependency injecting it into a client .
Consequently, accessing the second page of `Person` objects at a page size of 10 would resemble the following code:
.Paging access to Person entities
====
@@ -126,12 +131,15 @@ public class PersonRepositoryTests {
----
====
The preceding example creates an application context with Spring's unit test support, which performs annotation-based dependency injection into test cases.Inside the test method, we use the repository to query the datastore.We hand the repository a `PageRequest` instance that requests the first page of `Person` objects at a page size of 10.
The preceding example creates an application context with Spring's unit test support, which performs annotation-based dependency injection into test cases.
Inside the test method, we use the repository to query the datastore.
We hand the repository a `PageRequest` instance that requests the first page of `Person` objects at a page size of 10.
[[mongodb.repositories.queries]]
== Query Methods
Most of the data access operations you usually trigger on a repository result in a query being executed against the MongoDB databases.Defining such a query is a matter of declaring a method on the repository interface, as the following example shows:
Most of the data access operations you usually trigger on a repository result in a query being executed against the MongoDB databases.
Defining such a query is a matter of declaring a method on the repository interface, as the following example shows:
.PersonRepository with query methods
====
@@ -150,10 +158,16 @@ public interface PersonRepository extends PagingAndSortingRepository<Person, Str
Stream<Person> findAllBy(); <5>
}
----
<1> The `findByLastname` method shows a query for all people with the given last name. The query is derived by parsing the method name for constraints that can be concatenated with `And` and `Or`. Thus, the method name results in a query expression of `{"lastname" : lastname}`.
<2> Applies pagination to a query. You can equip your method signature with a `Pageable` parameter and let the method return a `Page` instance and Spring Data automatically pages the query accordingly.
<3> Shows that you can query based on properties that are not primitive types. Throws `IncorrectResultSizeDataAccessException` if more than one match is found.
<4> Uses the `First` keyword to restrict the query to only the first result. Unlike <3>, this method does not throw an exception if more than one match is found.
<1> The `findByLastname` method shows a query for all people with the given last name.
The query is derived by parsing the method name for constraints that can be concatenated with `And` and `Or`.
Thus, the method name results in a query expression of `{"lastname" : lastname}`.
<2> Applies pagination to a query.
You can equip your method signature with a `Pageable` parameter and let the method return a `Page` instance and Spring Data automatically pages the query accordingly.
<3> Shows that you can query based on properties that are not primitive types.
Throws `IncorrectResultSizeDataAccessException` if more than one match is found.
<4> Uses the `First` keyword to restrict the query to only the first result.
Unlike <3>, this method does not throw an exception if more than one match is found.
<5> Uses a Java 8 `Stream` that reads and converts individual elements while iterating the stream.
====
@@ -161,7 +175,7 @@ NOTE: We do not support referring to parameters that are mapped as `DBRef` in th
The following table shows the keywords that are supported for query methods:
[cols="1,2,3", options="header"]
[cols="1,2,3",options="header"]
.Supported keywords for query methods
|===
| Keyword
@@ -310,6 +324,7 @@ public interface PersonRepository extends MongoRepository<Person, String> {
Optional<Person> deleteByBirthdate(Date birthdate); <4>
}
----
<1> Using a return type of `List` retrieves and returns all matching documents before actually deleting them.
<2> A numeric return type directly removes the matching documents, returning the total number of documents removed.
<3> A single domain type result retrieves and removes the first matching document.
@@ -319,7 +334,8 @@ public interface PersonRepository extends MongoRepository<Person, String> {
[[mongodb.repositories.queries.geo-spatial]]
=== Geo-spatial Repository Queries
As you saw in the preceding table of keywords, a few keywords trigger geo-spatial operations within a MongoDB query. The `Near` keyword allows some further modification, as the next few examples show.
As you saw in the preceding table of keywords, a few keywords trigger geo-spatial operations within a MongoDB query.
The `Near` keyword allows some further modification, as the next few examples show.
The following example shows how to define a `near` query that finds all persons with a given distance of a given point:
@@ -335,7 +351,8 @@ public interface PersonRepository extends MongoRepository<Person, String> {
----
====
Adding a `Distance` parameter to the query method allows restricting results to those within the given distance. If the `Distance` was set up containing a `Metric`, we transparently use `$nearSphere` instead of `$code`, as the following example shows:
Adding a `Distance` parameter to the query method allows restricting results to those within the given distance.
If the `Distance` was set up containing a `Metric`, we transparently use `$nearSphere` instead of `$code`, as the following example shows:
.Using `Distance` with `Metrics`
====
@@ -348,9 +365,12 @@ Distance distance = new Distance(200, Metrics.KILOMETERS);
----
====
Using a `Distance` with a `Metric` causes a `$nearSphere` (instead of a plain `$near`) clause to be added. Beyond that, the actual distance gets calculated according to the `Metrics` used.
Using a `Distance` with a `Metric` causes a `$nearSphere` (instead of a plain `$near`) clause to be added.
Beyond that, the actual distance gets calculated according to the `Metrics` used.
(Note that `Metric` does not refer to metric units of measure. It could be miles rather than kilometers. Rather, `metric` refers to the concept of a system of measurement, regardless of which system you use.)
(Note that `Metric` does not refer to metric units of measure.
It could be miles rather than kilometers.
Rather, `metric` refers to the concept of a system of measurement, regardless of which system you use.)
NOTE: Using `@GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)` on the target property forces usage of the `$nearSphere` operator.
@@ -411,12 +431,14 @@ public interface PersonRepository extends MongoRepository<Person, String> {
}
----
The query in the preceding example returns only the `firstname`, `lastname` and `Id` properties of the `Person` objects. The `age` property, a `java.lang.Integer`, is not set and its value is therefore null.
The query in the preceding example returns only the `firstname`, `lastname` and `Id` properties of the `Person` objects.
The `age` property, a `java.lang.Integer`, is not set and its value is therefore null.
[[mongodb.repositories.queries.sort]]
=== Sorting Query Method results
MongoDB repositories allow various approaches to define sorting order. Let's take a look at the following example:
MongoDB repositories allow various approaches to define sorting order.
Let's take a look at the following example:
.Sorting Query Results
====
@@ -435,11 +457,16 @@ public interface PersonRepository extends MongoRepository<Person, String> {
List<Person> findByLastname(String lastname, Sort sort); <4>
}
----
<1> Static sorting derived from method name. `SortByAgeDesc` results in `{ age : -1 }` for the sort parameter.
<2> Dynamic sorting using a method argument. `Sort.by(DESC, "age")` creates `{ age : -1 }` for the sort parameter.
<3> Static sorting via `Query` annotation. Sort parameter applied as stated in the `sort` attribute.
<2> Dynamic sorting using a method argument.
`Sort.by(DESC, "age")` creates `{ age : -1 }` for the sort parameter.
<3> Static sorting via `Query` annotation.
Sort parameter applied as stated in the `sort` attribute.
<4> Default sorting via `Query` annotation combined with dynamic one via a method argument. `Sort.unsorted()`
results in `{ age : -1 }`. Using `Sort.by(ASC, "age")` overrides the defaults and creates `{ age : 1 }`. `Sort.by
results in `{ age : -1 }`.
Using `Sort.by(ASC, "age")` overrides the defaults and creates `{ age : 1 }`.
`Sort.by
(ASC, "firstname")` alters the default and results in `{ age : -1, firstname : 1 }`.
====
@@ -449,7 +476,8 @@ results in `{ age : -1 }`. Using `Sort.by(ASC, "age")` overrides the defaults an
Query strings and field definitions can be used together with SpEL expressions to create dynamic queries at runtime.
SpEL expressions can provide predicate values and can be used to extend predicates with subdocuments.
Expressions expose method arguments through an array that contains all the arguments.The following query uses `[0]`
Expressions expose method arguments through an array that contains all the arguments.
The following query uses `[0]`
to declare the predicate value for `lastname` (which is equivalent to the `?0` parameter binding):
[source,java]
@@ -461,8 +489,8 @@ public interface PersonRepository extends MongoRepository<Person, String> {
}
----
Expressions can be used to invoke functions, evaluate conditionals, and construct values.SpEL expressions
used in conjunction with JSON reveal a side-effect, because Map-like declarations inside of SpEL read like JSON, as the following example shows:
Expressions can be used to invoke functions, evaluate conditionals, and construct values.
SpEL expressions used in conjunction with JSON reveal a side-effect, because Map-like declarations inside of SpEL read like JSON, as the following example shows:
[source,java]
----
@@ -473,12 +501,14 @@ public interface PersonRepository extends MongoRepository<Person, String> {
}
----
SpEL in query strings can be a powerful way to enhance queries.However, they can also accept a broad range of unwanted arguments.
You should make sure to sanitize strings before passing them to the query to avoid unwanted changes to your query.
WARNING: SpEL in query strings can be a powerful way to enhance queries.
However, they can also accept a broad range of unwanted arguments.
Make sure to sanitize strings before passing them to the query to avoid creation of vulnerabilities or unwanted changes to your query.
Expression support is extensible through the Query SPI: `org.springframework.data.repository.query.spi.EvaluationContextExtension`.
The Query SPI can contribute properties and functions and can customize the root object.Extensions are retrieved from the application context
at the time of SpEL evaluation when the query is built.The following example shows how to use `EvaluationContextExtension`:
The Query SPI can contribute properties and functions and can customize the root object.
Extensions are retrieved from the application context at the time of SpEL evaluation when the query is built.
The following example shows how to use `EvaluationContextExtension`:
[source,java]
----
@@ -525,7 +555,9 @@ Page<Person> page = repository.findAll(person.lastname.contains("a"),
PageRequest.of(0, 2, Direction.ASC, "lastname"));
----
`QPerson` is a class that is generated by the Java annotation post-processing tool.It is a `Predicate` that lets you write type-safe queries.Notice that there are no strings in the query other than the `C0123` value.
`QPerson` is a class that is generated by the Java annotation post-processing tool.
It is a `Predicate` that lets you write type-safe queries.
Notice that there are no strings in the query other than the `C0123` value.
You can use the generated `Predicate` class by using the `QuerydslPredicateExecutor` interface, which the following listing shows:
@@ -558,11 +590,16 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
[[mongodb.repositories.queries.full-text]]
=== Full-text Search Queries
MongoDB's full-text search feature is store-specific and, therefore, can be found on `MongoRepository` rather than on the more general `CrudRepository`. We need a document with a full-text index (see "`<<mapping-usage-indexes.text-index>>`" to learn how to create a full-text index).
MongoDB's full-text search feature is store-specific and, therefore, can be found on `MongoRepository` rather than on the more general `CrudRepository`.
We need a document with a full-text index (see "`<<mapping-usage-indexes.text-index>>`" to learn how to create a full-text index).
Additional methods on `MongoRepository` take `TextCriteria` as an input parameter. In addition to those explicit methods, it is also possible to add a `TextCriteria`-derived repository method. The criteria are added as an additional `AND` criteria. Once the entity contains a `@TextScore`-annotated property, the document's full-text score can be retrieved. Furthermore, the `@TextScore` annotated also makes it possible to sort by the document's score, as the following example shows:
Additional methods on `MongoRepository` take `TextCriteria` as an input parameter.
In addition to those explicit methods, it is also possible to add a `TextCriteria`-derived repository method.
The criteria are added as an additional `AND` criteria.
Once the entity contains a `@TextScore`-annotated property, the document's full-text score can be retrieved.
Furthermore, the `@TextScore` annotated also makes it possible to sort by the document's score, as the following example shows:
[source, java]
[source,java]
----
@Document
class FullTextDocument {
@@ -602,7 +639,11 @@ include::./mongo-repositories-aggregation.adoc[]
[[mongodb.repositories.misc.cdi-integration]]
== CDI Integration
Instances of the repository interfaces are usually created by a container, and Spring is the most natural choice when working with Spring Data. As of version 1.3.0, Spring Data MongoDB ships with a custom CDI extension that lets you use the repository abstraction in CDI environments. The extension is part of the JAR. To activate it, drop the Spring Data MongoDB JAR into your classpath. You can now set up the infrastructure by implementing a CDI Producer for the `MongoTemplate`, as the following example shows:
Instances of the repository interfaces are usually created by a container, and Spring is the most natural choice when working with Spring Data.
As of version 1.3.0, Spring Data MongoDB ships with a custom CDI extension that lets you use the repository abstraction in CDI environments.
The extension is part of the JAR.
To activate it, drop the Spring Data MongoDB JAR into your classpath.
You can now set up the infrastructure by implementing a CDI Producer for the `MongoTemplate`, as the following example shows:
[source,java]
----
@@ -618,7 +659,8 @@ class MongoTemplateProducer {
}
----
The Spring Data MongoDB CDI extension picks up the `MongoTemplate` available as a CDI bean and creates a proxy for a Spring Data repository whenever a bean of a repository type is requested by the container. Thus, obtaining an instance of a Spring Data repository is a matter of declaring an `@Inject`-ed property, as the following example shows:
The Spring Data MongoDB CDI extension picks up the `MongoTemplate` available as a CDI bean and creates a proxy for a Spring Data repository whenever a bean of a repository type is requested by the container.
Thus, obtaining an instance of a Spring Data repository is a matter of declaring an `@Inject`-ed property, as the following example shows:
[source,java]
----

View File

@@ -1,4 +1,4 @@
Spring Data MongoDB 3.3.2 (2021.1.2)
Spring Data MongoDB 3.3.10 (2021.1.10)
Copyright (c) [2010-2019] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -25,6 +25,14 @@ conditions of the subcomponent's license, as noted in the LICENSE file.