Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bca0ca015 | ||
|
|
80d63a576c | ||
|
|
0f6ee3ddbc | ||
|
|
c3a5f325d2 | ||
|
|
957397eff9 | ||
|
|
f322d5b18f | ||
|
|
24e423b8d1 | ||
|
|
4d5f3c66d5 | ||
|
|
f29d03f9c8 | ||
|
|
fbf4726e56 | ||
|
|
85382f0dd8 | ||
|
|
739b44f6e5 | ||
|
|
49cd518647 | ||
|
|
b59c7f774f | ||
|
|
b7ac5f7970 | ||
|
|
9af1689fbf | ||
|
|
51ca3be48f | ||
|
|
8f8e9c6585 | ||
|
|
092217e425 | ||
|
|
9d1e1b8c17 | ||
|
|
5cf73168f7 | ||
|
|
792d7199f0 | ||
|
|
34a2d09303 | ||
|
|
26554e3031 | ||
|
|
018fe623c0 | ||
|
|
27e6b5a9be | ||
|
|
c9be849e62 | ||
|
|
da5f24981c | ||
|
|
7c7b05f10d | ||
|
|
ed4f30ab07 | ||
|
|
cf38ba15bf | ||
|
|
daf12a6e2b | ||
|
|
d0481d089e | ||
|
|
169c35789d | ||
|
|
0de55deb03 | ||
|
|
01ac35fa31 | ||
|
|
f5c0318a14 | ||
|
|
7a0debe335 | ||
|
|
0a79ad6585 | ||
|
|
404ce6a987 | ||
|
|
232a9c9943 | ||
|
|
7c5ac764b3 | ||
|
|
864c94f490 | ||
|
|
ebc4678aa3 | ||
|
|
28d6e67686 | ||
|
|
ca229cdb99 | ||
|
|
611100e6f4 | ||
|
|
3a6d6bbfed | ||
|
|
286ff1c4a1 | ||
|
|
5df195db15 | ||
|
|
e437865707 | ||
|
|
13888ab7cd | ||
|
|
ced6a1b190 | ||
|
|
e704f147ad | ||
|
|
67ea27d9e4 | ||
|
|
a9ed00530f | ||
|
|
75f73756c9 | ||
|
|
4b137cfd55 | ||
|
|
762aa62b2a | ||
|
|
8f4a8dcbee | ||
|
|
0aa92031a3 | ||
|
|
8aa52c129c | ||
|
|
03ac725080 | ||
|
|
5258b36080 | ||
|
|
ddbec07643 | ||
|
|
f4375fc54d | ||
|
|
ccbd18ff6a | ||
|
|
490ef81d7b | ||
|
|
92668635b1 |
4
.mvn/wrapper/maven-wrapper.properties
vendored
4
.mvn/wrapper/maven-wrapper.properties
vendored
@@ -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
94
Jenkinsfile
vendored
@@ -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'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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/*
|
||||
|
||||
@@ -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/*
|
||||
|
||||
@@ -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/*
|
||||
|
||||
@@ -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/*
|
||||
|
||||
@@ -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/*
|
||||
|
||||
@@ -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
19
pom.xml
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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))));
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) //
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)) //
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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!");
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"));
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]).
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
----
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user