Compare commits
154 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af917b9465 | ||
|
|
ee545487b8 | ||
|
|
240e53794c | ||
|
|
7b6a06888d | ||
|
|
034a3528af | ||
|
|
ff28789507 | ||
|
|
cdfdeafdac | ||
|
|
16a35e0329 | ||
|
|
79f05c3d7f | ||
|
|
9217821472 | ||
|
|
8d223abd05 | ||
|
|
6a973b245f | ||
|
|
714b23e0ce | ||
|
|
d4a6614c11 | ||
|
|
82ce0abe1a | ||
|
|
dec7c125d6 | ||
|
|
db12c4ba5a | ||
|
|
5bbe481e98 | ||
|
|
fb39c31986 | ||
|
|
dd446472bc | ||
|
|
72d82d3083 | ||
|
|
cdfe2a0b59 | ||
|
|
5525a4fbf9 | ||
|
|
59464f3b3c | ||
|
|
052cfdfd45 | ||
|
|
b31c21bb91 | ||
|
|
5b6e5ca568 | ||
|
|
1a9136c0c1 | ||
|
|
59753bb55a | ||
|
|
8d963fc5da | ||
|
|
c1de745014 | ||
|
|
aa35aaeb70 | ||
|
|
a5725806f5 | ||
|
|
d715414683 | ||
|
|
f2c2451b7d | ||
|
|
5b8d0d08ee | ||
|
|
18186f26e2 | ||
|
|
10acc14c14 | ||
|
|
87effb9013 | ||
|
|
19819680f9 | ||
|
|
2d2f67cc93 | ||
|
|
e9818fe11a | ||
|
|
a63db5586c | ||
|
|
68ab74a5bf | ||
|
|
de33734118 | ||
|
|
c272c7317e | ||
|
|
d7fc605f7b | ||
|
|
3b805b9e03 | ||
|
|
91cca3f2c4 | ||
|
|
2de6384d0f | ||
|
|
ab1c0ff7b8 | ||
|
|
ae2846c5bf | ||
|
|
e88c9cf791 | ||
|
|
fadca10f62 | ||
|
|
40320136f3 | ||
|
|
bc575de3b0 | ||
|
|
09b2afa79d | ||
|
|
96b564eb9a | ||
|
|
38390d3475 | ||
|
|
6937bb519b | ||
|
|
6e4d463053 | ||
|
|
a9d2050806 | ||
|
|
6676389062 | ||
|
|
81f85b8cca | ||
|
|
77f318bd77 | ||
|
|
7c7e70418f | ||
|
|
44a1123034 | ||
|
|
e487c08b0c | ||
|
|
a002d30aa9 | ||
|
|
36ddd26edc | ||
|
|
6197655e98 | ||
|
|
929faea88b | ||
|
|
1fe1c13531 | ||
|
|
838ddb5d26 | ||
|
|
33c7f0980f | ||
|
|
4bbc443a0e | ||
|
|
655dbc9783 | ||
|
|
0d752fd6e6 | ||
|
|
8aabf2fa5e | ||
|
|
ff9d338bd7 | ||
|
|
2a4ee12363 | ||
|
|
a66438fc20 | ||
|
|
0ccc037b8e | ||
|
|
00792192c3 | ||
|
|
e064b505c9 | ||
|
|
7df2bdf8ff | ||
|
|
2f9fc1618e | ||
|
|
9e2aecf4ae | ||
|
|
c32c4beb59 | ||
|
|
d48f3ec535 | ||
|
|
5f16aecd13 | ||
|
|
5fc49b1649 | ||
|
|
1e7dc7ce66 | ||
|
|
234783f442 | ||
|
|
3429350964 | ||
|
|
d130984bdc | ||
|
|
f5378bf825 | ||
|
|
21057c3d17 | ||
|
|
d0a98eb71d | ||
|
|
bc95c4d390 | ||
|
|
d56a4ea77d | ||
|
|
5a09626cbf | ||
|
|
029291a1dd | ||
|
|
989a2596cb | ||
|
|
f5c520dbc8 | ||
|
|
80c843eb20 | ||
|
|
9b136537c0 | ||
|
|
d334c5a44c | ||
|
|
cfd55be95b | ||
|
|
079c5a95aa | ||
|
|
3f6821f11f | ||
|
|
1a868ae35e | ||
|
|
248bcfa177 | ||
|
|
ee076ec02f | ||
|
|
1184d6ee2d | ||
|
|
062b4e8757 | ||
|
|
30a417d810 | ||
|
|
1671f960b6 | ||
|
|
d4cce9ac00 | ||
|
|
8f9576aa42 | ||
|
|
f15fd2a418 | ||
|
|
01656db002 | ||
|
|
84faff6bd4 | ||
|
|
d72e1531d3 | ||
|
|
ac59cf930a | ||
|
|
7bdc8d3aac | ||
|
|
47548a21ea | ||
|
|
5aaa8f79e7 | ||
|
|
1a77b1bc56 | ||
|
|
140fb2e9ea | ||
|
|
b571c8958d | ||
|
|
8d54cae54d | ||
|
|
14a71f0498 | ||
|
|
14c265f3a1 | ||
|
|
440a289ac6 | ||
|
|
9663a2227b | ||
|
|
b134e1916d | ||
|
|
65b02f92b4 | ||
|
|
667b71e073 | ||
|
|
225dbee15f | ||
|
|
c04ceb163b | ||
|
|
711ac343fe | ||
|
|
852a4ecc59 | ||
|
|
7ab2428c64 | ||
|
|
350acf66bc | ||
|
|
ab94a94b2e | ||
|
|
4c77763cd3 | ||
|
|
f197953480 | ||
|
|
44afd4939e | ||
|
|
575917435e | ||
|
|
2db55ab0aa | ||
|
|
79602b7dbe | ||
|
|
d5d2371b9e | ||
|
|
c95e8a5748 |
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:32:40 CEST 2022
|
||||
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip
|
||||
|
||||
99
Jenkinsfile
vendored
99
Jenkinsfile
vendored
@@ -9,7 +9,7 @@ pipeline {
|
||||
|
||||
triggers {
|
||||
pollSCM 'H/10 * * * *'
|
||||
upstream(upstreamProjects: "spring-data-commons/3.0.x", threshold: hudson.model.Result.SUCCESS)
|
||||
upstream(upstreamProjects: "spring-data-commons/main", threshold: hudson.model.Result.SUCCESS)
|
||||
}
|
||||
|
||||
options {
|
||||
@@ -58,6 +58,25 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Publish JDK (Java 17) + MongoDB 6.0') {
|
||||
when {
|
||||
anyOf {
|
||||
changeset "ci/openjdk17-mongodb-6.0/**"
|
||||
changeset "ci/pipeline.properties"
|
||||
}
|
||||
}
|
||||
agent { label 'data' }
|
||||
options { timeout(time: 30, unit: 'MINUTES') }
|
||||
|
||||
steps {
|
||||
script {
|
||||
def image = docker.build("springci/spring-data-with-mongodb-6.0:${p['java.main.tag']}", "--build-arg BASE=${p['docker.java.main.image']} --build-arg MONGODB=${p['docker.mongodb.6.0.version']} ci/openjdk17-mongodb-6.0/")
|
||||
docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
|
||||
image.push()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,15 +97,13 @@ pipeline {
|
||||
}
|
||||
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'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,7 +119,7 @@ pipeline {
|
||||
}
|
||||
parallel {
|
||||
|
||||
stage("test: mongodb 5.0 (Java 17)") {
|
||||
stage("test: MongoDB 5.0 (Java 17)") {
|
||||
agent {
|
||||
label 'data'
|
||||
}
|
||||
@@ -112,15 +129,35 @@ pipeline {
|
||||
}
|
||||
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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage("test: MongoDB 6.0 (Java 17)") {
|
||||
agent {
|
||||
label 'data'
|
||||
}
|
||||
options { timeout(time: 30, unit: 'MINUTES') }
|
||||
environment {
|
||||
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
docker.image("harbor-repo.vmware.com/dockerhub-proxy-cache/springci/spring-data-with-mongodb-6.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 'mongosh --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'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,18 +184,16 @@ pipeline {
|
||||
|
||||
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 -v'
|
||||
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 -v'
|
||||
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'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
README.adoc
14
README.adoc
@@ -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:
|
||||
@@ -277,12 +277,12 @@ and accessible from Maven using the Maven configuration noted <<maven-configurat
|
||||
NOTE: Configuration for Gradle is similar to Maven.
|
||||
|
||||
The best way to get started is by creating a Spring Boot project using MongoDB on https://start.spring.io[start.spring.io].
|
||||
Follow this https://start.spring.io/#type=maven-project&language=java&platformVersion=2.5.4&packaging=jar&jvmVersion=1.8&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=data-mongodb[link]
|
||||
to build an imperative application and this https://start.spring.io/#type=maven-project&language=java&platformVersion=2.5.4&packaging=jar&jvmVersion=1.8&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=data-mongodb-reactive[link]
|
||||
Follow this https://start.spring.io/#type=maven-project&language=java&platformVersion=3.0.0&packaging=jar&jvmVersion=17&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=data-mongodb[link]
|
||||
to build an imperative application and this https://start.spring.io/#type=maven-project&language=java&platformVersion=3.0.0&packaging=jar&jvmVersion=17&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=data-mongodb-reactive[link]
|
||||
to build a reactive one.
|
||||
|
||||
However, if you want to try out the latest and greatest, Spring Data MongoDB can be easily built with the https://github.com/takari/maven-wrapper[Maven wrapper]
|
||||
and minimally, JDK 8 (https://www.oracle.com/java/technologies/downloads/[JDK downloads]).
|
||||
and minimally, JDK 17 (https://www.oracle.com/java/technologies/downloads/[JDK downloads]).
|
||||
|
||||
In order to build Spring Data MongoDB, you will need to https://www.mongodb.com/try/download/community[download]
|
||||
and https://docs.mongodb.com/manual/installation/[install a MongoDB distribution].
|
||||
@@ -341,7 +341,7 @@ Now you are ready to build Spring Data MongoDB. Simply enter the following `mvnw
|
||||
$ ./mvnw clean install
|
||||
----
|
||||
|
||||
If you want to build with the regular `mvn` command, you will need https://maven.apache.org/run-maven/index.html[Maven v3.5.0 or above].
|
||||
If you want to build with the regular `mvn` command, you will need https://maven.apache.org/run-maven/index.html[Maven v3.8.0 or above].
|
||||
|
||||
_Also see link:CONTRIBUTING.adoc[CONTRIBUTING.adoc] if you wish to submit pull requests, and in particular, please sign
|
||||
the https://cla.pivotal.io/sign/spring[Contributor’s Agreement] before your first non-trivial change._
|
||||
|
||||
@@ -7,15 +7,15 @@ 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/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
|
||||
|
||||
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,17 @@ 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/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 ] 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
|
||||
|
||||
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/*
|
||||
|
||||
23
ci/openjdk17-mongodb-6.0/Dockerfile
Normal file
23
ci/openjdk17-mongodb-6.0/Dockerfile
Normal file
@@ -0,0 +1,23 @@
|
||||
ARG BASE
|
||||
FROM ${BASE}
|
||||
# Any ARG statements before FROM are cleared.
|
||||
ARG MONGODB
|
||||
|
||||
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 && \
|
||||
# MongoDB 6.0 release signing key
|
||||
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | apt-key add - && \
|
||||
# Needed when MongoDB creates a 6.0 folder.
|
||||
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/6.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-6.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/*
|
||||
@@ -7,6 +7,7 @@ docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/ecli
|
||||
# Supported versions of MongoDB
|
||||
docker.mongodb.4.4.version=4.4.12
|
||||
docker.mongodb.5.0.version=5.0.6
|
||||
docker.mongodb.6.0.version=6.0.0
|
||||
|
||||
# Supported versions of Redis
|
||||
docker.redis.6.version=6.2.6
|
||||
|
||||
25
pom.xml
25
pom.xml
@@ -5,17 +5,17 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>4.0.0-M2</version>
|
||||
<version>4.0.0-RC1</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>3.0.0-M2</version>
|
||||
<version>3.0.0-RC1</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
@@ -24,11 +24,10 @@
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<source.level>16</source.level>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>3.0.0-M2</springdata.commons>
|
||||
<mongo>4.5.0</mongo>
|
||||
<springdata.commons>3.0.0-RC1</springdata.commons>
|
||||
<mongo>4.8.0-beta0</mongo>
|
||||
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
|
||||
<jmh.version>1.19</jmh.version>
|
||||
</properties>
|
||||
@@ -113,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>
|
||||
@@ -137,6 +147,9 @@
|
||||
<repository>
|
||||
<id>spring-libs-milestone</id>
|
||||
<url>https://repo.spring.io/libs-milestone</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonatype-libs-snapshot</id>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>4.0.0-M2</version>
|
||||
<version>4.0.0-RC1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -322,7 +322,7 @@ public class AbstractMicrobenchmark {
|
||||
try {
|
||||
ResultsWriter.forUri(uri).write(results);
|
||||
} catch (Exception e) {
|
||||
System.err.println(String.format("Cannot save benchmark results to '%s'. Error was %s.", uri, e));
|
||||
System.err.println(String.format("Cannot save benchmark results to '%s'; Error was %s", uri, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,13 +15,18 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>4.0.0-M2</version>
|
||||
<version>4.0.0-RC1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.root>${basedir}/..</project.root>
|
||||
<dist.key>SDMONGO</dist.key>
|
||||
|
||||
<!-- Observability -->
|
||||
<micrometer-docs-generator.inputPath>${maven.multiModuleProjectDirectory}/spring-data-mongodb/</micrometer-docs-generator.inputPath>
|
||||
<micrometer-docs-generator.inclusionPattern>.*</micrometer-docs-generator.inclusionPattern>
|
||||
<micrometer-docs-generator.outputPath>${maven.multiModuleProjectDirectory}/target/</micrometer-docs-generator.outputPath>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -29,12 +35,63 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-metrics-metadata</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<mainClass>io.micrometer.docs.metrics.DocsFromSources
|
||||
</mainClass>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>generate-tracing-metadata</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<mainClass>io.micrometer.docs.spans.DocsFromSources
|
||||
</mainClass>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-docs-generator-spans</artifactId>
|
||||
<version>${micrometer-docs-generator}</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-docs-generator-metrics</artifactId>
|
||||
<version>${micrometer-docs-generator}</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<includePluginDependencies>true</includePluginDependencies>
|
||||
<arguments>
|
||||
<argument>${micrometer-docs-generator.inputPath}</argument>
|
||||
<argument>${micrometer-docs-generator.inclusionPattern}</argument>
|
||||
<argument>${micrometer-docs-generator.outputPath}</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<attributes>
|
||||
<mongo-reactivestreams>${mongo.reactivestreams}</mongo-reactivestreams>
|
||||
<mongo-reactivestreams>${mongo.reactivestreams}
|
||||
</mongo-reactivestreams>
|
||||
<reactor>${reactor}</reactor>
|
||||
</attributes>
|
||||
</configuration>
|
||||
@@ -43,4 +100,15 @@
|
||||
|
||||
</build>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-release</id>
|
||||
<url>https://repo.spring.io/plugins-release</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-snapshot</id>
|
||||
<url>https://repo.spring.io/libs-snapshot</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -11,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>4.0.0-M2</version>
|
||||
<version>4.0.0-RC1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -194,7 +196,19 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-observation</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>7.0.1.Final</version>
|
||||
<scope>test</scope>
|
||||
@@ -290,11 +304,34 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>io.mockk</groupId>
|
||||
<artifactId>mockk</artifactId>
|
||||
<artifactId>mockk-jvm</artifactId>
|
||||
<version>${mockk}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock-jre8-standalone</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing-integration-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- jMolecules -->
|
||||
|
||||
<dependency>
|
||||
@@ -328,8 +365,11 @@
|
||||
<goal>test-process</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target/generated-test-sources</outputDirectory>
|
||||
<processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
|
||||
<outputDirectory>target/generated-test-sources
|
||||
</outputDirectory>
|
||||
<processor>
|
||||
org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor
|
||||
</processor>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@@ -349,7 +389,9 @@
|
||||
<exclude>**/ReactivePerformanceTests.java</exclude>
|
||||
</excludes>
|
||||
<systemPropertyVariables>
|
||||
<java.util.logging.config.file>src/test/resources/logging.properties</java.util.logging.config.file>
|
||||
<java.util.logging.config.file>
|
||||
src/test/resources/logging.properties
|
||||
</java.util.logging.config.file>
|
||||
<reactor.trace.cancel>true</reactor.trace.cancel>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
|
||||
@@ -62,7 +62,7 @@ public interface CodecRegistryProvider {
|
||||
*/
|
||||
default <T> Optional<Codec<T>> getCodecFor(Class<T> type) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
Assert.notNull(type, "Type must not be null");
|
||||
|
||||
try {
|
||||
return Optional.of(getCodecRegistry().get(type));
|
||||
|
||||
@@ -102,7 +102,7 @@ public class MongoDatabaseUtils {
|
||||
private static MongoDatabase doGetMongoDatabase(@Nullable String dbName, MongoDatabaseFactory factory,
|
||||
SessionSynchronization sessionSynchronization) {
|
||||
|
||||
Assert.notNull(factory, "Factory must not be null!");
|
||||
Assert.notNull(factory, "Factory must not be null");
|
||||
|
||||
if (sessionSynchronization == SessionSynchronization.NEVER
|
||||
|| !TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.data.domain.ManagedTypes;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class MongoManagedTypes implements ManagedTypes {
|
||||
|
||||
private final ManagedTypes delegate;
|
||||
|
||||
private MongoManagedTypes(ManagedTypes types) {
|
||||
this.delegate = types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an existing {@link ManagedTypes} object with {@link MongoManagedTypes}.
|
||||
*
|
||||
* @param managedTypes
|
||||
* @return
|
||||
*/
|
||||
public static MongoManagedTypes from(ManagedTypes managedTypes) {
|
||||
return new MongoManagedTypes(managedTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method used to construct {@link MongoManagedTypes} from the given array of {@link Class types}.
|
||||
*
|
||||
* @param types array of {@link Class types} used to initialize the {@link ManagedTypes}; must not be {@literal null}.
|
||||
* @return new instance of {@link MongoManagedTypes} initialized from {@link Class types}.
|
||||
*/
|
||||
public static MongoManagedTypes from(Class<?>... types) {
|
||||
return fromIterable(Arrays.asList(types));
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method used to construct {@link MongoManagedTypes} from the given, required {@link Iterable} of
|
||||
* {@link Class types}.
|
||||
*
|
||||
* @param types {@link Iterable} of {@link Class types} used to initialize the {@link ManagedTypes}; must not be
|
||||
* {@literal null}.
|
||||
* @return new instance of {@link MongoManagedTypes} initialized the given, required {@link Iterable} of {@link Class
|
||||
* types}.
|
||||
*/
|
||||
public static MongoManagedTypes fromIterable(Iterable<? extends Class<?>> types) {
|
||||
return from(ManagedTypes.fromIterable(types));
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to return an empty {@link MongoManagedTypes} object.
|
||||
*
|
||||
* @return an empty {@link MongoManagedTypes} object.
|
||||
*/
|
||||
public static MongoManagedTypes empty() {
|
||||
return from(ManagedTypes.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<Class<?>> action) {
|
||||
delegate.forEach(action);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ class MongoResourceHolder extends ResourceHolderSupport {
|
||||
ClientSession session = getSession();
|
||||
|
||||
if (session == null) {
|
||||
throw new IllegalStateException("No session available!");
|
||||
throw new IllegalStateException("No session available");
|
||||
}
|
||||
|
||||
return session;
|
||||
|
||||
@@ -100,7 +100,7 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
||||
*/
|
||||
public MongoTransactionManager(MongoDatabaseFactory dbFactory, @Nullable TransactionOptions options) {
|
||||
|
||||
Assert.notNull(dbFactory, "DbFactory must not be null!");
|
||||
Assert.notNull(dbFactory, "DbFactory must not be null");
|
||||
|
||||
this.dbFactory = dbFactory;
|
||||
this.options = options;
|
||||
@@ -266,7 +266,7 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
||||
*/
|
||||
public void setDbFactory(MongoDatabaseFactory dbFactory) {
|
||||
|
||||
Assert.notNull(dbFactory, "DbFactory must not be null!");
|
||||
Assert.notNull(dbFactory, "DbFactory must not be null");
|
||||
this.dbFactory = dbFactory;
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
||||
private MongoDatabaseFactory getRequiredDbFactory() {
|
||||
|
||||
Assert.state(dbFactory != null,
|
||||
"MongoTransactionManager operates upon a MongoDbFactory. Did you forget to provide one? It's required.");
|
||||
"MongoTransactionManager operates upon a MongoDbFactory; Did you forget to provide one; It's required");
|
||||
|
||||
return dbFactory;
|
||||
}
|
||||
@@ -450,14 +450,14 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
||||
|
||||
private MongoResourceHolder getRequiredResourceHolder() {
|
||||
|
||||
Assert.state(resourceHolder != null, "MongoResourceHolder is required but not present. o_O");
|
||||
Assert.state(resourceHolder != null, "MongoResourceHolder is required but not present; o_O");
|
||||
return resourceHolder;
|
||||
}
|
||||
|
||||
private ClientSession getRequiredSession() {
|
||||
|
||||
ClientSession session = getSession();
|
||||
Assert.state(session != null, "A Session is required but it turned out to be null.");
|
||||
Assert.state(session != null, "A Session is required but it turned out to be null");
|
||||
return session;
|
||||
}
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ public class ReactiveMongoDatabaseUtils {
|
||||
private static Mono<MongoDatabase> doGetMongoDatabase(@Nullable String dbName, ReactiveMongoDatabaseFactory factory,
|
||||
SessionSynchronization sessionSynchronization) {
|
||||
|
||||
Assert.notNull(factory, "DatabaseFactory must not be null!");
|
||||
Assert.notNull(factory, "DatabaseFactory must not be null");
|
||||
|
||||
if (sessionSynchronization == SessionSynchronization.NEVER) {
|
||||
return getMongoDatabaseOrDefault(dbName, factory);
|
||||
|
||||
@@ -104,7 +104,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
||||
public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFactory,
|
||||
@Nullable TransactionOptions options) {
|
||||
|
||||
Assert.notNull(databaseFactory, "DatabaseFactory must not be null!");
|
||||
Assert.notNull(databaseFactory, "DatabaseFactory must not be null");
|
||||
|
||||
this.databaseFactory = databaseFactory;
|
||||
this.options = options;
|
||||
@@ -281,7 +281,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
||||
*/
|
||||
public void setDatabaseFactory(ReactiveMongoDatabaseFactory databaseFactory) {
|
||||
|
||||
Assert.notNull(databaseFactory, "DatabaseFactory must not be null!");
|
||||
Assert.notNull(databaseFactory, "DatabaseFactory must not be null");
|
||||
this.databaseFactory = databaseFactory;
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
||||
private ReactiveMongoDatabaseFactory getRequiredDatabaseFactory() {
|
||||
|
||||
Assert.state(databaseFactory != null,
|
||||
"ReactiveMongoTransactionManager operates upon a ReactiveMongoDatabaseFactory. Did you forget to provide one? It's required.");
|
||||
"ReactiveMongoTransactionManager operates upon a ReactiveMongoDatabaseFactory; Did you forget to provide one; It's required");
|
||||
|
||||
return databaseFactory;
|
||||
}
|
||||
@@ -458,14 +458,14 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
||||
|
||||
private ReactiveMongoResourceHolder getRequiredResourceHolder() {
|
||||
|
||||
Assert.state(resourceHolder != null, "ReactiveMongoResourceHolder is required but not present. o_O");
|
||||
Assert.state(resourceHolder != null, "ReactiveMongoResourceHolder is required but not present; o_O");
|
||||
return resourceHolder;
|
||||
}
|
||||
|
||||
private ClientSession getRequiredSession() {
|
||||
|
||||
ClientSession session = getSession();
|
||||
Assert.state(session != null, "A Session is required but it turned out to be null.");
|
||||
Assert.state(session != null, "A Session is required but it turned out to be null");
|
||||
return session;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,13 +76,13 @@ public class SessionAwareMethodInterceptor<D, C> implements MethodInterceptor {
|
||||
Class<D> databaseType, ClientSessionOperator<D> databaseDecorator, Class<C> collectionType,
|
||||
ClientSessionOperator<C> collectionDecorator) {
|
||||
|
||||
Assert.notNull(session, "ClientSession must not be null!");
|
||||
Assert.notNull(target, "Target must not be null!");
|
||||
Assert.notNull(sessionType, "SessionType must not be null!");
|
||||
Assert.notNull(databaseType, "Database type must not be null!");
|
||||
Assert.notNull(databaseDecorator, "Database ClientSessionOperator must not be null!");
|
||||
Assert.notNull(collectionType, "Collection type must not be null!");
|
||||
Assert.notNull(collectionDecorator, "Collection ClientSessionOperator must not be null!");
|
||||
Assert.notNull(session, "ClientSession must not be null");
|
||||
Assert.notNull(target, "Target must not be null");
|
||||
Assert.notNull(sessionType, "SessionType must not be null");
|
||||
Assert.notNull(databaseType, "Database type must not be null");
|
||||
Assert.notNull(databaseDecorator, "Database ClientSessionOperator must not be null");
|
||||
Assert.notNull(collectionType, "Collection type must not be null");
|
||||
Assert.notNull(collectionDecorator, "Collection ClientSessionOperator must not be null");
|
||||
|
||||
this.session = session;
|
||||
this.target = target;
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.aot;
|
||||
|
||||
import org.springframework.aot.generate.GenerationContext;
|
||||
import org.springframework.data.aot.TypeContributor;
|
||||
import org.springframework.data.repository.aot.AotRepositoryContext;
|
||||
import org.springframework.data.repository.aot.RepositoryRegistrationAotProcessor;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class AotMongoRepositoryPostProcessor extends RepositoryRegistrationAotProcessor {
|
||||
|
||||
private final LazyLoadingProxyAotProcessor lazyLoadingProxyAotProcessor = new LazyLoadingProxyAotProcessor();
|
||||
|
||||
@Override
|
||||
protected void contribute(AotRepositoryContext repositoryContext, GenerationContext generationContext) {
|
||||
// do some custom type registration here
|
||||
super.contribute(repositoryContext, generationContext);
|
||||
|
||||
repositoryContext.getResolvedTypes().stream().filter(MongoAotPredicates.IS_SIMPLE_TYPE.negate()).forEach(type -> {
|
||||
TypeContributor.contribute(type, it -> true, generationContext);
|
||||
lazyLoadingProxyAotProcessor.registerLazyLoadingProxyIfNeeded(type, generationContext);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.aot;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.aot.generate.GenerationContext;
|
||||
import org.springframework.aot.hint.TypeReference;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.data.annotation.Reference;
|
||||
import org.springframework.data.aot.TypeUtils;
|
||||
import org.springframework.data.mongodb.core.convert.LazyLoadingProxyFactory;
|
||||
import org.springframework.data.mongodb.core.convert.LazyLoadingProxyFactory.LazyLoadingInterceptor;
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
import org.springframework.data.mongodb.core.mapping.DocumentReference;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 4.0
|
||||
*/
|
||||
class LazyLoadingProxyAotProcessor {
|
||||
|
||||
private boolean generalLazyLoadingProxyContributed = false;
|
||||
|
||||
void registerLazyLoadingProxyIfNeeded(Class<?> type, GenerationContext generationContext) {
|
||||
|
||||
Set<Field> refFields = getFieldsWithAnnotationPresent(type, Reference.class);
|
||||
if (refFields.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
refFields.stream() //
|
||||
.filter(LazyLoadingProxyAotProcessor::isLazyLoading) //
|
||||
.forEach(field -> {
|
||||
|
||||
if (!generalLazyLoadingProxyContributed) {
|
||||
generationContext.getRuntimeHints().proxies().registerJdkProxy(
|
||||
TypeReference.of(org.springframework.data.mongodb.core.convert.LazyLoadingProxy.class),
|
||||
TypeReference.of(org.springframework.aop.SpringProxy.class),
|
||||
TypeReference.of(org.springframework.aop.framework.Advised.class),
|
||||
TypeReference.of(org.springframework.core.DecoratingProxy.class));
|
||||
generalLazyLoadingProxyContributed = true;
|
||||
}
|
||||
|
||||
if (field.getType().isInterface()) {
|
||||
|
||||
List<Class<?>> interfaces = new ArrayList<>(
|
||||
TypeUtils.resolveTypesInSignature(ResolvableType.forField(field, type)));
|
||||
|
||||
interfaces.add(0, org.springframework.data.mongodb.core.convert.LazyLoadingProxy.class);
|
||||
interfaces.add(org.springframework.aop.SpringProxy.class);
|
||||
interfaces.add(org.springframework.aop.framework.Advised.class);
|
||||
interfaces.add(org.springframework.core.DecoratingProxy.class);
|
||||
|
||||
generationContext.getRuntimeHints().proxies().registerJdkProxy(interfaces.toArray(Class[]::new));
|
||||
} else {
|
||||
LazyLoadingProxyFactory.resolveProxyType(field.getType(), () -> LazyLoadingInterceptor.none());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isLazyLoading(Field field) {
|
||||
if (AnnotatedElementUtils.isAnnotated(field, DBRef.class)) {
|
||||
return AnnotatedElementUtils.findMergedAnnotation(field, DBRef.class).lazy();
|
||||
}
|
||||
if (AnnotatedElementUtils.isAnnotated(field, DocumentReference.class)) {
|
||||
return AnnotatedElementUtils.findMergedAnnotation(field, DocumentReference.class).lazy();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Set<Field> getFieldsWithAnnotationPresent(Class<?> type, Class<? extends Annotation> annotation) {
|
||||
|
||||
Set<Field> fields = new LinkedHashSet<>();
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
if (MergedAnnotations.from(field).get(annotation).isPresent()) {
|
||||
fields.add(field);
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.aot;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.data.aot.TypeUtils;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 4.0
|
||||
*/
|
||||
class MongoAotPredicates {
|
||||
|
||||
static final Predicate<Class<?>> IS_SIMPLE_TYPE = (type) -> MongoSimpleTypes.HOLDER.isSimpleType(type) || TypeUtils.type(type).isPartOf("org.bson");
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.aot;
|
||||
|
||||
import org.springframework.aot.generate.GenerationContext;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.data.aot.ManagedTypesBeanRegistrationAotProcessor;
|
||||
import org.springframework.data.mongodb.MongoManagedTypes;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 2022/06
|
||||
*/
|
||||
class MongoManagedTypesBeanRegistrationAotProcessor extends ManagedTypesBeanRegistrationAotProcessor {
|
||||
|
||||
private final LazyLoadingProxyAotProcessor lazyLoadingProxyAotProcessor = new LazyLoadingProxyAotProcessor();
|
||||
|
||||
public MongoManagedTypesBeanRegistrationAotProcessor() {
|
||||
setModuleIdentifier("mongo");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMatch(@Nullable Class<?> beanType, @Nullable String beanName) {
|
||||
return isMongoManagedTypes(beanType) || super.isMatch(beanType, beanName);
|
||||
}
|
||||
|
||||
protected boolean isMongoManagedTypes(@Nullable Class<?> beanType) {
|
||||
return beanType != null && ClassUtils.isAssignable(MongoManagedTypes.class, beanType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void contributeType(ResolvableType type, GenerationContext generationContext) {
|
||||
|
||||
if (MongoAotPredicates.IS_SIMPLE_TYPE.test(type.toClass())) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.contributeType(type, generationContext);
|
||||
lazyLoadingProxyAotProcessor.registerLazyLoadingProxyIfNeeded(type.toClass(), generationContext);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.aot;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.aot.hint.MemberCategory;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.aot.hint.TypeReference;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterConvertCallback;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterSaveCallback;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertCallback;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeSaveCallback;
|
||||
import org.springframework.data.mongodb.core.mapping.event.ReactiveAfterConvertCallback;
|
||||
import org.springframework.data.mongodb.core.mapping.event.ReactiveAfterSaveCallback;
|
||||
import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeConvertCallback;
|
||||
import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeSaveCallback;
|
||||
import org.springframework.data.repository.util.ReactiveWrappers;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* {@link RuntimeHintsRegistrar} for repository types and entity callbacks.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 4.0
|
||||
*/
|
||||
class MongoRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
private static final boolean PROJECT_REACTOR_PRESENT = ReactiveWrappers
|
||||
.isAvailable(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR);
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
|
||||
|
||||
hints.reflection().registerTypes(
|
||||
Arrays.asList(TypeReference.of("org.springframework.data.mongodb.repository.support.SimpleMongoRepository"),
|
||||
TypeReference.of(BeforeConvertCallback.class), TypeReference.of(BeforeSaveCallback.class),
|
||||
TypeReference.of(AfterConvertCallback.class), TypeReference.of(AfterSaveCallback.class)),
|
||||
builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_PUBLIC_METHODS));
|
||||
|
||||
if (PROJECT_REACTOR_PRESENT) {
|
||||
|
||||
hints.reflection()
|
||||
.registerTypes(Arrays.asList(
|
||||
TypeReference.of("org.springframework.data.mongodb.repository.support.SimpleReactiveMongoRepository"),
|
||||
TypeReference.of(ReactiveBeforeConvertCallback.class), TypeReference.of(ReactiveBeforeSaveCallback.class),
|
||||
TypeReference.of(ReactiveAfterConvertCallback.class), TypeReference.of(ReactiveAfterSaveCallback.class)),
|
||||
builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
|
||||
MemberCategory.INVOKE_PUBLIC_METHODS));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,10 +80,10 @@ public abstract class AbstractMongoClientConfiguration extends MongoConfiguratio
|
||||
|
||||
/**
|
||||
* Creates a {@link MappingMongoConverter} using the configured {@link #mongoDbFactory()} and
|
||||
* {@link #mongoMappingContext(MongoCustomConversions)}. Will get {@link #customConversions()} applied.
|
||||
* {@link #mongoMappingContext(MongoCustomConversions, org.springframework.data.mongodb.MongoManagedTypes)}. Will get {@link #customConversions()} applied.
|
||||
*
|
||||
* @see #customConversions()
|
||||
* @see #mongoMappingContext(MongoCustomConversions)
|
||||
* @see #mongoMappingContext(MongoCustomConversions, org.springframework.data.mongodb.MongoManagedTypes)
|
||||
* @see #mongoDbFactory()
|
||||
*/
|
||||
@Bean
|
||||
|
||||
@@ -84,10 +84,10 @@ public abstract class AbstractReactiveMongoConfiguration extends MongoConfigurat
|
||||
|
||||
/**
|
||||
* Creates a {@link MappingMongoConverter} using the configured {@link #reactiveMongoDbFactory()} and
|
||||
* {@link #mongoMappingContext(MongoCustomConversions)}. Will get {@link #customConversions()} applied.
|
||||
* {@link #mongoMappingContext(MongoCustomConversions, org.springframework.data.mongodb.MongoManagedTypes)}. Will get {@link #customConversions()} applied.
|
||||
*
|
||||
* @see #customConversions()
|
||||
* @see #mongoMappingContext(MongoCustomConversions)
|
||||
* @see #mongoMappingContext(MongoCustomConversions, org.springframework.data.mongodb.MongoManagedTypes)
|
||||
* @see #reactiveMongoDbFactory()
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -255,7 +253,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
&& Boolean.parseBoolean(abbreviateFieldNames);
|
||||
|
||||
if (fieldNamingStrategyReferenced && abbreviationActivated) {
|
||||
context.error("Field name abbreviation cannot be activated if a field-naming-strategy-ref is configured!",
|
||||
context.error("Field name abbreviation cannot be activated if a field-naming-strategy-ref is configured",
|
||||
element);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -18,18 +18,14 @@ package org.springframework.data.mongodb.config;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
|
||||
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
|
||||
import org.springframework.data.auditing.config.AuditingConfiguration;
|
||||
import org.springframework.data.config.ParsingUtils;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -39,8 +35,9 @@ import org.springframework.util.Assert;
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
||||
class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport implements Ordered {
|
||||
|
||||
@Override
|
||||
protected Class<? extends Annotation> getAnnotation() {
|
||||
@@ -53,34 +50,27 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
|
||||
protected void postProcess(BeanDefinitionBuilder builder, AuditingConfiguration configuration,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
Assert.notNull(annotationMetadata, "AnnotationMetadata must not be null!");
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
|
||||
|
||||
super.registerBeanDefinitions(annotationMetadata, registry);
|
||||
builder.setFactoryMethod("from").addConstructorArgReference("mongoMappingContext");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
|
||||
|
||||
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
|
||||
Assert.notNull(configuration, "AuditingConfiguration must not be null");
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
|
||||
|
||||
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(org.springframework.data.repository.config.PersistentEntitiesFactoryBean.class);
|
||||
definition.addConstructorArgValue(new RuntimeBeanReference(MappingContext.class));
|
||||
|
||||
builder.addConstructorArgValue(definition.getBeanDefinition());
|
||||
return configureDefaultAuditHandlerAttributes(configuration, builder);
|
||||
return configureDefaultAuditHandlerAttributes(configuration,
|
||||
BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!");
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
|
||||
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null");
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||
|
||||
BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(AuditingEntityCallback.class);
|
||||
@@ -91,4 +81,8 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
||||
AuditingEntityCallback.class.getName(), registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.data.convert.CustomConversions;
|
||||
import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy;
|
||||
import org.springframework.data.mapping.model.FieldNamingStrategy;
|
||||
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
|
||||
import org.springframework.data.mongodb.MongoManagedTypes;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
@@ -76,14 +77,13 @@ public abstract class MongoConfigurationSupport {
|
||||
*
|
||||
* @see #getMappingBasePackages()
|
||||
* @return
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
@Bean
|
||||
public MongoMappingContext mongoMappingContext(MongoCustomConversions customConversions)
|
||||
throws ClassNotFoundException {
|
||||
public MongoMappingContext mongoMappingContext(MongoCustomConversions customConversions,
|
||||
MongoManagedTypes mongoManagedTypes) {
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(getInitialEntitySet());
|
||||
mappingContext.setManagedTypes(mongoManagedTypes);
|
||||
mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
|
||||
mappingContext.setFieldNamingStrategy(fieldNamingStrategy());
|
||||
mappingContext.setAutoIndexCreation(autoIndexCreation());
|
||||
@@ -91,6 +91,16 @@ public abstract class MongoConfigurationSupport {
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return new instance of {@link MongoManagedTypes}.
|
||||
* @throws ClassNotFoundException
|
||||
* @since 4.0
|
||||
*/
|
||||
@Bean
|
||||
public MongoManagedTypes mongoManagedTypes() throws ClassNotFoundException {
|
||||
return MongoManagedTypes.fromIterable(getInitialEntitySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register custom {@link Converter}s in a {@link CustomConversions} object if required. These
|
||||
* {@link CustomConversions} will be registered with the
|
||||
|
||||
@@ -117,7 +117,7 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
|
||||
userNameAndPassword[1].toCharArray()));
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Cannot create MongoCredentials for unknown auth mechanism '%s'!", authMechanism));
|
||||
String.format("Cannot create MongoCredentials for unknown auth mechanism '%s'", authMechanism));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -194,7 +194,7 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
|
||||
String[] optionArgs = option.split("=");
|
||||
|
||||
if (optionArgs.length == 1) {
|
||||
throw new IllegalArgumentException(String.format("Query parameter '%s' has no value!", optionArgs[0]));
|
||||
throw new IllegalArgumentException(String.format("Query parameter '%s' has no value", optionArgs[0]));
|
||||
}
|
||||
|
||||
properties.put(optionArgs[0], optionArgs[1]);
|
||||
@@ -209,21 +209,21 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
|
||||
|
||||
if (source.length != 2) {
|
||||
throw new IllegalArgumentException(
|
||||
"Credentials need to specify username and password like in 'username:password@database'!");
|
||||
"Credentials need to specify username and password like in 'username:password@database'");
|
||||
}
|
||||
}
|
||||
|
||||
private static void verifyDatabasePresent(String source) {
|
||||
|
||||
if (!StringUtils.hasText(source)) {
|
||||
throw new IllegalArgumentException("Credentials need to specify database like in 'username:password@database'!");
|
||||
throw new IllegalArgumentException("Credentials need to specify database like in 'username:password@database'");
|
||||
}
|
||||
}
|
||||
|
||||
private static void verifyUserNamePresent(String[] source) {
|
||||
|
||||
if (source.length == 0 || !StringUtils.hasText(source[0])) {
|
||||
throw new IllegalArgumentException("Credentials need to specify username!");
|
||||
throw new IllegalArgumentException("Credentials need to specify username");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
|
||||
try {
|
||||
return URLDecoder.decode(it, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new IllegalArgumentException("o_O UTF-8 not supported!", e);
|
||||
throw new IllegalArgumentException("o_O UTF-8 not supported", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
if (element.getAttributes().getLength() > allowedAttributesCount) {
|
||||
|
||||
parserContext.getReaderContext().error("Configure either MongoDB " + type + " or details individually!",
|
||||
parserContext.getReaderContext().error("Configure either MongoDB " + type + " or details individually",
|
||||
parserContext.extractSource(element));
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ package org.springframework.data.mongodb.config;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.data.auditing.ReactiveIsNewAwareAuditingHandler;
|
||||
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
|
||||
import org.springframework.data.auditing.config.AuditingConfiguration;
|
||||
@@ -34,6 +32,7 @@ import org.springframework.util.Assert;
|
||||
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableReactiveMongoAuditing} annotation.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @since 3.1
|
||||
*/
|
||||
class ReactiveMongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
||||
@@ -48,26 +47,27 @@ class ReactiveMongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupp
|
||||
return "reactiveMongoAuditingHandler";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcess(BeanDefinitionBuilder builder, AuditingConfiguration configuration,
|
||||
BeanDefinitionRegistry registry) {
|
||||
builder.setFactoryMethod("from").addConstructorArgReference("mongoMappingContext");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
|
||||
|
||||
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
|
||||
Assert.notNull(configuration, "AuditingConfiguration must not be null");
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveIsNewAwareAuditingHandler.class);
|
||||
|
||||
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntitiesFactoryBean.class);
|
||||
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
|
||||
builder.addConstructorArgValue(definition.getBeanDefinition());
|
||||
return configureDefaultAuditHandlerAttributes(configuration, builder);
|
||||
return configureDefaultAuditHandlerAttributes(configuration,
|
||||
BeanDefinitionBuilder.rootBeanDefinition(ReactiveIsNewAwareAuditingHandler.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!");
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
|
||||
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null");
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class);
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
||||
* A port is a number without a leading 0 at the end of the address that is proceeded by just a single :.
|
||||
*/
|
||||
private static final String HOST_PORT_SPLIT_PATTERN = "(?<!:):(?=[123456789]\\d*$)";
|
||||
private static final String COULD_NOT_PARSE_ADDRESS_MESSAGE = "Could not parse address %s '%s'. Check your replica set configuration!";
|
||||
private static final String COULD_NOT_PARSE_ADDRESS_MESSAGE = "Could not parse address %s '%s'; Check your replica set configuration";
|
||||
private static final Log LOG = LogFactory.getLog(ServerAddressPropertyEditor.class);
|
||||
|
||||
@Override
|
||||
@@ -68,7 +68,7 @@ public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
||||
|
||||
if (serverAddresses.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Could not resolve at least one server of the replica set configuration! Validate your config!");
|
||||
"Could not resolve at least one server of the replica set configuration; Validate your config");
|
||||
}
|
||||
|
||||
setValue(serverAddresses.toArray(new ServerAddress[serverAddresses.size()]));
|
||||
@@ -125,7 +125,7 @@ public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
||||
*/
|
||||
private String[] extractHostAddressAndPort(String addressAndPortSource) {
|
||||
|
||||
Assert.notNull(addressAndPortSource, "Address and port source must not be null!");
|
||||
Assert.notNull(addressAndPortSource, "Address and port source must not be null");
|
||||
|
||||
String[] hostAndPort = addressAndPortSource.split(HOST_PORT_SPLIT_PATTERN);
|
||||
String hostAddress = hostAndPort[0];
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -24,22 +22,16 @@ import java.util.stream.Collectors;
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOptions.DomainTypeMapping;
|
||||
import org.springframework.data.mongodb.core.aggregation.CountOperation;
|
||||
import org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,10 +24,14 @@ import org.springframework.data.util.Pair;
|
||||
import com.mongodb.bulk.BulkWriteResult;
|
||||
|
||||
/**
|
||||
* Bulk operations for insert/update/remove actions on a collection. These bulks operation are available since MongoDB
|
||||
* 2.6 and make use of low level bulk commands on the protocol level. This interface defines a fluent API to add
|
||||
* multiple single operations or list of similar operations in sequence which can then eventually be executed by calling
|
||||
* Bulk operations for insert/update/remove actions on a collection. Bulk operations are available since MongoDB 2.6 and
|
||||
* make use of low level bulk commands on the protocol level. This interface defines a fluent API to add multiple single
|
||||
* operations or list of similar operations in sequence which can then eventually be executed by calling
|
||||
* {@link #execute()}.
|
||||
* <p>
|
||||
* Bulk operations are issued as one batch that pulls together all insert, update, and delete operations. Operations
|
||||
* that require individual operation results such as optimistic locking (using {@code @Version}) are not supported and
|
||||
* the version field remains not populated.
|
||||
*
|
||||
* @author Tobias Trelle
|
||||
* @author Oliver Gierke
|
||||
|
||||
@@ -36,21 +36,29 @@ import com.mongodb.client.model.changestream.OperationType;
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Myroslav Kosinskyi
|
||||
* @since 2.1
|
||||
*/
|
||||
public class ChangeStreamEvent<T> {
|
||||
|
||||
@SuppressWarnings("rawtypes") //
|
||||
private static final AtomicReferenceFieldUpdater<ChangeStreamEvent, Object> CONVERTED_UPDATER = AtomicReferenceFieldUpdater
|
||||
.newUpdater(ChangeStreamEvent.class, Object.class, "converted");
|
||||
private static final AtomicReferenceFieldUpdater<ChangeStreamEvent, Object> CONVERTED_FULL_DOCUMENT_UPDATER = AtomicReferenceFieldUpdater
|
||||
.newUpdater(ChangeStreamEvent.class, Object.class, "convertedFullDocument");
|
||||
|
||||
@SuppressWarnings("rawtypes") //
|
||||
private static final AtomicReferenceFieldUpdater<ChangeStreamEvent, Object> CONVERTED_FULL_DOCUMENT_BEFORE_CHANGE_UPDATER = AtomicReferenceFieldUpdater
|
||||
.newUpdater(ChangeStreamEvent.class, Object.class, "convertedFullDocumentBeforeChange");
|
||||
|
||||
private final @Nullable ChangeStreamDocument<Document> raw;
|
||||
|
||||
private final Class<T> targetType;
|
||||
private final MongoConverter converter;
|
||||
|
||||
// accessed through CONVERTED_UPDATER.
|
||||
private volatile @Nullable T converted;
|
||||
// accessed through CONVERTED_FULL_DOCUMENT_UPDATER.
|
||||
private volatile @Nullable T convertedFullDocument;
|
||||
|
||||
// accessed through CONVERTED_FULL_DOCUMENT_BEFORE_CHANGE_UPDATER.
|
||||
private volatile @Nullable T convertedFullDocumentBeforeChange;
|
||||
|
||||
/**
|
||||
* @param raw can be {@literal null}.
|
||||
@@ -147,27 +155,43 @@ public class ChangeStreamEvent<T> {
|
||||
@Nullable
|
||||
public T getBody() {
|
||||
|
||||
if (raw == null) {
|
||||
if (raw == null || raw.getFullDocument() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Document fullDocument = raw.getFullDocument();
|
||||
return getConvertedFullDocument(raw.getFullDocument());
|
||||
}
|
||||
|
||||
if (fullDocument == null) {
|
||||
return targetType.cast(fullDocument);
|
||||
/**
|
||||
* Get the potentially converted {@link ChangeStreamDocument#getFullDocumentBeforeChange() document} before being changed.
|
||||
*
|
||||
* @return {@literal null} when {@link #getRaw()} or {@link ChangeStreamDocument#getFullDocumentBeforeChange()} is
|
||||
* {@literal null}.
|
||||
* @since 4.0
|
||||
*/
|
||||
@Nullable
|
||||
public T getBodyBeforeChange() {
|
||||
|
||||
if (raw == null || raw.getFullDocumentBeforeChange() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getConverted(fullDocument);
|
||||
return getConvertedFullDocumentBeforeChange(raw.getFullDocumentBeforeChange());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private T getConverted(Document fullDocument) {
|
||||
return (T) doGetConverted(fullDocument);
|
||||
private T getConvertedFullDocumentBeforeChange(Document fullDocument) {
|
||||
return (T) doGetConverted(fullDocument, CONVERTED_FULL_DOCUMENT_BEFORE_CHANGE_UPDATER);
|
||||
}
|
||||
|
||||
private Object doGetConverted(Document fullDocument) {
|
||||
@SuppressWarnings("unchecked")
|
||||
private T getConvertedFullDocument(Document fullDocument) {
|
||||
return (T) doGetConverted(fullDocument, CONVERTED_FULL_DOCUMENT_UPDATER);
|
||||
}
|
||||
|
||||
Object result = CONVERTED_UPDATER.get(this);
|
||||
private Object doGetConverted(Document fullDocument, AtomicReferenceFieldUpdater<ChangeStreamEvent, Object> updater) {
|
||||
|
||||
Object result = updater.get(this);
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
@@ -176,13 +200,13 @@ public class ChangeStreamEvent<T> {
|
||||
if (ClassUtils.isAssignable(Document.class, fullDocument.getClass())) {
|
||||
|
||||
result = converter.read(targetType, fullDocument);
|
||||
return CONVERTED_UPDATER.compareAndSet(this, null, result) ? result : CONVERTED_UPDATER.get(this);
|
||||
return updater.compareAndSet(this, null, result) ? result : updater.get(this);
|
||||
}
|
||||
|
||||
if (converter.getConversionService().canConvert(fullDocument.getClass(), targetType)) {
|
||||
|
||||
result = converter.getConversionService().convert(fullDocument, targetType);
|
||||
return CONVERTED_UPDATER.compareAndSet(this, null, result) ? result : CONVERTED_UPDATER.get(this);
|
||||
return updater.compareAndSet(this, null, result) ? result : updater.get(this);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.mongodb.client.model.changestream.ChangeStreamDocument;
|
||||
import com.mongodb.client.model.changestream.FullDocument;
|
||||
import com.mongodb.client.model.changestream.FullDocumentBeforeChange;
|
||||
|
||||
/**
|
||||
* Options applicable to MongoDB <a href="https://docs.mongodb.com/manual/changeStreams/">Change Streams</a>. Intended
|
||||
@@ -40,6 +41,7 @@ import com.mongodb.client.model.changestream.FullDocument;
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Myroslav Kosinskyi
|
||||
* @since 2.1
|
||||
*/
|
||||
public class ChangeStreamOptions {
|
||||
@@ -47,6 +49,7 @@ public class ChangeStreamOptions {
|
||||
private @Nullable Object filter;
|
||||
private @Nullable BsonValue resumeToken;
|
||||
private @Nullable FullDocument fullDocumentLookup;
|
||||
private @Nullable FullDocumentBeforeChange fullDocumentBeforeChangeLookup;
|
||||
private @Nullable Collation collation;
|
||||
private @Nullable Object resumeTimestamp;
|
||||
private Resume resume = Resume.UNDEFINED;
|
||||
@@ -74,6 +77,14 @@ public class ChangeStreamOptions {
|
||||
return Optional.ofNullable(fullDocumentLookup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link Optional#empty()} if not set.
|
||||
* @since 4.0
|
||||
*/
|
||||
public Optional<FullDocumentBeforeChange> getFullDocumentBeforeChangeLookup() {
|
||||
return Optional.ofNullable(fullDocumentBeforeChangeLookup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link Optional#empty()} if not set.
|
||||
*/
|
||||
@@ -148,7 +159,7 @@ public class ChangeStreamOptions {
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
"o_O that should actually not happen. The timestamp should be an Instant or a BsonTimestamp but was "
|
||||
"o_O that should actually not happen; The timestamp should be an Instant or a BsonTimestamp but was "
|
||||
+ ObjectUtils.nullSafeClassName(timestamp));
|
||||
}
|
||||
|
||||
@@ -170,6 +181,9 @@ public class ChangeStreamOptions {
|
||||
if (!ObjectUtils.nullSafeEquals(this.fullDocumentLookup, that.fullDocumentLookup)) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtils.nullSafeEquals(this.fullDocumentBeforeChangeLookup, that.fullDocumentBeforeChangeLookup)) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtils.nullSafeEquals(this.collation, that.collation)) {
|
||||
return false;
|
||||
}
|
||||
@@ -184,6 +198,7 @@ public class ChangeStreamOptions {
|
||||
int result = ObjectUtils.nullSafeHashCode(filter);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(resumeToken);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(fullDocumentLookup);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(fullDocumentBeforeChangeLookup);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(collation);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(resumeTimestamp);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(resume);
|
||||
@@ -220,6 +235,7 @@ public class ChangeStreamOptions {
|
||||
private @Nullable Object filter;
|
||||
private @Nullable BsonValue resumeToken;
|
||||
private @Nullable FullDocument fullDocumentLookup;
|
||||
private @Nullable FullDocumentBeforeChange fullDocumentBeforeChangeLookup;
|
||||
private @Nullable Collation collation;
|
||||
private @Nullable Object resumeTimestamp;
|
||||
private Resume resume = Resume.UNDEFINED;
|
||||
@@ -234,7 +250,7 @@ public class ChangeStreamOptions {
|
||||
*/
|
||||
public ChangeStreamOptionsBuilder collation(Collation collation) {
|
||||
|
||||
Assert.notNull(collation, "Collation must not be null nor empty!");
|
||||
Assert.notNull(collation, "Collation must not be null nor empty");
|
||||
|
||||
this.collation = collation;
|
||||
return this;
|
||||
@@ -258,7 +274,7 @@ public class ChangeStreamOptions {
|
||||
*/
|
||||
public ChangeStreamOptionsBuilder filter(Aggregation filter) {
|
||||
|
||||
Assert.notNull(filter, "Filter must not be null!");
|
||||
Assert.notNull(filter, "Filter must not be null");
|
||||
|
||||
this.filter = filter;
|
||||
return this;
|
||||
@@ -287,7 +303,7 @@ public class ChangeStreamOptions {
|
||||
*/
|
||||
public ChangeStreamOptionsBuilder resumeToken(BsonValue resumeToken) {
|
||||
|
||||
Assert.notNull(resumeToken, "ResumeToken must not be null!");
|
||||
Assert.notNull(resumeToken, "ResumeToken must not be null");
|
||||
|
||||
this.resumeToken = resumeToken;
|
||||
|
||||
@@ -316,12 +332,38 @@ public class ChangeStreamOptions {
|
||||
*/
|
||||
public ChangeStreamOptionsBuilder fullDocumentLookup(FullDocument lookup) {
|
||||
|
||||
Assert.notNull(lookup, "Lookup must not be null!");
|
||||
Assert.notNull(lookup, "Lookup must not be null");
|
||||
|
||||
this.fullDocumentLookup = lookup;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link FullDocumentBeforeChange} lookup to use.
|
||||
*
|
||||
* @param lookup must not be {@literal null}.
|
||||
* @return this.
|
||||
* @since 4.0
|
||||
*/
|
||||
public ChangeStreamOptionsBuilder fullDocumentBeforeChangeLookup(FullDocumentBeforeChange lookup) {
|
||||
|
||||
Assert.notNull(lookup, "Lookup must not be null");
|
||||
|
||||
this.fullDocumentBeforeChangeLookup = lookup;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the full document before being changed if it is available.
|
||||
*
|
||||
* @return this.
|
||||
* @since 4.0
|
||||
* @see #fullDocumentBeforeChangeLookup(FullDocumentBeforeChange)
|
||||
*/
|
||||
public ChangeStreamOptionsBuilder returnFullDocumentBeforeChange() {
|
||||
return fullDocumentBeforeChangeLookup(FullDocumentBeforeChange.WHEN_AVAILABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cluster time to resume from.
|
||||
*
|
||||
@@ -330,7 +372,7 @@ public class ChangeStreamOptions {
|
||||
*/
|
||||
public ChangeStreamOptionsBuilder resumeAt(Instant resumeTimestamp) {
|
||||
|
||||
Assert.notNull(resumeTimestamp, "ResumeTimestamp must not be null!");
|
||||
Assert.notNull(resumeTimestamp, "ResumeTimestamp must not be null");
|
||||
|
||||
this.resumeTimestamp = resumeTimestamp;
|
||||
return this;
|
||||
@@ -345,7 +387,7 @@ public class ChangeStreamOptions {
|
||||
*/
|
||||
public ChangeStreamOptionsBuilder resumeAt(BsonTimestamp resumeTimestamp) {
|
||||
|
||||
Assert.notNull(resumeTimestamp, "ResumeTimestamp must not be null!");
|
||||
Assert.notNull(resumeTimestamp, "ResumeTimestamp must not be null");
|
||||
|
||||
this.resumeTimestamp = resumeTimestamp;
|
||||
return this;
|
||||
@@ -391,6 +433,7 @@ public class ChangeStreamOptions {
|
||||
options.filter = this.filter;
|
||||
options.resumeToken = this.resumeToken;
|
||||
options.fullDocumentLookup = this.fullDocumentLookup;
|
||||
options.fullDocumentBeforeChangeLookup = this.fullDocumentBeforeChangeLookup;
|
||||
options.collation = this.collation;
|
||||
options.resumeTimestamp = this.resumeTimestamp;
|
||||
options.resume = this.resume;
|
||||
|
||||
@@ -46,10 +46,11 @@ public class CollectionOptions {
|
||||
private @Nullable Collation collation;
|
||||
private ValidationOptions validationOptions;
|
||||
private @Nullable TimeSeriesOptions timeSeriesOptions;
|
||||
private @Nullable CollectionChangeStreamOptions changeStreamOptions;
|
||||
|
||||
private CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped,
|
||||
@Nullable Collation collation, ValidationOptions validationOptions,
|
||||
@Nullable TimeSeriesOptions timeSeriesOptions) {
|
||||
@Nullable TimeSeriesOptions timeSeriesOptions, @Nullable CollectionChangeStreamOptions changeStreamOptions) {
|
||||
|
||||
this.maxDocuments = maxDocuments;
|
||||
this.size = size;
|
||||
@@ -57,6 +58,7 @@ public class CollectionOptions {
|
||||
this.collation = collation;
|
||||
this.validationOptions = validationOptions;
|
||||
this.timeSeriesOptions = timeSeriesOptions;
|
||||
this.changeStreamOptions = changeStreamOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,9 +70,9 @@ public class CollectionOptions {
|
||||
*/
|
||||
public static CollectionOptions just(Collation collation) {
|
||||
|
||||
Assert.notNull(collation, "Collation must not be null!");
|
||||
Assert.notNull(collation, "Collation must not be null");
|
||||
|
||||
return new CollectionOptions(null, null, null, collation, ValidationOptions.none(), null);
|
||||
return new CollectionOptions(null, null, null, collation, ValidationOptions.none(), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +82,7 @@ public class CollectionOptions {
|
||||
* @since 2.0
|
||||
*/
|
||||
public static CollectionOptions empty() {
|
||||
return new CollectionOptions(null, null, null, null, ValidationOptions.none(), null);
|
||||
return new CollectionOptions(null, null, null, null, ValidationOptions.none(), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,6 +99,18 @@ public class CollectionOptions {
|
||||
return empty().timeSeries(TimeSeriesOptions.timeSeries(timeField));
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick way to set up {@link CollectionOptions} for emitting (pre & post) change events.
|
||||
*
|
||||
* @return new instance of {@link CollectionOptions}.
|
||||
* @see #changeStream(CollectionChangeStreamOptions)
|
||||
* @see CollectionChangeStreamOptions#preAndPostImages(boolean)
|
||||
* @since 4.0
|
||||
*/
|
||||
public static CollectionOptions emitChangedRevisions() {
|
||||
return empty().changeStream(CollectionChangeStreamOptions.preAndPostImages(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new {@link CollectionOptions} with already given settings and capped set to {@literal true}. <br />
|
||||
* <strong>NOTE</strong> Using capped collections requires defining {@link #size(long)}.
|
||||
@@ -105,7 +119,7 @@ public class CollectionOptions {
|
||||
* @since 2.0
|
||||
*/
|
||||
public CollectionOptions capped() {
|
||||
return new CollectionOptions(size, maxDocuments, true, collation, validationOptions, null);
|
||||
return new CollectionOptions(size, maxDocuments, true, collation, validationOptions, timeSeriesOptions, changeStreamOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,7 +130,7 @@ public class CollectionOptions {
|
||||
* @since 2.0
|
||||
*/
|
||||
public CollectionOptions maxDocuments(long maxDocuments) {
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions);
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions, changeStreamOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,7 +141,7 @@ public class CollectionOptions {
|
||||
* @since 2.0
|
||||
*/
|
||||
public CollectionOptions size(long size) {
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions);
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions, changeStreamOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,7 +152,7 @@ public class CollectionOptions {
|
||||
* @since 2.0
|
||||
*/
|
||||
public CollectionOptions collation(@Nullable Collation collation) {
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions);
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions, changeStreamOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,7 +244,7 @@ public class CollectionOptions {
|
||||
*/
|
||||
public CollectionOptions schemaValidationLevel(ValidationLevel validationLevel) {
|
||||
|
||||
Assert.notNull(validationLevel, "ValidationLevel must not be null!");
|
||||
Assert.notNull(validationLevel, "ValidationLevel must not be null");
|
||||
return validation(validationOptions.validationLevel(validationLevel));
|
||||
}
|
||||
|
||||
@@ -244,7 +258,7 @@ public class CollectionOptions {
|
||||
*/
|
||||
public CollectionOptions schemaValidationAction(ValidationAction validationAction) {
|
||||
|
||||
Assert.notNull(validationAction, "ValidationAction must not be null!");
|
||||
Assert.notNull(validationAction, "ValidationAction must not be null");
|
||||
return validation(validationOptions.validationAction(validationAction));
|
||||
}
|
||||
|
||||
@@ -257,8 +271,8 @@ public class CollectionOptions {
|
||||
*/
|
||||
public CollectionOptions validation(ValidationOptions validationOptions) {
|
||||
|
||||
Assert.notNull(validationOptions, "ValidationOptions must not be null!");
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions);
|
||||
Assert.notNull(validationOptions, "ValidationOptions must not be null");
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions, changeStreamOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,8 +284,21 @@ public class CollectionOptions {
|
||||
*/
|
||||
public CollectionOptions timeSeries(TimeSeriesOptions timeSeriesOptions) {
|
||||
|
||||
Assert.notNull(timeSeriesOptions, "TimeSeriesOptions must not be null!");
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions);
|
||||
Assert.notNull(timeSeriesOptions, "TimeSeriesOptions must not be null");
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions, changeStreamOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new {@link CollectionOptions} with the given {@link TimeSeriesOptions}.
|
||||
*
|
||||
* @param changeStreamOptions must not be {@literal null}.
|
||||
* @return new instance of {@link CollectionOptions}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public CollectionOptions changeStream(CollectionChangeStreamOptions changeStreamOptions) {
|
||||
|
||||
Assert.notNull(changeStreamOptions, "ChangeStreamOptions must not be null");
|
||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions, changeStreamOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -332,6 +359,16 @@ public class CollectionOptions {
|
||||
return Optional.ofNullable(timeSeriesOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link CollectionChangeStreamOptions} if available.
|
||||
*
|
||||
* @return {@link Optional#empty()} if not specified.
|
||||
* @since 4.0
|
||||
*/
|
||||
public Optional<CollectionChangeStreamOptions> getChangeStreamOptions() {
|
||||
return Optional.ofNullable(changeStreamOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulation of ValidationOptions options.
|
||||
*
|
||||
@@ -428,6 +465,34 @@ public class CollectionOptions {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulation of options applied to define collections change stream behaviour.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 4.0
|
||||
*/
|
||||
public static class CollectionChangeStreamOptions {
|
||||
|
||||
private final boolean preAndPostImages;
|
||||
|
||||
private CollectionChangeStreamOptions(boolean emitChangedRevisions) {
|
||||
this.preAndPostImages = emitChangedRevisions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the version of a document before and after changes (the document pre- and post-images).
|
||||
*
|
||||
* @return new instance of {@link CollectionChangeStreamOptions}.
|
||||
*/
|
||||
public static CollectionChangeStreamOptions preAndPostImages(boolean emitChangedRevisions) {
|
||||
return new CollectionChangeStreamOptions(true);
|
||||
}
|
||||
|
||||
public boolean getPreAndPostImages() {
|
||||
return preAndPostImages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Options applicable to Time Series collections.
|
||||
*
|
||||
@@ -446,7 +511,7 @@ public class CollectionOptions {
|
||||
|
||||
private TimeSeriesOptions(String timeField, @Nullable String metaField, GranularityDefinition granularity) {
|
||||
|
||||
Assert.hasText(timeField, "Time field must not be empty or null!");
|
||||
Assert.hasText(timeField, "Time field must not be empty or null");
|
||||
|
||||
this.timeField = timeField;
|
||||
this.metaField = metaField;
|
||||
|
||||
@@ -23,8 +23,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.query.MetricConversion;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -38,7 +38,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
class CountQuery {
|
||||
|
||||
private Document source;
|
||||
private final Document source;
|
||||
|
||||
private CountQuery(Document source) {
|
||||
this.source = source;
|
||||
@@ -101,7 +101,7 @@ class CountQuery {
|
||||
}
|
||||
|
||||
if (valueToInspect instanceof Collection) {
|
||||
return requiresRewrite((Collection) valueToInspect);
|
||||
return requiresRewrite((Collection<?>) valueToInspect);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -157,12 +157,14 @@ class CountQuery {
|
||||
* @param $and potentially existing {@code $and} condition.
|
||||
* @return the rewritten query {@link Document}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Document createGeoWithin(String key, Document source, @Nullable Object $and) {
|
||||
|
||||
boolean spheric = source.containsKey("$nearSphere");
|
||||
Object $near = spheric ? source.get("$nearSphere") : source.get("$near");
|
||||
|
||||
Number maxDistance = source.containsKey("$maxDistance") ? (Number) source.get("$maxDistance") : Double.MAX_VALUE;
|
||||
Number maxDistance = getMaxDistance(source, $near, spheric);
|
||||
|
||||
List<Object> $centerMax = Arrays.asList(toCenterCoordinates($near), maxDistance);
|
||||
Document $geoWithinMax = new Document("$geoWithin",
|
||||
new Document(spheric ? "$centerSphere" : "$center", $centerMax));
|
||||
@@ -176,23 +178,51 @@ 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<Document> andElements = (Collection<Document>) $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: "
|
||||
"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))));
|
||||
criteria.add(new Document(key, $geoWithinMax));
|
||||
|
||||
return new Document("$and", criteria);
|
||||
}
|
||||
|
||||
private static Number getMaxDistance(Document source, Object $near, boolean spheric) {
|
||||
|
||||
Number maxDistance = Double.MAX_VALUE;
|
||||
|
||||
if (source.containsKey("$maxDistance")) { // legacy coordinate pair
|
||||
return (Number) source.get("$maxDistance");
|
||||
}
|
||||
|
||||
if ($near instanceof Document nearDoc) {
|
||||
|
||||
if (nearDoc.containsKey("$maxDistance")) {
|
||||
|
||||
maxDistance = (Number) nearDoc.get("$maxDistance");
|
||||
// geojson is in Meters but we need radians x/(6378.1*1000)
|
||||
if (spheric && nearDoc.containsKey("$geometry")) {
|
||||
maxDistance = MetricConversion.metersToRadians(maxDistance.doubleValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxDistance;
|
||||
}
|
||||
|
||||
private static boolean containsNear(Document source) {
|
||||
return source.containsKey("$near") || source.containsKey("$nearSphere");
|
||||
}
|
||||
@@ -216,10 +246,16 @@ class CountQuery {
|
||||
return Arrays.asList(((Point) value).getX(), ((Point) value).getY());
|
||||
}
|
||||
|
||||
if (value instanceof Document && ((Document) value).containsKey("x")) {
|
||||
if (value instanceof Document document) {
|
||||
|
||||
Document point = (Document) value;
|
||||
return Arrays.asList(point.get("x"), point.get("y"));
|
||||
if (document.containsKey("x")) {
|
||||
return Arrays.asList(document.get("x"), document.get("y"));
|
||||
}
|
||||
|
||||
if (document.containsKey("$geometry")) {
|
||||
Document geoJsonPoint = document.get("$geometry", Document.class);
|
||||
return geoJsonPoint.get("coordinates");
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
@@ -61,8 +61,8 @@ public interface CursorPreparer extends ReadPreferenceAware {
|
||||
default FindIterable<Document> initiateFind(MongoCollection<Document> collection,
|
||||
Function<MongoCollection<Document>, FindIterable<Document>> find) {
|
||||
|
||||
Assert.notNull(collection, "Collection must not be null!");
|
||||
Assert.notNull(find, "Find function must not be null!");
|
||||
Assert.notNull(collection, "Collection must not be null");
|
||||
Assert.notNull(find, "Find function must not be null");
|
||||
|
||||
if (hasReadPreference()) {
|
||||
collection = collection.withReadPreference(getReadPreference());
|
||||
|
||||
@@ -90,9 +90,9 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
DefaultBulkOperations(MongoOperations mongoOperations, String collectionName,
|
||||
BulkOperationContext bulkOperationContext) {
|
||||
|
||||
Assert.notNull(mongoOperations, "MongoOperations must not be null!");
|
||||
Assert.hasText(collectionName, "CollectionName must not be null nor empty!");
|
||||
Assert.notNull(bulkOperationContext, "BulkOperationContext must not be null!");
|
||||
Assert.notNull(mongoOperations, "MongoOperations must not be null");
|
||||
Assert.hasText(collectionName, "CollectionName must not be null nor empty");
|
||||
Assert.notNull(bulkOperationContext, "BulkOperationContext must not be null");
|
||||
|
||||
this.mongoOperations = mongoOperations;
|
||||
this.collectionName = collectionName;
|
||||
@@ -112,7 +112,7 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
@Override
|
||||
public BulkOperations insert(Object document) {
|
||||
|
||||
Assert.notNull(document, "Document must not be null!");
|
||||
Assert.notNull(document, "Document must not be null");
|
||||
|
||||
maybeEmitEvent(new BeforeConvertEvent<>(document, collectionName));
|
||||
Object source = maybeInvokeBeforeConvertCallback(document);
|
||||
@@ -124,7 +124,7 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
@Override
|
||||
public BulkOperations insert(List<? extends Object> documents) {
|
||||
|
||||
Assert.notNull(documents, "Documents must not be null!");
|
||||
Assert.notNull(documents, "Documents must not be null");
|
||||
|
||||
documents.forEach(this::insert);
|
||||
|
||||
@@ -135,8 +135,8 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
@SuppressWarnings("unchecked")
|
||||
public BulkOperations updateOne(Query query, Update update) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(update, "Update must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
|
||||
return updateOne(Collections.singletonList(Pair.of(query, update)));
|
||||
}
|
||||
@@ -144,7 +144,7 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
@Override
|
||||
public BulkOperations updateOne(List<Pair<Query, Update>> updates) {
|
||||
|
||||
Assert.notNull(updates, "Updates must not be null!");
|
||||
Assert.notNull(updates, "Updates must not be null");
|
||||
|
||||
for (Pair<Query, Update> update : updates) {
|
||||
update(update.getFirst(), update.getSecond(), false, false);
|
||||
@@ -157,8 +157,8 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
@SuppressWarnings("unchecked")
|
||||
public BulkOperations updateMulti(Query query, Update update) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(update, "Update must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
|
||||
return updateMulti(Collections.singletonList(Pair.of(query, update)));
|
||||
}
|
||||
@@ -166,7 +166,7 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
@Override
|
||||
public BulkOperations updateMulti(List<Pair<Query, Update>> updates) {
|
||||
|
||||
Assert.notNull(updates, "Updates must not be null!");
|
||||
Assert.notNull(updates, "Updates must not be null");
|
||||
|
||||
for (Pair<Query, Update> update : updates) {
|
||||
update(update.getFirst(), update.getSecond(), false, true);
|
||||
@@ -193,7 +193,7 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
@Override
|
||||
public BulkOperations remove(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
DeleteOptions deleteOptions = new DeleteOptions();
|
||||
query.getCollation().map(Collation::toMongoCollation).ifPresent(deleteOptions::collation);
|
||||
@@ -206,7 +206,7 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
@Override
|
||||
public BulkOperations remove(List<Query> removes) {
|
||||
|
||||
Assert.notNull(removes, "Removals must not be null!");
|
||||
Assert.notNull(removes, "Removals must not be null");
|
||||
|
||||
for (Query query : removes) {
|
||||
remove(query);
|
||||
@@ -218,9 +218,9 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
@Override
|
||||
public BulkOperations replaceOne(Query query, Object replacement, FindAndReplaceOptions options) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(replacement, "Replacement must not be null!");
|
||||
Assert.notNull(options, "Options must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(replacement, "Replacement must not be null");
|
||||
Assert.notNull(options, "Options must not be null");
|
||||
|
||||
ReplaceOptions replaceOptions = new ReplaceOptions();
|
||||
replaceOptions.upsert(options.isUpsert());
|
||||
@@ -241,7 +241,7 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
|
||||
com.mongodb.bulk.BulkWriteResult result = mongoOperations.execute(collectionName, this::bulkWriteTo);
|
||||
|
||||
Assert.state(result != null, "Result must not be null.");
|
||||
Assert.state(result != null, "Result must not be null");
|
||||
|
||||
models.forEach(this::maybeEmitAfterSaveEvent);
|
||||
models.forEach(this::maybeInvokeAfterSaveCallback);
|
||||
@@ -308,8 +308,8 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
*/
|
||||
private BulkOperations update(Query query, Update update, boolean upsert, boolean multi) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(update, "Update must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
|
||||
UpdateOptions options = computeUpdateOptions(query, update, upsert);
|
||||
|
||||
@@ -470,7 +470,7 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
return options.ordered(false);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("BulkMode was null!");
|
||||
throw new IllegalStateException("BulkMode was null");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,9 +83,9 @@ public class DefaultIndexOperations implements IndexOperations {
|
||||
public DefaultIndexOperations(MongoDatabaseFactory mongoDbFactory, String collectionName, QueryMapper queryMapper,
|
||||
@Nullable Class<?> type) {
|
||||
|
||||
Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null!");
|
||||
Assert.notNull(collectionName, "Collection name can not be null!");
|
||||
Assert.notNull(queryMapper, "QueryMapper must not be null!");
|
||||
Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null");
|
||||
Assert.notNull(collectionName, "Collection name can not be null");
|
||||
Assert.notNull(queryMapper, "QueryMapper must not be null");
|
||||
|
||||
this.collectionName = collectionName;
|
||||
this.mapper = queryMapper;
|
||||
@@ -103,8 +103,8 @@ public class DefaultIndexOperations implements IndexOperations {
|
||||
*/
|
||||
public DefaultIndexOperations(MongoOperations mongoOperations, String collectionName, @Nullable Class<?> type) {
|
||||
|
||||
Assert.notNull(mongoOperations, "MongoOperations must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(mongoOperations, "MongoOperations must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
|
||||
this.mongoOperations = mongoOperations;
|
||||
this.mapper = new QueryMapper(mongoOperations.getConverter());
|
||||
@@ -172,7 +172,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()) {
|
||||
|
||||
@@ -189,7 +190,7 @@ public class DefaultIndexOperations implements IndexOperations {
|
||||
@Nullable
|
||||
public <T> T execute(CollectionCallback<T> callback) {
|
||||
|
||||
Assert.notNull(callback, "CollectionCallback must not be null!");
|
||||
Assert.notNull(callback, "CollectionCallback must not be null");
|
||||
|
||||
if (type != null) {
|
||||
return mongoOperations.execute(type, callback);
|
||||
|
||||
@@ -76,9 +76,9 @@ public class DefaultReactiveIndexOperations implements ReactiveIndexOperations {
|
||||
private DefaultReactiveIndexOperations(ReactiveMongoOperations mongoOperations, String collectionName,
|
||||
QueryMapper queryMapper, Optional<Class<?>> type) {
|
||||
|
||||
Assert.notNull(mongoOperations, "ReactiveMongoOperations must not be null!");
|
||||
Assert.notNull(collectionName, "Collection must not be null!");
|
||||
Assert.notNull(queryMapper, "QueryMapper must not be null!");
|
||||
Assert.notNull(mongoOperations, "ReactiveMongoOperations must not be null");
|
||||
Assert.notNull(collectionName, "Collection must not be null");
|
||||
Assert.notNull(queryMapper, "QueryMapper must not be null");
|
||||
|
||||
this.mongoOperations = mongoOperations;
|
||||
this.collectionName = collectionName;
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.bson.types.ObjectId;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
|
||||
import org.springframework.data.mongodb.core.script.NamedMongoScript;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -65,7 +64,7 @@ class DefaultScriptOperations implements ScriptOperations {
|
||||
*/
|
||||
public DefaultScriptOperations(MongoOperations mongoOperations) {
|
||||
|
||||
Assert.notNull(mongoOperations, "MongoOperations must not be null!");
|
||||
Assert.notNull(mongoOperations, "MongoOperations must not be null");
|
||||
|
||||
this.mongoOperations = mongoOperations;
|
||||
}
|
||||
@@ -78,7 +77,7 @@ class DefaultScriptOperations implements ScriptOperations {
|
||||
@Override
|
||||
public NamedMongoScript register(NamedMongoScript script) {
|
||||
|
||||
Assert.notNull(script, "Script must not be null!");
|
||||
Assert.notNull(script, "Script must not be null");
|
||||
|
||||
mongoOperations.save(script, SCRIPT_COLLECTION_NAME);
|
||||
return script;
|
||||
@@ -87,7 +86,7 @@ class DefaultScriptOperations implements ScriptOperations {
|
||||
@Override
|
||||
public Object execute(final ExecutableMongoScript script, final Object... args) {
|
||||
|
||||
Assert.notNull(script, "Script must not be null!");
|
||||
Assert.notNull(script, "Script must not be null");
|
||||
|
||||
return mongoOperations.execute(new DbCallback<Object>() {
|
||||
|
||||
@@ -106,7 +105,7 @@ class DefaultScriptOperations implements ScriptOperations {
|
||||
@Override
|
||||
public Object call(final String scriptName, final Object... args) {
|
||||
|
||||
Assert.hasText(scriptName, "ScriptName must not be null or empty!");
|
||||
Assert.hasText(scriptName, "ScriptName must not be null or empty");
|
||||
|
||||
return mongoOperations.execute(new DbCallback<Object>() {
|
||||
|
||||
@@ -122,7 +121,7 @@ class DefaultScriptOperations implements ScriptOperations {
|
||||
@Override
|
||||
public boolean exists(String scriptName) {
|
||||
|
||||
Assert.hasText(scriptName, "ScriptName must not be null or empty!");
|
||||
Assert.hasText(scriptName, "ScriptName must not be null or empty");
|
||||
|
||||
return mongoOperations.exists(query(where("_id").is(scriptName)), NamedMongoScript.class, SCRIPT_COLLECTION_NAME);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.core;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Delegate class to encapsulate lifecycle event configuration and publishing.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 4.0
|
||||
* @see ApplicationEventPublisher
|
||||
*/
|
||||
class EntityLifecycleEventDelegate {
|
||||
|
||||
private @Nullable ApplicationEventPublisher publisher;
|
||||
private boolean eventsEnabled = true;
|
||||
|
||||
public void setPublisher(@Nullable ApplicationEventPublisher publisher) {
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
public boolean isEventsEnabled() {
|
||||
return eventsEnabled;
|
||||
}
|
||||
|
||||
public void setEventsEnabled(boolean eventsEnabled) {
|
||||
this.eventsEnabled = eventsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish an application event if event publishing is enabled.
|
||||
*
|
||||
* @param event the application event.
|
||||
*/
|
||||
public void publishEvent(Object event) {
|
||||
|
||||
if (canPublishEvent()) {
|
||||
publisher.publishEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canPublishEvent() {
|
||||
return publisher != null && eventsEnabled;
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.convert.CustomConversions;
|
||||
@@ -57,6 +56,7 @@ import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.client.model.ChangeStreamPreAndPostImagesOptions;
|
||||
import com.mongodb.client.model.CreateCollectionOptions;
|
||||
import com.mongodb.client.model.TimeSeriesGranularity;
|
||||
import com.mongodb.client.model.ValidationOptions;
|
||||
@@ -112,7 +112,7 @@ class EntityOperations {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
<T> Entity<T> forEntity(T entity) {
|
||||
|
||||
Assert.notNull(entity, "Bean must not be null!");
|
||||
Assert.notNull(entity, "Bean must not be null");
|
||||
|
||||
if (entity instanceof String) {
|
||||
return new UnmappedEntity(parse(entity.toString()));
|
||||
@@ -135,8 +135,8 @@ class EntityOperations {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
<T> AdaptibleEntity<T> forEntity(T entity, ConversionService conversionService) {
|
||||
|
||||
Assert.notNull(entity, "Bean must not be null!");
|
||||
Assert.notNull(conversionService, "ConversionService must not be null!");
|
||||
Assert.notNull(entity, "Bean must not be null");
|
||||
Assert.notNull(conversionService, "ConversionService must not be null");
|
||||
|
||||
if (entity instanceof String) {
|
||||
return new UnmappedEntity(parse(entity.toString()));
|
||||
@@ -171,10 +171,17 @@ class EntityOperations {
|
||||
|
||||
if (entityClass == null) {
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
"No class parameter provided, entity collection can't be determined!");
|
||||
"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) {
|
||||
@@ -201,7 +208,7 @@ class EntityOperations {
|
||||
*/
|
||||
public String getIdPropertyName(Class<?> type) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
Assert.notNull(type, "Type must not be null");
|
||||
|
||||
MongoPersistentEntity<?> persistentEntity = context.getPersistentEntity(type);
|
||||
|
||||
@@ -240,12 +247,12 @@ class EntityOperations {
|
||||
try {
|
||||
return Document.parse(source);
|
||||
} catch (org.bson.json.JsonParseException o_O) {
|
||||
throw new MappingException("Could not parse given String to save into a JSON document!", o_O);
|
||||
throw new MappingException("Could not parse given String to save into a JSON document", o_O);
|
||||
} catch (RuntimeException o_O) {
|
||||
|
||||
// legacy 3.x exception
|
||||
if (ClassUtils.matchesTypeName(o_O.getClass(), "JSONParseException")) {
|
||||
throw new MappingException("Could not parse given String to save into a JSON document!", o_O);
|
||||
throw new MappingException("Could not parse given String to save into a JSON document", o_O);
|
||||
}
|
||||
throw o_O;
|
||||
}
|
||||
@@ -334,6 +341,9 @@ class EntityOperations {
|
||||
result.timeSeriesOptions(options);
|
||||
});
|
||||
|
||||
collectionOptions.getChangeStreamOptions().ifPresent(it -> result
|
||||
.changeStreamPreAndPostImagesOptions(new ChangeStreamPreAndPostImagesOptions(it.getPreAndPostImages())));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -518,7 +528,7 @@ class EntityOperations {
|
||||
|
||||
@Override
|
||||
public Query getQueryForVersion() {
|
||||
throw new MappingException("Cannot query for version on plain Documents!");
|
||||
throw new MappingException("Cannot query for version on plain Documents");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -614,7 +624,7 @@ class EntityOperations {
|
||||
public Query getByIdQuery() {
|
||||
|
||||
if (!entity.hasIdProperty()) {
|
||||
throw new MappingException("No id property found for object of type " + entity.getType() + "!");
|
||||
throw new MappingException("No id property found for object of type " + entity.getType());
|
||||
}
|
||||
|
||||
MongoPersistentProperty idProperty = entity.getRequiredIdProperty();
|
||||
@@ -662,7 +672,7 @@ class EntityOperations {
|
||||
|
||||
if (!MongoSimpleTypes.AUTOGENERATED_ID_TYPES.contains(property.getType())) {
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
String.format("Cannot autogenerate id of type %s for entity of type %s!", property.getType().getName(),
|
||||
String.format("Cannot autogenerate id of type %s for entity of type %s", property.getType().getName(),
|
||||
entity.getType().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class ExecutableAggregationOperationSupport implements ExecutableAggregationOper
|
||||
@Override
|
||||
public <T> ExecutableAggregation<T> aggregateAndReturn(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ExecutableAggregationSupport<>(template, domainType, null, null);
|
||||
}
|
||||
@@ -69,7 +69,7 @@ class ExecutableAggregationOperationSupport implements ExecutableAggregationOper
|
||||
@Override
|
||||
public AggregationWithAggregation<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection must not be null nor empty");
|
||||
|
||||
return new ExecutableAggregationSupport<>(template, domainType, aggregation, collection);
|
||||
}
|
||||
@@ -77,7 +77,7 @@ class ExecutableAggregationOperationSupport implements ExecutableAggregationOper
|
||||
@Override
|
||||
public TerminatingAggregation<T> by(Aggregation aggregation) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation must not be null!");
|
||||
Assert.notNull(aggregation, "Aggregation must not be null");
|
||||
|
||||
return new ExecutableAggregationSupport<>(template, domainType, aggregation, collection);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
||||
@Override
|
||||
public <T> ExecutableFind<T> query(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ExecutableFindSupport<>(template, domainType, domainType, null, ALL_QUERY);
|
||||
}
|
||||
@@ -84,7 +84,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
||||
@Override
|
||||
public FindWithProjection<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection name must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection name must not be null nor empty");
|
||||
|
||||
return new ExecutableFindSupport<>(template, domainType, returnType, collection, query);
|
||||
}
|
||||
@@ -92,7 +92,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
||||
@Override
|
||||
public <T1> FindWithQuery<T1> as(Class<T1> returnType) {
|
||||
|
||||
Assert.notNull(returnType, "ReturnType must not be null!");
|
||||
Assert.notNull(returnType, "ReturnType must not be null");
|
||||
|
||||
return new ExecutableFindSupport<>(template, domainType, returnType, collection, query);
|
||||
}
|
||||
@@ -100,7 +100,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
||||
@Override
|
||||
public TerminatingFind<T> matching(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
return new ExecutableFindSupport<>(template, domainType, returnType, collection, query);
|
||||
}
|
||||
@@ -115,7 +115,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
||||
}
|
||||
|
||||
if (result.size() > 1) {
|
||||
throw new IncorrectResultSizeDataAccessException("Query " + asString() + " returned non unique result.", 1);
|
||||
throw new IncorrectResultSizeDataAccessException("Query " + asString() + " returned non unique result", 1);
|
||||
}
|
||||
|
||||
return result.iterator().next();
|
||||
@@ -158,7 +158,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
||||
@Override
|
||||
public TerminatingDistinct<Object> distinct(String field) {
|
||||
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(field, "Field must not be null");
|
||||
|
||||
return new DistinctOperationSupport(this, field);
|
||||
}
|
||||
@@ -246,7 +246,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <R> TerminatingDistinct<R> as(Class<R> resultType) {
|
||||
|
||||
Assert.notNull(resultType, "ResultType must not be null!");
|
||||
Assert.notNull(resultType, "ResultType must not be null");
|
||||
|
||||
return new DistinctOperationSupport<>((ExecutableFindSupport) delegate.as(resultType), field);
|
||||
}
|
||||
@@ -254,7 +254,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
||||
@Override
|
||||
public TerminatingDistinct<T> matching(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
return new DistinctOperationSupport<>((ExecutableFindSupport<T>) delegate.matching(query), field);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
||||
@Override
|
||||
public <T> ExecutableInsert<T> insert(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ExecutableInsertSupport<>(template, domainType, null, null);
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
||||
@Override
|
||||
public T one(T object) {
|
||||
|
||||
Assert.notNull(object, "Object must not be null!");
|
||||
Assert.notNull(object, "Object must not be null");
|
||||
|
||||
return template.insert(object, getCollectionName());
|
||||
}
|
||||
@@ -78,7 +78,7 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
||||
@Override
|
||||
public Collection<T> all(Collection<? extends T> objects) {
|
||||
|
||||
Assert.notNull(objects, "Objects must not be null!");
|
||||
Assert.notNull(objects, "Objects must not be null");
|
||||
|
||||
return template.insert(objects, getCollectionName());
|
||||
}
|
||||
@@ -86,7 +86,7 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
||||
@Override
|
||||
public BulkWriteResult bulk(Collection<? extends T> objects) {
|
||||
|
||||
Assert.notNull(objects, "Objects must not be null!");
|
||||
Assert.notNull(objects, "Objects must not be null");
|
||||
|
||||
return template.bulkOps(bulkMode != null ? bulkMode : BulkMode.ORDERED, domainType, getCollectionName())
|
||||
.insert(new ArrayList<>(objects)).execute();
|
||||
@@ -95,7 +95,7 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
||||
@Override
|
||||
public InsertWithBulkMode<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection must not be null nor empty.");
|
||||
Assert.hasText(collection, "Collection must not be null nor empty");
|
||||
|
||||
return new ExecutableInsertSupport<>(template, domainType, collection, bulkMode);
|
||||
}
|
||||
@@ -103,7 +103,7 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
||||
@Override
|
||||
public TerminatingBulkInsert<T> withBulkMode(BulkMode bulkMode) {
|
||||
|
||||
Assert.notNull(bulkMode, "BulkMode must not be null!");
|
||||
Assert.notNull(bulkMode, "BulkMode must not be null");
|
||||
|
||||
return new ExecutableInsertSupport<>(template, domainType, collection, bulkMode);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,9 @@ public interface ExecutableMapReduceOperation {
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 2.1
|
||||
* @deprecated since 4.0 in favor of {@link org.springframework.data.mongodb.core.aggregation}.
|
||||
*/
|
||||
@Deprecated
|
||||
interface MapReduceWithOptions<T> {
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,7 +37,7 @@ class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperatio
|
||||
|
||||
ExecutableMapReduceOperationSupport(MongoTemplate template) {
|
||||
|
||||
Assert.notNull(template, "Template must not be null!");
|
||||
Assert.notNull(template, "Template must not be null");
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperatio
|
||||
@Override
|
||||
public <T> ExecutableMapReduceSupport<T> mapReduce(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ExecutableMapReduceSupport<>(template, domainType, domainType, null, ALL_QUERY, null, null, null);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperatio
|
||||
@Override
|
||||
public MapReduceWithProjection<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection name must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection name must not be null nor empty");
|
||||
|
||||
return new ExecutableMapReduceSupport<>(template, domainType, returnType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
@@ -114,7 +114,7 @@ class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperatio
|
||||
@Override
|
||||
public TerminatingMapReduce<T> matching(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
return new ExecutableMapReduceSupport<>(template, domainType, returnType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
@@ -127,7 +127,7 @@ class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperatio
|
||||
@Override
|
||||
public <R> MapReduceWithQuery<R> as(Class<R> resultType) {
|
||||
|
||||
Assert.notNull(resultType, "ResultType must not be null!");
|
||||
Assert.notNull(resultType, "ResultType must not be null");
|
||||
|
||||
return new ExecutableMapReduceSupport<>(template, domainType, resultType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
@@ -140,7 +140,7 @@ class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperatio
|
||||
@Override
|
||||
public ExecutableMapReduce<T> with(MapReduceOptions options) {
|
||||
|
||||
Assert.notNull(options, "Options must not be null! Please consider empty MapReduceOptions#options() instead.");
|
||||
Assert.notNull(options, "Options must not be null Please consider empty MapReduceOptions#options() instead");
|
||||
|
||||
return new ExecutableMapReduceSupport<>(template, domainType, returnType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
@@ -153,7 +153,7 @@ class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperatio
|
||||
@Override
|
||||
public MapReduceWithReduceFunction<T> map(String mapFunction) {
|
||||
|
||||
Assert.hasText(mapFunction, "MapFunction name must not be null nor empty!");
|
||||
Assert.hasText(mapFunction, "MapFunction name must not be null nor empty");
|
||||
|
||||
return new ExecutableMapReduceSupport<>(template, domainType, returnType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
@@ -166,7 +166,7 @@ class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperatio
|
||||
@Override
|
||||
public ExecutableMapReduce<T> reduce(String reduceFunction) {
|
||||
|
||||
Assert.hasText(reduceFunction, "ReduceFunction name must not be null nor empty!");
|
||||
Assert.hasText(reduceFunction, "ReduceFunction name must not be null nor empty");
|
||||
|
||||
return new ExecutableMapReduceSupport<>(template, domainType, returnType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
|
||||
@@ -44,7 +44,7 @@ class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation {
|
||||
@Override
|
||||
public <T> ExecutableRemove<T> remove(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ExecutableRemoveSupport<>(tempate, domainType, ALL_QUERY, null);
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation {
|
||||
@Override
|
||||
public RemoveWithQuery<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection must not be null nor empty");
|
||||
|
||||
return new ExecutableRemoveSupport<>(template, domainType, query, collection);
|
||||
}
|
||||
@@ -78,7 +78,7 @@ class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation {
|
||||
@Override
|
||||
public TerminatingRemove<T> matching(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
return new ExecutableRemoveSupport<>(template, domainType, query, collection);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
||||
@Override
|
||||
public <T> ExecutableUpdate<T> update(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ExecutableUpdateSupport<>(template, domainType, ALL_QUERY, null, null, null, null, null, domainType);
|
||||
}
|
||||
@@ -84,7 +84,7 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
||||
@Override
|
||||
public TerminatingUpdate<T> apply(UpdateDefinition update) {
|
||||
|
||||
Assert.notNull(update, "Update must not be null!");
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
|
||||
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
findAndReplaceOptions, replacement, targetType);
|
||||
@@ -93,7 +93,7 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
||||
@Override
|
||||
public UpdateWithQuery<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection must not be null nor empty");
|
||||
|
||||
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
findAndReplaceOptions, replacement, targetType);
|
||||
@@ -102,7 +102,7 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
||||
@Override
|
||||
public TerminatingFindAndModify<T> withOptions(FindAndModifyOptions options) {
|
||||
|
||||
Assert.notNull(options, "Options must not be null!");
|
||||
Assert.notNull(options, "Options must not be null");
|
||||
|
||||
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, options,
|
||||
findAndReplaceOptions, replacement, targetType);
|
||||
@@ -111,7 +111,7 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
||||
@Override
|
||||
public FindAndReplaceWithProjection<T> replaceWith(T replacement) {
|
||||
|
||||
Assert.notNull(replacement, "Replacement must not be null!");
|
||||
Assert.notNull(replacement, "Replacement must not be null");
|
||||
|
||||
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
findAndReplaceOptions, replacement, targetType);
|
||||
@@ -120,7 +120,7 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
||||
@Override
|
||||
public FindAndReplaceWithProjection<T> withOptions(FindAndReplaceOptions options) {
|
||||
|
||||
Assert.notNull(options, "Options must not be null!");
|
||||
Assert.notNull(options, "Options must not be null");
|
||||
|
||||
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
options, replacement, targetType);
|
||||
@@ -129,7 +129,7 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
||||
@Override
|
||||
public UpdateWithUpdate<T> matching(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
findAndReplaceOptions, replacement, targetType);
|
||||
@@ -138,7 +138,7 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
||||
@Override
|
||||
public <R> FindAndReplaceWithOptions<R> as(Class<R> resultType) {
|
||||
|
||||
Assert.notNull(resultType, "ResultType must not be null!");
|
||||
Assert.notNull(resultType, "ResultType must not be null");
|
||||
|
||||
return new ExecutableUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
findAndReplaceOptions, replacement, resultType);
|
||||
|
||||
@@ -35,7 +35,7 @@ public class FindAndModifyOptions {
|
||||
|
||||
private static final FindAndModifyOptions NONE = new FindAndModifyOptions() {
|
||||
|
||||
private static final String ERROR_MSG = "FindAndModifyOptions.none() cannot be changed. Please use FindAndModifyOptions.options() instead.";
|
||||
private static final String ERROR_MSG = "FindAndModifyOptions.none() cannot be changed; Please use FindAndModifyOptions.options() instead";
|
||||
|
||||
@Override
|
||||
public FindAndModifyOptions returnNew(boolean returnNew) {
|
||||
|
||||
@@ -38,7 +38,7 @@ public class FindAndReplaceOptions {
|
||||
|
||||
private static final FindAndReplaceOptions NONE = new FindAndReplaceOptions() {
|
||||
|
||||
private static final String ERROR_MSG = "FindAndReplaceOptions.none() cannot be changed. Please use FindAndReplaceOptions.options() instead.";
|
||||
private static final String ERROR_MSG = "FindAndReplaceOptions.none() cannot be changed; Please use FindAndReplaceOptions.options() instead";
|
||||
|
||||
@Override
|
||||
public FindAndReplaceOptions returnNew() {
|
||||
|
||||
@@ -61,8 +61,8 @@ public interface FindPublisherPreparer extends ReadPreferenceAware {
|
||||
default FindPublisher<Document> initiateFind(MongoCollection<Document> collection,
|
||||
Function<MongoCollection<Document>, FindPublisher<Document>> find) {
|
||||
|
||||
Assert.notNull(collection, "Collection must not be null!");
|
||||
Assert.notNull(find, "Find function must not be null!");
|
||||
Assert.notNull(collection, "Collection must not be null");
|
||||
Assert.notNull(find, "Find function must not be null");
|
||||
|
||||
if (hasReadPreference()) {
|
||||
collection = collection.withReadPreference(getReadPreference());
|
||||
|
||||
@@ -39,7 +39,7 @@ class GeoCommandStatistics {
|
||||
*/
|
||||
private GeoCommandStatistics(Document source) {
|
||||
|
||||
Assert.notNull(source, "Source document must not be null!");
|
||||
Assert.notNull(source, "Source document must not be null");
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class GeoCommandStatistics {
|
||||
*/
|
||||
public static GeoCommandStatistics from(Document commandResult) {
|
||||
|
||||
Assert.notNull(commandResult, "Command result must not be null!");
|
||||
Assert.notNull(commandResult, "Command result must not be null");
|
||||
|
||||
Object stats = commandResult.get("stats");
|
||||
return stats == null ? NONE : new GeoCommandStatistics((Document) stats);
|
||||
|
||||
@@ -97,6 +97,16 @@ public class MappedDocument {
|
||||
return this.document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the documents {@link #ID_FIELD}.
|
||||
*
|
||||
* @param value the {@literal _id} value to set.
|
||||
* @since 3.4.3
|
||||
*/
|
||||
public void updateId(Object value) {
|
||||
document.put(ID_FIELD, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@link UpdateDefinition} that indicates that the {@link #getUpdateObject() update object} has already been
|
||||
* mapped to the specific domain type.
|
||||
|
||||
@@ -40,7 +40,7 @@ import org.springframework.data.mongodb.core.schema.JsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
|
||||
import org.springframework.data.mongodb.core.schema.MongoJsonSchema.MongoJsonSchemaBuilder;
|
||||
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -81,7 +81,7 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
||||
MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext,
|
||||
Predicate<JsonSchemaPropertyContext> filter, LinkedMultiValueMap<String, Class<?>> mergeProperties) {
|
||||
|
||||
Assert.notNull(converter, "Converter must not be null!");
|
||||
Assert.notNull(converter, "Converter must not be null");
|
||||
this.converter = converter;
|
||||
this.mappingContext = mappingContext;
|
||||
this.filter = filter;
|
||||
@@ -267,7 +267,7 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
||||
}
|
||||
|
||||
private boolean isSpecificType(MongoPersistentProperty property) {
|
||||
return !ClassTypeInformation.OBJECT.equals(property.getTypeInformation().getActualType());
|
||||
return !TypeInformation.OBJECT.equals(property.getTypeInformation().getActualType());
|
||||
}
|
||||
|
||||
private JsonSchemaProperty applyEncryptionDataIfNecessary(MongoPersistentProperty property,
|
||||
|
||||
@@ -57,8 +57,8 @@ public class MongoAction {
|
||||
public MongoAction(@Nullable WriteConcern defaultWriteConcern, MongoActionOperation mongoActionOperation,
|
||||
String collectionName, @Nullable Class<?> entityType, @Nullable Document document, @Nullable Document query) {
|
||||
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(mongoActionOperation, "MongoActionOperation must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
Assert.notNull(mongoActionOperation, "MongoActionOperation must not be null");
|
||||
|
||||
this.defaultWriteConcern = defaultWriteConcern;
|
||||
this.mongoActionOperation = mongoActionOperation;
|
||||
|
||||
@@ -42,7 +42,7 @@ public class MongoAdmin implements MongoAdminOperations {
|
||||
*/
|
||||
public MongoAdmin(MongoClient client) {
|
||||
|
||||
Assert.notNull(client, "Client must not be null!");
|
||||
Assert.notNull(client, "Client must not be null");
|
||||
this.mongoClient = client;
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ public class MongoClientFactoryBean extends AbstractFactoryBean<MongoClient> imp
|
||||
protected MongoClientSettings computeClientSetting() {
|
||||
|
||||
if (connectionString != null && (StringUtils.hasText(host) || port != null)) {
|
||||
throw new IllegalStateException("ConnectionString and host/port configuration exclude one another!");
|
||||
throw new IllegalStateException("ConnectionString and host/port configuration exclude one another");
|
||||
}
|
||||
|
||||
ConnectionString connectionString = this.connectionString != null ? this.connectionString
|
||||
|
||||
@@ -44,8 +44,8 @@ public class MongoDataIntegrityViolationException extends DataIntegrityViolation
|
||||
|
||||
super(message);
|
||||
|
||||
Assert.notNull(writeResult, "WriteResult must not be null!");
|
||||
Assert.notNull(actionOperation, "MongoActionOperation must not be null!");
|
||||
Assert.notNull(writeResult, "WriteResult must not be null");
|
||||
Assert.notNull(actionOperation, "MongoActionOperation must not be null");
|
||||
|
||||
this.writeResult = writeResult;
|
||||
this.actionOperation = actionOperation;
|
||||
|
||||
@@ -64,10 +64,10 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
|
||||
protected MongoDatabaseFactorySupport(C mongoClient, String databaseName, boolean mongoInstanceCreated,
|
||||
PersistenceExceptionTranslator exceptionTranslator) {
|
||||
|
||||
Assert.notNull(mongoClient, "MongoClient must not be null!");
|
||||
Assert.hasText(databaseName, "Database name must not be empty!");
|
||||
Assert.notNull(mongoClient, "MongoClient must not be null");
|
||||
Assert.hasText(databaseName, "Database name must not be empty");
|
||||
Assert.isTrue(databaseName.matches("[^/\\\\.$\"\\s]+"),
|
||||
"Database name must not contain slashes, dots, spaces, quotes, or dollar signs!");
|
||||
"Database name must not contain slashes, dots, spaces, quotes, or dollar signs");
|
||||
|
||||
this.mongoClient = mongoClient;
|
||||
this.databaseName = databaseName;
|
||||
@@ -91,7 +91,7 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
|
||||
@Override
|
||||
public MongoDatabase getMongoDatabase(String dbName) throws DataAccessException {
|
||||
|
||||
Assert.hasText(dbName, "Database name must not be empty!");
|
||||
Assert.hasText(dbName, "Database name must not be empty");
|
||||
|
||||
MongoDatabase db = doGetMongoDatabase(dbName);
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ public interface MongoJsonSchemaCreator {
|
||||
*/
|
||||
static MongoJsonSchemaCreator create(MongoConverter mongoConverter) {
|
||||
|
||||
Assert.notNull(mongoConverter, "MongoConverter must not be null!");
|
||||
Assert.notNull(mongoConverter, "MongoConverter must not be null");
|
||||
return new MappingMongoJsonSchemaCreator(mongoConverter);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,9 @@ import org.bson.Document;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationPipeline;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationUpdate;
|
||||
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
||||
@@ -77,6 +79,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);
|
||||
|
||||
@@ -178,7 +181,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
||||
*/
|
||||
default SessionScoped withSession(Supplier<ClientSession> sessionProvider) {
|
||||
|
||||
Assert.notNull(sessionProvider, "SessionProvider must not be null!");
|
||||
Assert.notNull(sessionProvider, "SessionProvider must not be null");
|
||||
|
||||
return new SessionScoped() {
|
||||
|
||||
@@ -280,6 +283,56 @@ public interface MongoOperations extends FluentMongoOperations {
|
||||
*/
|
||||
MongoCollection<Document> createCollection(String collectionName, @Nullable CollectionOptions collectionOptions);
|
||||
|
||||
/**
|
||||
* Create a view with the provided name. The view content is defined by the {@link AggregationOperation pipeline
|
||||
* stages} on another collection or view identified by the given {@link #getCollectionName(Class) source type}.
|
||||
*
|
||||
* @param name the name of the view to create.
|
||||
* @param source the type defining the views source collection.
|
||||
* @param stages the {@link AggregationOperation aggregation pipeline stages} defining the view content.
|
||||
* @since 4.0
|
||||
*/
|
||||
default MongoCollection<Document> createView(String name, Class<?> source, AggregationOperation... stages) {
|
||||
return createView(name, source, AggregationPipeline.of(stages));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a view with the provided name. The view content is defined by the {@link AggregationPipeline pipeline} on
|
||||
* another collection or view identified by the given {@link #getCollectionName(Class) source type}.
|
||||
*
|
||||
* @param name the name of the view to create.
|
||||
* @param source the type defining the views source collection.
|
||||
* @param pipeline the {@link AggregationPipeline} defining the view content.
|
||||
* @since 4.0
|
||||
*/
|
||||
default MongoCollection<Document> createView(String name, Class<?> source, AggregationPipeline pipeline) {
|
||||
return createView(name, source, pipeline, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a view with the provided name. The view content is defined by the {@link AggregationPipeline pipeline} on
|
||||
* another collection or view identified by the given {@link #getCollectionName(Class) source type}.
|
||||
*
|
||||
* @param name the name of the view to create.
|
||||
* @param source the type defining the views source collection.
|
||||
* @param pipeline the {@link AggregationPipeline} defining the view content.
|
||||
* @param options additional settings to apply when creating the view. Can be {@literal null}.
|
||||
* @since 4.0
|
||||
*/
|
||||
MongoCollection<Document> createView(String name, Class<?> source, AggregationPipeline pipeline, @Nullable ViewOptions options);
|
||||
|
||||
/**
|
||||
* Create a view with the provided name. The view content is defined by the {@link AggregationPipeline pipeline} on
|
||||
* another collection or view identified by the given source.
|
||||
*
|
||||
* @param name the name of the view to create.
|
||||
* @param source the name of the collection or view defining the to be created views source.
|
||||
* @param pipeline the {@link AggregationPipeline} defining the view content.
|
||||
* @param options additional settings to apply when creating the view. Can be {@literal null}.
|
||||
* @since 4.0
|
||||
*/
|
||||
MongoCollection<Document> createView(String name, String source, AggregationPipeline pipeline, @Nullable ViewOptions options);
|
||||
|
||||
/**
|
||||
* A set of collection names.
|
||||
*
|
||||
@@ -918,6 +971,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
|
||||
@@ -959,6 +1014,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
|
||||
@@ -985,7 +1042,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
||||
@Nullable
|
||||
default <T> T findAndReplace(Query query, T replacement, FindAndReplaceOptions options, String collectionName) {
|
||||
|
||||
Assert.notNull(replacement, "Replacement must not be null!");
|
||||
Assert.notNull(replacement, "Replacement must not be null");
|
||||
return findAndReplace(query, replacement, options, (Class<T>) ClassUtils.getUserClass(replacement), collectionName);
|
||||
}
|
||||
|
||||
@@ -1032,6 +1089,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
|
||||
@@ -1115,6 +1174,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.
|
||||
* @see #exactCount(Query, Class)
|
||||
* @see #estimatedCount(Class)
|
||||
*/
|
||||
@@ -1170,11 +1231,13 @@ 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) {
|
||||
|
||||
Assert.notNull(entityClass, "Entity class must not be null!");
|
||||
Assert.notNull(entityClass, "Entity class must not be null");
|
||||
return estimatedCount(getCollectionName(entityClass));
|
||||
}
|
||||
|
||||
@@ -1206,6 +1269,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.
|
||||
* @since 3.4
|
||||
*/
|
||||
default long exactCount(Query query, Class<?> entityClass) {
|
||||
@@ -1261,9 +1326,10 @@ public interface MongoOperations extends FluentMongoOperations {
|
||||
/**
|
||||
* Insert the object into the collection for the entity type of the object to save. <br />
|
||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. <br />
|
||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
||||
* String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from ObjectId to your
|
||||
* property type will be handled by Spring's BeanWrapper class that leverages Type Conversion API. See
|
||||
* If your object has an {@literal Id} property which holds a {@literal null} value, it will be set with the generated
|
||||
* Id from MongoDB. If your Id property is a String then MongoDB ObjectId will be used to populate that string.
|
||||
* Otherwise, the conversion from ObjectId to your property type will be handled by Spring's BeanWrapper class that
|
||||
* leverages Type Conversion API. See
|
||||
* <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation" > Spring's
|
||||
* Type Conversion"</a> for more details. <br />
|
||||
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
||||
@@ -1273,6 +1339,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);
|
||||
|
||||
@@ -1297,6 +1365,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);
|
||||
|
||||
@@ -1315,6 +1385,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);
|
||||
|
||||
@@ -1333,6 +1405,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);
|
||||
|
||||
@@ -1367,9 +1441,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);
|
||||
|
||||
@@ -1421,9 +1497,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);
|
||||
|
||||
@@ -1475,9 +1553,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);
|
||||
|
||||
@@ -1525,6 +1605,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);
|
||||
|
||||
@@ -1541,18 +1623,20 @@ public interface MongoOperations extends FluentMongoOperations {
|
||||
DeleteResult remove(Object object, String collectionName);
|
||||
|
||||
/**
|
||||
* Remove all documents that match the provided query document criteria from the the collection used to store the
|
||||
* Remove all documents that match the provided query document criteria from the collection used to store the
|
||||
* entityClass. The Class parameter is also used to help convert the Id of the object if it is present in the query.
|
||||
*
|
||||
* @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 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);
|
||||
|
||||
/**
|
||||
* Remove all documents that match the provided query document criteria from the the collection used to store the
|
||||
* Remove all documents that match the provided query document criteria from the collection used to store the
|
||||
* entityClass. The Class parameter is also used to help convert the Id of the object if it is present in the query.
|
||||
*
|
||||
* @param query the query document that specifies the criteria used to remove a record.
|
||||
@@ -1595,14 +1679,16 @@ 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);
|
||||
|
||||
/**
|
||||
* Returns and removes all documents that match the provided query document criteria from the the collection used to
|
||||
* store the entityClass. The Class parameter is also used to help convert the Id of the object if it is present in
|
||||
* the query.
|
||||
* Returns and removes all documents that match the provided query document criteria from the collection used to store
|
||||
* the entityClass. The Class parameter is also used to help convert the Id of the object if it is present in the
|
||||
* query.
|
||||
*
|
||||
* @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.
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -66,8 +67,8 @@ import org.springframework.data.mongodb.core.QueryOperations.UpdateContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationPipeline;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
|
||||
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
||||
import org.springframework.data.mongodb.core.convert.DbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
|
||||
@@ -174,6 +175,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
private final EntityOperations operations;
|
||||
private final PropertyOperations propertyOperations;
|
||||
private final QueryOperations queryOperations;
|
||||
private final EntityLifecycleEventDelegate eventDelegate;
|
||||
|
||||
private @Nullable WriteConcern writeConcern;
|
||||
private WriteConcernResolver writeConcernResolver = DefaultWriteConcernResolver.INSTANCE;
|
||||
@@ -216,7 +218,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
*/
|
||||
public MongoTemplate(MongoDatabaseFactory mongoDbFactory, @Nullable MongoConverter mongoConverter) {
|
||||
|
||||
Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null!");
|
||||
Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null");
|
||||
|
||||
this.mongoDbFactory = mongoDbFactory;
|
||||
this.exceptionTranslator = mongoDbFactory.getExceptionTranslator();
|
||||
@@ -228,6 +230,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
this.propertyOperations = new PropertyOperations(this.mongoConverter.getMappingContext());
|
||||
this.queryOperations = new QueryOperations(queryMapper, updateMapper, operations, propertyOperations,
|
||||
mongoDbFactory);
|
||||
this.eventDelegate = new EntityLifecycleEventDelegate();
|
||||
|
||||
// We always have a mapping context in the converter, whether it's a simple one or not
|
||||
mappingContext = this.mongoConverter.getMappingContext();
|
||||
@@ -266,6 +269,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
this.operations = that.operations;
|
||||
this.propertyOperations = that.propertyOperations;
|
||||
this.queryOperations = that.queryOperations;
|
||||
this.eventDelegate = that.eventDelegate;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,12 +312,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
this.readPreference = readPreference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure whether lifecycle events such as {@link AfterLoadEvent}, {@link BeforeSaveEvent}, etc. should be
|
||||
* published or whether emission should be suppressed. Enabled by default.
|
||||
*
|
||||
* @param enabled {@code true} to enable entity lifecycle events; {@code false} to disable entity lifecycle events.
|
||||
* @since 4.0
|
||||
* @see MongoMappingEvent
|
||||
*/
|
||||
public void setEntityLifecycleEventsEnabled(boolean enabled) {
|
||||
this.eventDelegate.setEventsEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
prepareIndexCreator(applicationContext);
|
||||
|
||||
eventPublisher = applicationContext;
|
||||
eventDelegate.setPublisher(eventPublisher);
|
||||
|
||||
if (entityCallbacks == null) {
|
||||
setEntityCallbacks(EntityCallbacks.create(applicationContext));
|
||||
@@ -338,7 +355,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
*/
|
||||
public void setEntityCallbacks(EntityCallbacks entityCallbacks) {
|
||||
|
||||
Assert.notNull(entityCallbacks, "EntityCallbacks must not be null!");
|
||||
Assert.notNull(entityCallbacks, "EntityCallbacks must not be null");
|
||||
this.entityCallbacks = entityCallbacks;
|
||||
}
|
||||
|
||||
@@ -430,10 +447,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
protected <T> Stream<T> doStream(Query query, Class<?> entityType, String collectionName, Class<T> returnType) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(entityType, "Entity type must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(returnType, "ReturnType must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(entityType, "Entity type must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
Assert.notNull(returnType, "ReturnType must not be null");
|
||||
|
||||
return execute(collectionName, (CollectionCallback<Stream<T>>) collection -> {
|
||||
|
||||
@@ -462,7 +479,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public Document executeCommand(String jsonCommand) {
|
||||
|
||||
Assert.hasText(jsonCommand, "JsonCommand must not be null nor empty!");
|
||||
Assert.hasText(jsonCommand, "JsonCommand must not be null nor empty");
|
||||
|
||||
return execute(db -> db.runCommand(Document.parse(jsonCommand), Document.class));
|
||||
}
|
||||
@@ -471,7 +488,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public Document executeCommand(Document command) {
|
||||
|
||||
Assert.notNull(command, "Command must not be null!");
|
||||
Assert.notNull(command, "Command must not be null");
|
||||
|
||||
return execute(db -> db.runCommand(command, Document.class));
|
||||
}
|
||||
@@ -480,7 +497,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public Document executeCommand(Document command, @Nullable ReadPreference readPreference) {
|
||||
|
||||
Assert.notNull(command, "Command must not be null!");
|
||||
Assert.notNull(command, "Command must not be null");
|
||||
|
||||
return execute(db -> readPreference != null //
|
||||
? db.runCommand(command, readPreference, Document.class) //
|
||||
@@ -506,9 +523,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
protected void executeQuery(Query query, String collectionName, DocumentCallbackHandler documentCallbackHandler,
|
||||
@Nullable CursorPreparer preparer) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(documentCallbackHandler, "DocumentCallbackHandler must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
Assert.notNull(documentCallbackHandler, "DocumentCallbackHandler must not be null");
|
||||
|
||||
Document queryObject = queryMapper.getMappedObject(query.getQueryObject(), Optional.empty());
|
||||
Document sortObject = query.getSortObject();
|
||||
@@ -526,7 +543,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public <T> T execute(DbCallback<T> action) {
|
||||
|
||||
Assert.notNull(action, "DbCallback must not be null!");
|
||||
Assert.notNull(action, "DbCallback must not be null");
|
||||
|
||||
try {
|
||||
MongoDatabase db = prepareDatabase(this.doGetDatabase());
|
||||
@@ -539,15 +556,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public <T> T execute(Class<?> entityClass, CollectionCallback<T> callback) {
|
||||
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
return execute(getCollectionName(entityClass), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T execute(String collectionName, CollectionCallback<T> callback) {
|
||||
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(callback, "CollectionCallback must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
Assert.notNull(callback, "CollectionCallback must not be null");
|
||||
|
||||
try {
|
||||
MongoCollection<Document> collection = getAndPrepareCollection(doGetDatabase(), collectionName);
|
||||
@@ -560,7 +577,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public SessionScoped withSession(ClientSessionOptions options) {
|
||||
|
||||
Assert.notNull(options, "ClientSessionOptions must not be null!");
|
||||
Assert.notNull(options, "ClientSessionOptions must not be null");
|
||||
|
||||
return withSession(() -> mongoDbFactory.getSession(options));
|
||||
}
|
||||
@@ -568,7 +585,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public MongoTemplate withSession(ClientSession session) {
|
||||
|
||||
Assert.notNull(session, "ClientSession must not be null!");
|
||||
Assert.notNull(session, "ClientSession must not be null");
|
||||
|
||||
return new SessionBoundMongoTemplate(session, MongoTemplate.this);
|
||||
}
|
||||
@@ -593,7 +610,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
public <T> MongoCollection<Document> createCollection(Class<T> entityClass,
|
||||
@Nullable CollectionOptions collectionOptions) {
|
||||
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
|
||||
return doCreateCollection(getCollectionName(entityClass),
|
||||
operations.convertToCreateCollectionOptions(collectionOptions, entityClass));
|
||||
@@ -602,7 +619,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public MongoCollection<Document> createCollection(String collectionName) {
|
||||
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
return doCreateCollection(collectionName, new Document());
|
||||
}
|
||||
@@ -611,16 +628,50 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
public MongoCollection<Document> createCollection(String collectionName,
|
||||
@Nullable CollectionOptions collectionOptions) {
|
||||
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
return doCreateCollection(collectionName,
|
||||
operations.convertToCreateCollectionOptions(collectionOptions, Object.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoCollection<Document> createView(String name, Class<?> source, AggregationPipeline pipeline, @Nullable ViewOptions options) {
|
||||
|
||||
return createView(name, getCollectionName(source),
|
||||
queryOperations.createAggregation(Aggregation.newAggregation(source, pipeline.getOperations()), source),
|
||||
options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoCollection<Document> createView(String name, String source, AggregationPipeline pipeline, @Nullable ViewOptions options) {
|
||||
|
||||
return createView(name, source,
|
||||
queryOperations.createAggregation(Aggregation.newAggregation(pipeline.getOperations()), (Class<?>) null),
|
||||
options);
|
||||
}
|
||||
|
||||
private MongoCollection<Document> createView(String name, String source, AggregationDefinition aggregation,
|
||||
@Nullable ViewOptions options) {
|
||||
return doCreateView(name, source, aggregation.getAggregationPipeline(), options);
|
||||
}
|
||||
|
||||
protected MongoCollection<Document> doCreateView(String name, String source, List<Document> pipeline, @Nullable ViewOptions options) {
|
||||
|
||||
CreateViewOptions viewOptions = new CreateViewOptions();
|
||||
if (options != null) {
|
||||
options.getCollation().map(Collation::toMongoCollation).ifPresent(viewOptions::collation);
|
||||
}
|
||||
|
||||
return execute(db -> {
|
||||
db.createView(name, source, pipeline, viewOptions);
|
||||
return db.getCollection(name);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public MongoCollection<Document> getCollection(String collectionName) {
|
||||
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
return execute(db -> db.getCollection(collectionName, Document.class));
|
||||
}
|
||||
@@ -634,7 +685,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public boolean collectionExists(String collectionName) {
|
||||
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
return execute(db -> {
|
||||
|
||||
@@ -655,7 +706,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public void dropCollection(String collectionName) {
|
||||
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
execute(collectionName, (CollectionCallback<Void>) collection -> {
|
||||
collection.drop();
|
||||
@@ -695,8 +746,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public BulkOperations bulkOps(BulkMode mode, @Nullable Class<?> entityType, String collectionName) {
|
||||
|
||||
Assert.notNull(mode, "BulkMode must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(mode, "BulkMode must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
|
||||
DefaultBulkOperations operations = new DefaultBulkOperations(this, collectionName,
|
||||
new BulkOperationContext(mode, Optional.ofNullable(getPersistentEntity(entityType)), queryMapper, updateMapper,
|
||||
@@ -724,9 +775,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public <T> T findOne(Query query, Class<T> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
if (ObjectUtils.isEmpty(query.getSortObject())) {
|
||||
|
||||
@@ -756,7 +807,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
if (query == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Query passed in to exist can't be null");
|
||||
}
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
QueryContext queryContext = queryOperations.createQueryContext(query);
|
||||
Document mappedQuery = queryContext.getMappedQuery(entityClass, this::getPersistentEntity);
|
||||
@@ -775,9 +826,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public <T> List<T> find(Query query, Class<T> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
|
||||
return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass,
|
||||
new QueryCursorPreparer(query, entityClass));
|
||||
@@ -793,9 +844,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public <T> T findById(Object id, Class<T> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(id, "Id must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(id, "Id must not be null");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
String idKey = operations.getIdPropertyName(entityClass);
|
||||
|
||||
@@ -812,11 +863,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
public <T> List<T> findDistinct(Query query, String field, String collectionName, Class<?> entityClass,
|
||||
Class<T> resultClass) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(resultClass, "ResultClass must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(field, "Field must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
Assert.notNull(resultClass, "ResultClass must not be null");
|
||||
|
||||
MongoPersistentEntity<?> entity = entityClass != Object.class ? getPersistentEntity(entityClass) : null;
|
||||
DistinctQueryContext distinctQueryContext = queryOperations.distinctQueryContext(query, field);
|
||||
@@ -872,15 +923,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
public <T> GeoResults<T> geoNear(NearQuery near, Class<?> domainType, String collectionName, Class<T> returnType) {
|
||||
|
||||
if (near == null) {
|
||||
throw new InvalidDataAccessApiUsageException("NearQuery must not be null!");
|
||||
throw new InvalidDataAccessApiUsageException("NearQuery must not be null");
|
||||
}
|
||||
|
||||
if (domainType == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Entity class must not be null!");
|
||||
throw new InvalidDataAccessApiUsageException("Entity class must not be null");
|
||||
}
|
||||
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(returnType, "ReturnType must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
Assert.notNull(returnType, "ReturnType must not be null");
|
||||
|
||||
String collection = StringUtils.hasText(collectionName) ? collectionName : getCollectionName(domainType);
|
||||
String distanceField = operations.nearQueryDistanceFieldName(domainType);
|
||||
@@ -894,7 +945,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
DocumentCallback<GeoResult<T>> callback = new GeoNearResultDocumentCallback<>(distanceField,
|
||||
new ProjectingReadCallback<>(mongoConverter, projection, 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) {
|
||||
@@ -934,17 +985,17 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
public <T> T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class<T> entityClass,
|
||||
String collectionName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(update, "Update must not be null!");
|
||||
Assert.notNull(options, "Options must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
Assert.notNull(options, "Options must not be null");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
FindAndModifyOptions optionsToUse = FindAndModifyOptions.of(options);
|
||||
|
||||
Optionals.ifAllPresent(query.getCollation(), optionsToUse.getCollation(), (l, r) -> {
|
||||
throw new IllegalArgumentException(
|
||||
"Both Query and FindAndModifyOptions define a collation. Please provide the collation only via one of the two.");
|
||||
"Both Query and FindAndModifyOptions define a collation; Please provide the collation only via one of the two");
|
||||
});
|
||||
|
||||
if (!options.getCollation().isPresent()) {
|
||||
@@ -959,15 +1010,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
public <S, T> T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class<S> entityType,
|
||||
String collectionName, Class<T> resultType) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(replacement, "Replacement must not be null!");
|
||||
Assert.notNull(options, "Options must not be null! Use FindAndReplaceOptions#empty() instead.");
|
||||
Assert.notNull(entityType, "EntityType must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(resultType, "ResultType must not be null! Use Object.class instead.");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(replacement, "Replacement must not be null");
|
||||
Assert.notNull(options, "Options must not be null Use FindAndReplaceOptions#empty() instead");
|
||||
Assert.notNull(entityType, "EntityType must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
Assert.notNull(resultType, "ResultType must not be null Use Object.class instead");
|
||||
|
||||
Assert.isTrue(query.getLimit() <= 1, "Query must not define a limit other than 1 ore none!");
|
||||
Assert.isTrue(query.getSkip() <= 0, "Query must not define skip.");
|
||||
Assert.isTrue(query.getLimit() <= 1, "Query must not define a limit other than 1 ore none");
|
||||
Assert.isTrue(query.getSkip() <= 0, "Query must not define skip");
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityType);
|
||||
QueryContext queryContext = queryOperations.createQueryContext(query);
|
||||
@@ -1007,9 +1058,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public <T> T findAndRemove(Query query, Class<T> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(),
|
||||
getMappedSortObject(query, entityClass), operations.forType(entityClass).getCollation(query).orElse(null),
|
||||
@@ -1019,7 +1070,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public long count(Query query, Class<?> entityClass) {
|
||||
|
||||
Assert.notNull(entityClass, "Entity class must not be null!");
|
||||
Assert.notNull(entityClass, "Entity class must not be null");
|
||||
return count(query, entityClass, getCollectionName(entityClass));
|
||||
}
|
||||
|
||||
@@ -1035,8 +1086,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public long count(Query query, @Nullable Class<?> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
|
||||
CountContext countContext = queryOperations.countQueryContext(query);
|
||||
|
||||
@@ -1103,7 +1154,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public <T> T insert(T objectToSave) {
|
||||
|
||||
Assert.notNull(objectToSave, "ObjectToSave must not be null!");
|
||||
Assert.notNull(objectToSave, "ObjectToSave must not be null");
|
||||
|
||||
ensureNotCollectionLike(objectToSave);
|
||||
return insert(objectToSave, getCollectionName(ClassUtils.getUserClass(objectToSave)));
|
||||
@@ -1113,8 +1164,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T insert(T objectToSave, String collectionName) {
|
||||
|
||||
Assert.notNull(objectToSave, "ObjectToSave must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(objectToSave, "ObjectToSave must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
ensureNotCollectionLike(objectToSave);
|
||||
return (T) doInsert(collectionName, objectToSave, this.mongoConverter);
|
||||
@@ -1130,7 +1181,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
protected void ensureNotCollectionLike(@Nullable Object source) {
|
||||
|
||||
if (EntityOperations.isCollectionLike(source)) {
|
||||
throw new IllegalArgumentException("Cannot use a collection here.");
|
||||
throw new IllegalArgumentException("Cannot use a collection here");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1202,7 +1253,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Collection<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass) {
|
||||
|
||||
Assert.notNull(batchToSave, "BatchToSave must not be null!");
|
||||
Assert.notNull(batchToSave, "BatchToSave must not be null");
|
||||
|
||||
return (Collection<T>) doInsertBatch(getCollectionName(entityClass), batchToSave, this.mongoConverter);
|
||||
}
|
||||
@@ -1211,8 +1262,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Collection<T> insert(Collection<? extends T> batchToSave, String collectionName) {
|
||||
|
||||
Assert.notNull(batchToSave, "BatchToSave must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(batchToSave, "BatchToSave must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
|
||||
return (Collection<T>) doInsertBatch(collectionName, batchToSave, this.mongoConverter);
|
||||
}
|
||||
@@ -1221,7 +1272,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Collection<T> insertAll(Collection<? extends T> objectsToSave) {
|
||||
|
||||
Assert.notNull(objectsToSave, "ObjectsToSave must not be null!");
|
||||
Assert.notNull(objectsToSave, "ObjectsToSave must not be null");
|
||||
return (Collection<T>) doInsertAll(objectsToSave, this.mongoConverter);
|
||||
}
|
||||
|
||||
@@ -1258,9 +1309,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
protected <T> Collection<T> doInsertBatch(String collectionName, Collection<? extends T> batchToSave,
|
||||
MongoWriter<T> writer) {
|
||||
|
||||
Assert.notNull(writer, "MongoWriter must not be null!");
|
||||
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) {
|
||||
|
||||
@@ -1303,7 +1354,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public <T> T save(T objectToSave) {
|
||||
|
||||
Assert.notNull(objectToSave, "Object to save must not be null!");
|
||||
Assert.notNull(objectToSave, "Object to save must not be null");
|
||||
return save(objectToSave, getCollectionName(ClassUtils.getUserClass(objectToSave)));
|
||||
}
|
||||
|
||||
@@ -1311,8 +1362,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T save(T objectToSave, String collectionName) {
|
||||
|
||||
Assert.notNull(objectToSave, "Object to save must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(objectToSave, "Object to save must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
ensureNotCollectionLike(objectToSave);
|
||||
|
||||
AdaptibleEntity<T> source = operations.forEntity(objectToSave, mongoConverter.getConversionService());
|
||||
@@ -1355,7 +1406,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
if (result.getModifiedCount() == 0) {
|
||||
|
||||
throw new OptimisticLockingFailureException(
|
||||
String.format("Cannot save entity %s with version %s to collection %s. Has it been modified meanwhile?",
|
||||
String.format("Cannot save entity %s with version %s to collection %s; Has it been modified meanwhile",
|
||||
source.getId(), source.getVersion(), collectionName));
|
||||
}
|
||||
maybeEmitEvent(new AfterSaveEvent<>(toSave, mapped.getDocument(), collectionName));
|
||||
@@ -1392,18 +1443,21 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
collectionName));
|
||||
}
|
||||
|
||||
MappedDocument mappedDocument = queryOperations.createInsertContext(MappedDocument.of(document))
|
||||
.prepareId(entityClass);
|
||||
|
||||
return execute(collectionName, collection -> {
|
||||
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT, collectionName, entityClass,
|
||||
document, null);
|
||||
mappedDocument.getDocument(), null);
|
||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||
|
||||
if (writeConcernToUse == null) {
|
||||
collection.insertOne(document);
|
||||
collection.insertOne(mappedDocument.getDocument());
|
||||
} else {
|
||||
collection.withWriteConcern(writeConcernToUse).insertOne(document);
|
||||
collection.withWriteConcern(writeConcernToUse).insertOne(mappedDocument.getDocument());
|
||||
}
|
||||
|
||||
return operations.forEntity(document).getId();
|
||||
return operations.forEntity(mappedDocument.getDocument()).getId();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1454,7 +1508,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
: collection.withWriteConcern(writeConcernToUse);
|
||||
|
||||
if (!mapped.hasId()) {
|
||||
collectionToUse.insertOne(dbDoc);
|
||||
|
||||
mapped = queryOperations.createInsertContext(mapped).prepareId(mappingContext.getPersistentEntity(entityClass));
|
||||
collectionToUse.insertOne(mapped.getDocument());
|
||||
} else {
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||
@@ -1492,7 +1548,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public UpdateResult upsert(Query query, UpdateDefinition update, Class<?> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
|
||||
return doUpdate(collectionName, query, update, entityClass, true, false);
|
||||
}
|
||||
@@ -1510,7 +1566,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public UpdateResult updateFirst(Query query, UpdateDefinition update, Class<?> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
|
||||
return doUpdate(collectionName, query, update, entityClass, false, false);
|
||||
}
|
||||
@@ -1528,7 +1584,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public UpdateResult updateMulti(Query query, UpdateDefinition update, Class<?> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
|
||||
return doUpdate(collectionName, query, update, entityClass, false, true);
|
||||
}
|
||||
@@ -1537,13 +1593,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
protected UpdateResult doUpdate(String collectionName, Query query, UpdateDefinition update,
|
||||
@Nullable Class<?> entityClass, boolean upsert, boolean multi) {
|
||||
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(update, "Update must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
|
||||
if (query.isSorted() && LOGGER.isWarnEnabled()) {
|
||||
|
||||
LOGGER.warn(String.format("%s does not support sort ('%s'). Please use findAndModify() instead.",
|
||||
LOGGER.warn(String.format("%s does not support sort ('%s'); Please use findAndModify() instead",
|
||||
upsert ? "Upsert" : "UpdateFirst", serializeToJsonSafely(query.getSortObject())));
|
||||
}
|
||||
|
||||
@@ -1616,7 +1672,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public DeleteResult remove(Object object) {
|
||||
|
||||
Assert.notNull(object, "Object must not be null!");
|
||||
Assert.notNull(object, "Object must not be null");
|
||||
|
||||
return remove(object, getCollectionName(object.getClass()));
|
||||
}
|
||||
@@ -1624,8 +1680,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public DeleteResult remove(Object object, String collectionName) {
|
||||
|
||||
Assert.notNull(object, "Object must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(object, "Object must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
|
||||
Query query = operations.forEntity(object).getRemoveByQuery();
|
||||
|
||||
@@ -1645,7 +1701,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public DeleteResult remove(Query query, Class<?> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
return doRemove(collectionName, query, entityClass, true);
|
||||
}
|
||||
|
||||
@@ -1653,8 +1709,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
protected <T> DeleteResult doRemove(String collectionName, Query query, @Nullable Class<T> entityClass,
|
||||
boolean multi) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
|
||||
MongoPersistentEntity<?> entity = getPersistentEntity(entityClass);
|
||||
|
||||
@@ -1764,11 +1820,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
public <T> List<T> mapReduce(Query query, Class<?> domainType, String inputCollectionName, String mapFunction,
|
||||
String reduceFunction, @Nullable MapReduceOptions mapReduceOptions, Class<T> resultType) {
|
||||
|
||||
Assert.notNull(domainType, "Domain type must not be null!");
|
||||
Assert.notNull(inputCollectionName, "Input collection name must not be null!");
|
||||
Assert.notNull(resultType, "Result type must not be null!");
|
||||
Assert.notNull(mapFunction, "Map function must not be null!");
|
||||
Assert.notNull(reduceFunction, "Reduce function must not be null!");
|
||||
Assert.notNull(domainType, "Domain type must not be null");
|
||||
Assert.notNull(inputCollectionName, "Input collection name must not be null");
|
||||
Assert.notNull(resultType, "Result type must not be null");
|
||||
Assert.notNull(mapFunction, "Map function must not be null");
|
||||
Assert.notNull(reduceFunction, "Reduce function must not be null");
|
||||
|
||||
String mapFunc = replaceWithResourceIfNecessary(mapFunction);
|
||||
String reduceFunc = replaceWithResourceIfNecessary(reduceFunction);
|
||||
@@ -1798,7 +1854,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
|
||||
Optionals.ifAllPresent(collation, mapReduceOptions.getCollation(), (l, r) -> {
|
||||
throw new IllegalArgumentException(
|
||||
"Both Query and MapReduceOptions define a collation. Please provide the collation only via one of the two.");
|
||||
"Both Query and MapReduceOptions define a collation; Please provide the collation only via one of the two.");
|
||||
});
|
||||
|
||||
if (mapReduceOptions.getCollation().isPresent()) {
|
||||
@@ -1854,21 +1910,21 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
|
||||
@Override
|
||||
public <O> AggregationResults<O> aggregate(TypedAggregation<?> aggregation, Class<O> outputType) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null");
|
||||
return aggregate(aggregation, getCollectionName(aggregation.getInputType()), outputType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <O> AggregationResults<O> aggregate(TypedAggregation<?> aggregation, String inputCollectionName,
|
||||
Class<O> outputType) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
|
||||
|
||||
return aggregate(aggregation, inputCollectionName, outputType, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <O> AggregationResults<O> aggregate(Aggregation aggregation, Class<?> inputType, Class<O> outputType) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null");
|
||||
return aggregate(aggregation, getCollectionName(inputType), outputType,
|
||||
queryOperations.createAggregation(aggregation, inputType).getAggregationOperationContext());
|
||||
}
|
||||
@@ -1881,24 +1937,22 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
@Override
|
||||
public <O> Stream<O> aggregateStream(TypedAggregation<?> aggregation, String inputCollectionName,
|
||||
Class<O> outputType) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
|
||||
|
||||
AggregationOperationContext context = new TypeBasedAggregationOperationContext(aggregation.getInputType(),
|
||||
mappingContext, queryMapper);
|
||||
return aggregateStream(aggregation, inputCollectionName, outputType, context);
|
||||
return aggregateStream(aggregation, inputCollectionName, outputType, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <O> Stream<O> aggregateStream(TypedAggregation<?> aggregation, Class<O> outputType) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null");
|
||||
return aggregateStream(aggregation, getCollectionName(aggregation.getInputType()), outputType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <O> Stream<O> aggregateStream(Aggregation aggregation, Class<?> inputType, Class<O> outputType) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null");
|
||||
return aggregateStream(aggregation, getCollectionName(inputType), outputType,
|
||||
new TypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper));
|
||||
queryOperations.createAggregation(aggregation, inputType).getAggregationOperationContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1949,9 +2003,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
protected <O> AggregationResults<O> aggregate(Aggregation aggregation, String collectionName, Class<O> outputType,
|
||||
@Nullable AggregationOperationContext context) {
|
||||
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
|
||||
Assert.notNull(outputType, "Output type must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null");
|
||||
Assert.notNull(outputType, "Output type must not be null");
|
||||
|
||||
return doAggregate(aggregation, collectionName, outputType,
|
||||
queryOperations.createAggregation(aggregation, context));
|
||||
@@ -2043,10 +2097,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
protected <O> Stream<O> aggregateStream(Aggregation aggregation, String collectionName, Class<O> outputType,
|
||||
@Nullable AggregationOperationContext context) {
|
||||
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
|
||||
Assert.notNull(outputType, "Output type must not be null!");
|
||||
Assert.isTrue(!aggregation.getOptions().isExplain(), "Can't use explain option with streaming!");
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
Assert.notNull(outputType, "Output type must not be null");
|
||||
Assert.isTrue(!aggregation.getOptions().isExplain(), "Can't use explain option with streaming");
|
||||
|
||||
AggregationDefinition aggregationDefinition = queryOperations.createAggregation(aggregation, context);
|
||||
|
||||
@@ -2123,7 +2177,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
Resource functionResource = resourceLoader.getResource(func);
|
||||
|
||||
if (!functionResource.exists()) {
|
||||
throw new InvalidDataAccessApiUsageException(String.format("Resource %s not found!", function));
|
||||
throw new InvalidDataAccessApiUsageException(String.format("Resource %s not found", function));
|
||||
}
|
||||
|
||||
Scanner scanner = null;
|
||||
@@ -2132,7 +2186,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
scanner = new Scanner(functionResource.getInputStream());
|
||||
return scanner.useDelimiter("\\A").next();
|
||||
} catch (IOException e) {
|
||||
throw new InvalidDataAccessApiUsageException(String.format("Cannot read map-reduce file %s!", function), e);
|
||||
throw new InvalidDataAccessApiUsageException(String.format("Cannot read map-reduce file %s", function), e);
|
||||
} finally {
|
||||
if (scanner != null) {
|
||||
scanner.close();
|
||||
@@ -2168,11 +2222,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
}
|
||||
|
||||
protected <E extends MongoMappingEvent<T>, T> E maybeEmitEvent(E event) {
|
||||
|
||||
if (eventPublisher != null) {
|
||||
eventPublisher.publishEvent(event);
|
||||
}
|
||||
|
||||
eventDelegate.publishEvent(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
@@ -2461,6 +2511,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
doc.put("timeseries", timeseries);
|
||||
});
|
||||
|
||||
collectionOptions.getChangeStreamOptions().map(it -> new Document("enabled", it.getPreAndPostImages()))
|
||||
.ifPresent(it -> {
|
||||
doc.put("changeStreamPreAndPostImages", it);
|
||||
});
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
@@ -2672,7 +2727,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();
|
||||
@@ -2809,8 +2865,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
|
||||
public FindCallback(Document query, Document fields, @Nullable com.mongodb.client.model.Collation collation) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(fields, "Fields must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(fields, "Fields must not be null");
|
||||
|
||||
this.query = query;
|
||||
this.fields = fields;
|
||||
@@ -3197,7 +3253,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
*/
|
||||
GeoNearResultDocumentCallback(String distanceField, DocumentCallback<T> delegate, Metric metric) {
|
||||
|
||||
Assert.notNull(delegate, "DocumentCallback must not be null!");
|
||||
Assert.notNull(delegate, "DocumentCallback must not be null");
|
||||
|
||||
this.distanceField = distanceField;
|
||||
this.delegate = delegate;
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.stream.Collectors;
|
||||
import org.bson.BsonValue;
|
||||
import org.bson.Document;
|
||||
import org.bson.codecs.Codec;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.mapping.PropertyPath;
|
||||
import org.springframework.data.mapping.PropertyReferenceException;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
@@ -46,6 +46,7 @@ import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOpe
|
||||
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.convert.UpdateMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoId;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.mapping.ShardKey;
|
||||
@@ -107,6 +108,14 @@ class QueryOperations {
|
||||
this.aggregationUtil = new AggregationUtil(queryMapper, mappingContext);
|
||||
}
|
||||
|
||||
InsertContext createInsertContext(Document source) {
|
||||
return createInsertContext(MappedDocument.of(source));
|
||||
}
|
||||
|
||||
InsertContext createInsertContext(MappedDocument mappedDocument) {
|
||||
return new InsertContext(mappedDocument);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link QueryContext} instance.
|
||||
*
|
||||
@@ -227,6 +236,57 @@ class QueryOperations {
|
||||
return new AggregationDefinition(aggregation, aggregationOperationContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link InsertContext} encapsulates common tasks required to interact with {@link Document} to be inserted.
|
||||
*
|
||||
* @since 3.4.3
|
||||
*/
|
||||
class InsertContext {
|
||||
|
||||
private final MappedDocument source;
|
||||
|
||||
private InsertContext(MappedDocument source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the {@literal _id} field. May generate a new {@literal id} value and convert it to the id properties
|
||||
* {@link MongoPersistentProperty#getFieldType() target type}.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return the {@link MappedDocument} containing the changes.
|
||||
* @see #prepareId(MongoPersistentEntity)
|
||||
*/
|
||||
<T> MappedDocument prepareId(Class<T> type) {
|
||||
return prepareId(mappingContext.getPersistentEntity(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the {@literal _id} field. May generate a new {@literal id} value and convert it to the id properties
|
||||
* {@link MongoPersistentProperty#getFieldType() target type}.
|
||||
*
|
||||
* @param entity can be {@literal null}.
|
||||
* @param <T>
|
||||
* @return the {@link MappedDocument} containing the changes.
|
||||
*/
|
||||
<T> MappedDocument prepareId(@Nullable MongoPersistentEntity<T> entity) {
|
||||
|
||||
if (entity == null || source.hasId()) {
|
||||
return source;
|
||||
}
|
||||
|
||||
MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
if (idProperty != null
|
||||
&& (idProperty.hasExplicitWriteTarget() || idProperty.isAnnotationPresent(MongoId.class))) {
|
||||
if (!ClassUtils.isAssignable(ObjectId.class, idProperty.getFieldType())) {
|
||||
source.updateId(queryMapper.convertId(new ObjectId(), idProperty.getFieldType()));
|
||||
}
|
||||
}
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link QueryContext} encapsulates common tasks required to convert a {@link Query} into its MongoDB document
|
||||
* representation, mapping field names, as well as determining and applying {@link Collation collations}.
|
||||
@@ -288,8 +348,7 @@ class QueryOperations {
|
||||
return queryMapper.getMappedObject(getQueryObject(), entity);
|
||||
}
|
||||
|
||||
Document getMappedFields(@Nullable MongoPersistentEntity<?> entity,
|
||||
EntityProjection<?, ?> projection) {
|
||||
Document getMappedFields(@Nullable MongoPersistentEntity<?> entity, EntityProjection<?, ?> projection) {
|
||||
|
||||
Document fields = evaluateFields(entity);
|
||||
|
||||
@@ -402,8 +461,7 @@ class QueryOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
Document getMappedFields(@Nullable MongoPersistentEntity<?> entity,
|
||||
EntityProjection<?, ?> projection) {
|
||||
Document getMappedFields(@Nullable MongoPersistentEntity<?> entity, EntityProjection<?, ?> projection) {
|
||||
return getMappedFields(entity);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class ReactiveAggregationOperationSupport implements ReactiveAggregationOperatio
|
||||
*/
|
||||
ReactiveAggregationOperationSupport(ReactiveMongoTemplate template) {
|
||||
|
||||
Assert.notNull(template, "Template must not be null!");
|
||||
Assert.notNull(template, "Template must not be null");
|
||||
|
||||
this.template = template;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ class ReactiveAggregationOperationSupport implements ReactiveAggregationOperatio
|
||||
@Override
|
||||
public <T> ReactiveAggregation<T> aggregateAndReturn(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ReactiveAggregationSupport<>(template, domainType, null, null);
|
||||
}
|
||||
@@ -74,7 +74,7 @@ class ReactiveAggregationOperationSupport implements ReactiveAggregationOperatio
|
||||
@Override
|
||||
public AggregationOperationWithAggregation<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection must not be null nor empty");
|
||||
|
||||
return new ReactiveAggregationSupport<>(template, domainType, aggregation, collection);
|
||||
}
|
||||
@@ -82,7 +82,7 @@ class ReactiveAggregationOperationSupport implements ReactiveAggregationOperatio
|
||||
@Override
|
||||
public TerminatingAggregationOperation<T> by(Aggregation aggregation) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation must not be null!");
|
||||
Assert.notNull(aggregation, "Aggregation must not be null");
|
||||
|
||||
return new ReactiveAggregationSupport<>(template, domainType, aggregation, collection);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
||||
@Override
|
||||
public <T> ReactiveChangeStream<T> changeStream(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
return new ReactiveChangeStreamSupport<>(template, domainType, domainType, null, null);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
||||
@Override
|
||||
public ChangeStreamWithFilterAndProjection<T> watchCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection name must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection name must not be null nor empty");
|
||||
|
||||
return new ReactiveChangeStreamSupport<>(template, domainType, returnType, collection, options);
|
||||
}
|
||||
@@ -83,7 +83,7 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
||||
@Override
|
||||
public ChangeStreamWithFilterAndProjection<T> watchCollection(Class<?> entityClass) {
|
||||
|
||||
Assert.notNull(entityClass, "Collection type not be null!");
|
||||
Assert.notNull(entityClass, "Collection type not be null");
|
||||
|
||||
return watchCollection(template.getCollectionName(entityClass));
|
||||
}
|
||||
@@ -129,7 +129,7 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
||||
@Override
|
||||
public <R> ChangeStreamWithFilterAndProjection<R> as(Class<R> resultType) {
|
||||
|
||||
Assert.notNull(resultType, "ResultType must not be null!");
|
||||
Assert.notNull(resultType, "ResultType must not be null");
|
||||
|
||||
return new ReactiveChangeStreamSupport<>(template, domainType, resultType, collection, options);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
||||
@Override
|
||||
public <T> ReactiveFind<T> query(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ReactiveFindSupport<>(template, domainType, domainType, null, ALL_QUERY);
|
||||
}
|
||||
@@ -80,7 +80,7 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
||||
@Override
|
||||
public FindWithProjection<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection name must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection name must not be null nor empty");
|
||||
|
||||
return new ReactiveFindSupport<>(template, domainType, returnType, collection, query);
|
||||
}
|
||||
@@ -88,7 +88,7 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
||||
@Override
|
||||
public <T1> FindWithQuery<T1> as(Class<T1> returnType) {
|
||||
|
||||
Assert.notNull(returnType, "ReturnType must not be null!");
|
||||
Assert.notNull(returnType, "ReturnType must not be null");
|
||||
|
||||
return new ReactiveFindSupport<>(template, domainType, returnType, collection, query);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
||||
@Override
|
||||
public TerminatingFind<T> matching(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
return new ReactiveFindSupport<>(template, domainType, returnType, collection, query);
|
||||
}
|
||||
@@ -124,7 +124,7 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
||||
|
||||
if (it.size() > 1) {
|
||||
return Mono.error(
|
||||
new IncorrectResultSizeDataAccessException("Query " + asString() + " returned non unique result.", 1));
|
||||
new IncorrectResultSizeDataAccessException("Query " + asString() + " returned non unique result", 1));
|
||||
}
|
||||
|
||||
return Mono.just(it.get(0));
|
||||
@@ -159,7 +159,7 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
||||
@Override
|
||||
public TerminatingDistinct<Object> distinct(String field) {
|
||||
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(field, "Field must not be null");
|
||||
|
||||
return new DistinctOperationSupport<>(this, field);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
||||
@Override
|
||||
public <R> TerminatingDistinct<R> as(Class<R> resultType) {
|
||||
|
||||
Assert.notNull(resultType, "ResultType must not be null!");
|
||||
Assert.notNull(resultType, "ResultType must not be null");
|
||||
|
||||
return new DistinctOperationSupport<>((ReactiveFindSupport) delegate.as(resultType), field);
|
||||
}
|
||||
@@ -219,7 +219,7 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
||||
@SuppressWarnings("unchecked")
|
||||
public TerminatingDistinct<T> matching(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
return new DistinctOperationSupport<>((ReactiveFindSupport<T>) delegate.matching(query), field);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class ReactiveInsertOperationSupport implements ReactiveInsertOperation {
|
||||
@Override
|
||||
public <T> ReactiveInsert<T> insert(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ReactiveInsertSupport<>(template, domainType, null);
|
||||
}
|
||||
@@ -62,7 +62,7 @@ class ReactiveInsertOperationSupport implements ReactiveInsertOperation {
|
||||
@Override
|
||||
public Mono<T> one(T object) {
|
||||
|
||||
Assert.notNull(object, "Object must not be null!");
|
||||
Assert.notNull(object, "Object must not be null");
|
||||
|
||||
return template.insert(object, getCollectionName());
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class ReactiveInsertOperationSupport implements ReactiveInsertOperation {
|
||||
@Override
|
||||
public Flux<T> all(Collection<? extends T> objects) {
|
||||
|
||||
Assert.notNull(objects, "Objects must not be null!");
|
||||
Assert.notNull(objects, "Objects must not be null");
|
||||
|
||||
return template.insert(objects, getCollectionName());
|
||||
}
|
||||
@@ -78,7 +78,7 @@ class ReactiveInsertOperationSupport implements ReactiveInsertOperation {
|
||||
@Override
|
||||
public ReactiveInsert<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection must not be null nor empty.");
|
||||
Assert.hasText(collection, "Collection must not be null nor empty");
|
||||
|
||||
return new ReactiveInsertSupport<>(template, domainType, collection);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class ReactiveMapReduceOperationSupport implements ReactiveMapReduceOperation {
|
||||
@Override
|
||||
public <T> ReactiveMapReduceSupport<T> mapReduce(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ReactiveMapReduceSupport<>(template, domainType, domainType, null, ALL_QUERY, null, null, null);
|
||||
}
|
||||
@@ -100,7 +100,7 @@ class ReactiveMapReduceOperationSupport implements ReactiveMapReduceOperation {
|
||||
@Override
|
||||
public MapReduceWithProjection<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection name must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection name must not be null nor empty");
|
||||
|
||||
return new ReactiveMapReduceSupport<>(template, domainType, returnType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
@@ -113,7 +113,7 @@ class ReactiveMapReduceOperationSupport implements ReactiveMapReduceOperation {
|
||||
@Override
|
||||
public TerminatingMapReduce<T> matching(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
return new ReactiveMapReduceSupport<>(template, domainType, returnType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
@@ -126,7 +126,7 @@ class ReactiveMapReduceOperationSupport implements ReactiveMapReduceOperation {
|
||||
@Override
|
||||
public <R> MapReduceWithQuery<R> as(Class<R> resultType) {
|
||||
|
||||
Assert.notNull(resultType, "ResultType must not be null!");
|
||||
Assert.notNull(resultType, "ResultType must not be null");
|
||||
|
||||
return new ReactiveMapReduceSupport<>(template, domainType, resultType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
@@ -139,7 +139,7 @@ class ReactiveMapReduceOperationSupport implements ReactiveMapReduceOperation {
|
||||
@Override
|
||||
public ReactiveMapReduce<T> with(MapReduceOptions options) {
|
||||
|
||||
Assert.notNull(options, "Options must not be null! Please consider empty MapReduceOptions#options() instead.");
|
||||
Assert.notNull(options, "Options must not be null Please consider empty MapReduceOptions#options() instead");
|
||||
|
||||
return new ReactiveMapReduceSupport<>(template, domainType, returnType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
@@ -152,7 +152,7 @@ class ReactiveMapReduceOperationSupport implements ReactiveMapReduceOperation {
|
||||
@Override
|
||||
public MapReduceWithReduceFunction<T> map(String mapFunction) {
|
||||
|
||||
Assert.hasText(mapFunction, "MapFunction name must not be null nor empty!");
|
||||
Assert.hasText(mapFunction, "MapFunction name must not be null nor empty");
|
||||
|
||||
return new ReactiveMapReduceSupport<>(template, domainType, returnType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
@@ -165,7 +165,7 @@ class ReactiveMapReduceOperationSupport implements ReactiveMapReduceOperation {
|
||||
@Override
|
||||
public ReactiveMapReduce<T> reduce(String reduceFunction) {
|
||||
|
||||
Assert.hasText(reduceFunction, "ReduceFunction name must not be null nor empty!");
|
||||
Assert.hasText(reduceFunction, "ReduceFunction name must not be null nor empty");
|
||||
|
||||
return new ReactiveMapReduceSupport<>(template, domainType, returnType, collection, query, mapFunction,
|
||||
reduceFunction, options);
|
||||
|
||||
@@ -115,7 +115,7 @@ public class ReactiveMongoClientFactoryBean extends AbstractFactoryBean<MongoCli
|
||||
}
|
||||
|
||||
throw new IllegalStateException(
|
||||
"Cannot create MongoClients. One of the following is required: mongoClientSettings, connectionString or host/port");
|
||||
"Cannot create MongoClients; One of the following is required: mongoClientSettings, connectionString or host/port");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -70,8 +70,8 @@ public class ReactiveMongoContext {
|
||||
*/
|
||||
public static Context setSession(Context context, Publisher<ClientSession> session) {
|
||||
|
||||
Assert.notNull(context, "Context must not be null!");
|
||||
Assert.notNull(session, "Session publisher must not be null!");
|
||||
Assert.notNull(context, "Context must not be null");
|
||||
Assert.notNull(session, "Session publisher must not be null");
|
||||
|
||||
return context.put(SESSION_KEY, Mono.from(session));
|
||||
}
|
||||
|
||||
@@ -25,10 +25,13 @@ import java.util.function.Supplier;
|
||||
import org.bson.Document;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscription;
|
||||
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationPipeline;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationUpdate;
|
||||
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
@@ -164,7 +167,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
||||
*/
|
||||
default ReactiveSessionScoped withSession(Supplier<ClientSession> sessionProvider) {
|
||||
|
||||
Assert.notNull(sessionProvider, "SessionProvider must not be null!");
|
||||
Assert.notNull(sessionProvider, "SessionProvider must not be null");
|
||||
|
||||
return withSession(Mono.fromSupplier(sessionProvider));
|
||||
}
|
||||
@@ -240,6 +243,56 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
||||
*/
|
||||
Mono<MongoCollection<Document>> createCollection(String collectionName, CollectionOptions collectionOptions);
|
||||
|
||||
/**
|
||||
* Create a view with the provided name. The view content is defined by the {@link AggregationOperation pipeline
|
||||
* stages} on another collection or view identified by the given {@link #getCollectionName(Class) source type}.
|
||||
*
|
||||
* @param name the name of the view to create.
|
||||
* @param source the type defining the views source collection.
|
||||
* @param stages the {@link AggregationOperation aggregation pipeline stages} defining the view content.
|
||||
* @since 4.0
|
||||
*/
|
||||
default Mono<MongoCollection<Document>> createView(String name, Class<?> source, AggregationOperation... stages) {
|
||||
return createView(name, source, AggregationPipeline.of(stages));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a view with the provided name. The view content is defined by the {@link AggregationPipeline pipeline} on
|
||||
* another collection or view identified by the given {@link #getCollectionName(Class) source type}.
|
||||
*
|
||||
* @param name the name of the view to create.
|
||||
* @param source the type defining the views source collection.
|
||||
* @param pipeline the {@link AggregationPipeline} defining the view content.
|
||||
* @since 4.0
|
||||
*/
|
||||
default Mono<MongoCollection<Document>> createView(String name, Class<?> source, AggregationPipeline pipeline) {
|
||||
return createView(name, source, pipeline, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a view with the provided name. The view content is defined by the {@link AggregationPipeline pipeline} on
|
||||
* another collection or view identified by the given {@link #getCollectionName(Class) source type}.
|
||||
*
|
||||
* @param name the name of the view to create.
|
||||
* @param source the type defining the views source collection.
|
||||
* @param pipeline the {@link AggregationPipeline} defining the view content.
|
||||
* @param options additional settings to apply when creating the view. Can be {@literal null}.
|
||||
* @since 4.0
|
||||
*/
|
||||
Mono<MongoCollection<Document>> createView(String name, Class<?> source, AggregationPipeline pipeline, @Nullable ViewOptions options);
|
||||
|
||||
/**
|
||||
* Create a view with the provided name. The view content is defined by the {@link AggregationPipeline pipeline} on
|
||||
* another collection or view identified by the given source.
|
||||
*
|
||||
* @param name the name of the view to create.
|
||||
* @param source the name of the collection or view defining the to be created views source.
|
||||
* @param pipeline the {@link AggregationPipeline} defining the view content.
|
||||
* @param options additional settings to apply when creating the view. Can be {@literal null}.
|
||||
* @since 4.0
|
||||
*/
|
||||
Mono<MongoCollection<Document>> createView(String name, String source, AggregationPipeline pipeline, @Nullable ViewOptions options);
|
||||
|
||||
/**
|
||||
* A set of collection names.
|
||||
*
|
||||
@@ -693,6 +746,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) {
|
||||
@@ -732,6 +787,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) {
|
||||
@@ -756,7 +813,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
||||
*/
|
||||
default <T> Mono<T> findAndReplace(Query query, T replacement, FindAndReplaceOptions options, String collectionName) {
|
||||
|
||||
Assert.notNull(replacement, "Replacement must not be null!");
|
||||
Assert.notNull(replacement, "Replacement must not be null");
|
||||
return findAndReplace(query, replacement, options, (Class<T>) ClassUtils.getUserClass(replacement), collectionName);
|
||||
}
|
||||
|
||||
@@ -802,6 +859,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,
|
||||
@@ -882,6 +941,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.
|
||||
* @see #exactCount(Query, Class)
|
||||
* @see #estimatedCount(Class)
|
||||
*/
|
||||
@@ -937,11 +998,13 @@ 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) {
|
||||
|
||||
Assert.notNull(entityClass, "Entity class must not be null!");
|
||||
Assert.notNull(entityClass, "Entity class must not be null");
|
||||
return estimatedCount(getCollectionName(entityClass));
|
||||
}
|
||||
|
||||
@@ -973,6 +1036,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.
|
||||
* @since 3.4
|
||||
*/
|
||||
default Mono<Long> exactCount(Query query, Class<?> entityClass) {
|
||||
@@ -1028,9 +1093,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
||||
/**
|
||||
* Insert the object into the collection for the entity type of the object to save. <br />
|
||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. <br />
|
||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
||||
* String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from ObjectId to your
|
||||
* property type will be handled by Spring's BeanWrapper class that leverages Type Conversion API. See
|
||||
* If your object has an {@literal Id} property which holds a {@literal null} value, it will be set with the generated
|
||||
* Id from MongoDB. If your Id property is a String then MongoDB ObjectId will be used to populate that string.
|
||||
* Otherwise, the conversion from ObjectId to your property type will be handled by Spring's BeanWrapper class that
|
||||
* leverages Type Conversion API. See
|
||||
* <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation" > Spring's
|
||||
* Type Conversion"</a> for more details. <br />
|
||||
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
||||
@@ -1040,6 +1106,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);
|
||||
|
||||
@@ -1063,7 +1131,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);
|
||||
|
||||
@@ -1082,6 +1152,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);
|
||||
|
||||
@@ -1106,6 +1178,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);
|
||||
|
||||
@@ -1142,6 +1216,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);
|
||||
|
||||
@@ -1176,6 +1252,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);
|
||||
|
||||
@@ -1208,6 +1286,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
|
||||
@@ -1262,6 +1342,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
|
||||
@@ -1317,6 +1399,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
|
||||
*/
|
||||
@@ -1363,6 +1447,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);
|
||||
|
||||
@@ -1380,6 +1466,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);
|
||||
|
||||
@@ -1393,17 +1481,19 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
||||
Mono<DeleteResult> remove(Mono<? extends Object> objectToRemove, String collectionName);
|
||||
|
||||
/**
|
||||
* Remove all documents that match the provided query document criteria from the the collection used to store the
|
||||
* Remove all documents that match the provided query document criteria from the collection used to store the
|
||||
* entityClass. The Class parameter is also used to help convert the Id of the object if it is present in the query.
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Remove all documents that match the provided query document criteria from the the collection used to store the
|
||||
* Remove all documents that match the provided query document criteria from the collection used to store the
|
||||
* entityClass. The Class parameter is also used to help convert the Id of the object if it is present in the query.
|
||||
*
|
||||
* @param query the query document that specifies the criteria used to remove a record.
|
||||
@@ -1442,13 +1532,15 @@ 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);
|
||||
|
||||
/**
|
||||
* Returns and removes all documents that match the provided query document criteria from the the collection used to
|
||||
* store the entityClass. The Class parameter is also used to help convert the Id of the object if it is present in
|
||||
* the query.
|
||||
* Returns and removes all documents that match the provided query document criteria from the collection used to store
|
||||
* the entityClass. The Class parameter is also used to help convert the Id of the object if it is present in the
|
||||
* query.
|
||||
*
|
||||
* @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.
|
||||
@@ -1471,6 +1563,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);
|
||||
|
||||
@@ -1611,6 +1705,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);
|
||||
|
||||
@@ -46,7 +46,6 @@ import org.bson.conversions.Bson;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscriber;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -81,6 +80,7 @@ import org.springframework.data.mongodb.core.QueryOperations.UpdateContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationPipeline;
|
||||
import org.springframework.data.mongodb.core.aggregation.PrefixingDelegatingAggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
|
||||
@@ -127,16 +127,7 @@ import com.mongodb.CursorType;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadPreference;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.client.model.CountOptions;
|
||||
import com.mongodb.client.model.CreateCollectionOptions;
|
||||
import com.mongodb.client.model.DeleteOptions;
|
||||
import com.mongodb.client.model.EstimatedDocumentCountOptions;
|
||||
import com.mongodb.client.model.FindOneAndDeleteOptions;
|
||||
import com.mongodb.client.model.FindOneAndReplaceOptions;
|
||||
import com.mongodb.client.model.FindOneAndUpdateOptions;
|
||||
import com.mongodb.client.model.ReplaceOptions;
|
||||
import com.mongodb.client.model.ReturnDocument;
|
||||
import com.mongodb.client.model.UpdateOptions;
|
||||
import com.mongodb.client.model.*;
|
||||
import com.mongodb.client.model.changestream.FullDocument;
|
||||
import com.mongodb.client.result.DeleteResult;
|
||||
import com.mongodb.client.result.InsertOneResult;
|
||||
@@ -185,6 +176,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
private final EntityOperations operations;
|
||||
private final PropertyOperations propertyOperations;
|
||||
private final QueryOperations queryOperations;
|
||||
private final EntityLifecycleEventDelegate eventDelegate;
|
||||
|
||||
private @Nullable WriteConcern writeConcern;
|
||||
private WriteConcernResolver writeConcernResolver = DefaultWriteConcernResolver.INSTANCE;
|
||||
@@ -241,7 +233,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
public ReactiveMongoTemplate(ReactiveMongoDatabaseFactory mongoDatabaseFactory,
|
||||
@Nullable MongoConverter mongoConverter, Consumer<Throwable> subscriptionExceptionHandler) {
|
||||
|
||||
Assert.notNull(mongoDatabaseFactory, "ReactiveMongoDatabaseFactory must not be null!");
|
||||
Assert.notNull(mongoDatabaseFactory, "ReactiveMongoDatabaseFactory must not be null");
|
||||
|
||||
this.mongoDatabaseFactory = mongoDatabaseFactory;
|
||||
this.exceptionTranslator = mongoDatabaseFactory.getExceptionTranslator();
|
||||
@@ -256,6 +248,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
this.propertyOperations = new PropertyOperations(this.mongoConverter.getMappingContext());
|
||||
this.queryOperations = new QueryOperations(queryMapper, updateMapper, operations, propertyOperations,
|
||||
mongoDatabaseFactory);
|
||||
this.eventDelegate = new EntityLifecycleEventDelegate();
|
||||
|
||||
// We create indexes based on mapping events
|
||||
if (this.mappingContext instanceof MongoMappingContext) {
|
||||
@@ -287,6 +280,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
this.propertyOperations = that.propertyOperations;
|
||||
this.sessionSynchronization = that.sessionSynchronization;
|
||||
this.queryOperations = that.queryOperations;
|
||||
this.eventDelegate = that.eventDelegate;
|
||||
}
|
||||
|
||||
private void onCheckForIndexes(MongoPersistentEntity<?> entity, Consumer<Throwable> subscriptionExceptionHandler) {
|
||||
@@ -339,12 +333,25 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
this.readPreference = readPreference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure whether lifecycle events such as {@link AfterLoadEvent}, {@link BeforeSaveEvent}, etc. should be
|
||||
* published or whether emission should be suppressed. Enabled by default.
|
||||
*
|
||||
* @param enabled {@code true} to enable entity lifecycle events; {@code false} to disable entity lifecycle events.
|
||||
* @since 4.0
|
||||
* @see MongoMappingEvent
|
||||
*/
|
||||
public void setEntityLifecycleEventsEnabled(boolean enabled) {
|
||||
this.eventDelegate.setEventsEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
prepareIndexCreator(applicationContext);
|
||||
|
||||
eventPublisher = applicationContext;
|
||||
eventDelegate.setPublisher(eventPublisher);
|
||||
|
||||
if (entityCallbacks == null) {
|
||||
setEntityCallbacks(ReactiveEntityCallbacks.create(applicationContext));
|
||||
@@ -367,7 +374,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
*/
|
||||
public void setEntityCallbacks(ReactiveEntityCallbacks entityCallbacks) {
|
||||
|
||||
Assert.notNull(entityCallbacks, "EntityCallbacks must not be null!");
|
||||
Assert.notNull(entityCallbacks, "EntityCallbacks must not be null");
|
||||
this.entityCallbacks = entityCallbacks;
|
||||
}
|
||||
|
||||
@@ -468,7 +475,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public Mono<Document> executeCommand(String jsonCommand) {
|
||||
|
||||
Assert.notNull(jsonCommand, "Command must not be empty!");
|
||||
Assert.notNull(jsonCommand, "Command must not be empty");
|
||||
|
||||
return executeCommand(Document.parse(jsonCommand));
|
||||
}
|
||||
@@ -481,7 +488,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public Mono<Document> executeCommand(Document command, @Nullable ReadPreference readPreference) {
|
||||
|
||||
Assert.notNull(command, "Command must not be null!");
|
||||
Assert.notNull(command, "Command must not be null");
|
||||
|
||||
return createFlux(db -> readPreference != null ? db.runCommand(command, readPreference, Document.class)
|
||||
: db.runCommand(command, Document.class)).next();
|
||||
@@ -500,7 +507,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public <T> Flux<T> execute(String collectionName, ReactiveCollectionCallback<T> callback) {
|
||||
|
||||
Assert.notNull(callback, "ReactiveCollectionCallback must not be null!");
|
||||
Assert.notNull(callback, "ReactiveCollectionCallback must not be null");
|
||||
|
||||
return createFlux(collectionName, callback);
|
||||
}
|
||||
@@ -565,7 +572,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
*/
|
||||
public <T> Flux<T> createFlux(ReactiveDatabaseCallback<T> callback) {
|
||||
|
||||
Assert.notNull(callback, "ReactiveDatabaseCallback must not be null!");
|
||||
Assert.notNull(callback, "ReactiveDatabaseCallback must not be null");
|
||||
|
||||
return Mono.defer(this::doGetDatabase).flatMapMany(database -> callback.doInDB(prepareDatabase(database)))
|
||||
.onErrorMap(translateException());
|
||||
@@ -580,7 +587,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
*/
|
||||
public <T> Mono<T> createMono(ReactiveDatabaseCallback<T> callback) {
|
||||
|
||||
Assert.notNull(callback, "ReactiveDatabaseCallback must not be null!");
|
||||
Assert.notNull(callback, "ReactiveDatabaseCallback must not be null");
|
||||
|
||||
return Mono.defer(this::doGetDatabase).flatMap(database -> Mono.from(callback.doInDB(prepareDatabase(database))))
|
||||
.onErrorMap(translateException());
|
||||
@@ -595,8 +602,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
*/
|
||||
public <T> Flux<T> createFlux(String collectionName, ReactiveCollectionCallback<T> callback) {
|
||||
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(callback, "ReactiveDatabaseCallback must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
Assert.notNull(callback, "ReactiveDatabaseCallback must not be null");
|
||||
|
||||
Mono<MongoCollection<Document>> collectionPublisher = doGetDatabase()
|
||||
.map(database -> getAndPrepareCollection(database, collectionName));
|
||||
@@ -614,8 +621,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
*/
|
||||
public <T> Mono<T> createMono(String collectionName, ReactiveCollectionCallback<T> callback) {
|
||||
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(callback, "ReactiveCollectionCallback must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
Assert.notNull(callback, "ReactiveCollectionCallback must not be null");
|
||||
|
||||
Mono<MongoCollection<Document>> collectionPublisher = doGetDatabase()
|
||||
.map(database -> getAndPrepareCollection(database, collectionName));
|
||||
@@ -633,7 +640,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
public <T> Mono<MongoCollection<Document>> createCollection(Class<T> entityClass,
|
||||
@Nullable CollectionOptions collectionOptions) {
|
||||
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
|
||||
CollectionOptions options = collectionOptions != null ? collectionOptions : CollectionOptions.empty();
|
||||
options = Optionals
|
||||
@@ -655,10 +662,47 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
return doCreateCollection(collectionName, convertToCreateCollectionOptions(collectionOptions));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<MongoCollection<Document>> createView(String name, Class<?> source, AggregationPipeline pipeline,
|
||||
@Nullable ViewOptions options) {
|
||||
|
||||
return createView(name, getCollectionName(source),
|
||||
queryOperations.createAggregation(Aggregation.newAggregation(source, pipeline.getOperations()), source),
|
||||
options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<MongoCollection<Document>> createView(String name, String source, AggregationPipeline pipeline,
|
||||
@Nullable ViewOptions options) {
|
||||
|
||||
return createView(name, source,
|
||||
queryOperations.createAggregation(Aggregation.newAggregation(pipeline.getOperations()), (Class<?>) null),
|
||||
options);
|
||||
}
|
||||
|
||||
private Mono<MongoCollection<Document>> createView(String name, String source, AggregationDefinition aggregation,
|
||||
@Nullable ViewOptions options) {
|
||||
return doCreateView(name, source, aggregation.getAggregationPipeline(), options);
|
||||
}
|
||||
|
||||
protected Mono<MongoCollection<Document>> doCreateView(String name, String source, List<Document> pipeline,
|
||||
@Nullable ViewOptions options) {
|
||||
|
||||
CreateViewOptions viewOptions = new CreateViewOptions();
|
||||
if (options != null) {
|
||||
options.getCollation().map(Collation::toMongoCollation).ifPresent(viewOptions::collation);
|
||||
}
|
||||
|
||||
return execute(db -> {
|
||||
return Flux.from(db.createView(name, source, pipeline, viewOptions))
|
||||
.then(Mono.fromSupplier(() -> db.getCollection(name)));
|
||||
}).next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<MongoCollection<Document>> getCollection(String collectionName) {
|
||||
|
||||
Assert.notNull(collectionName, "Collection name must not be null!");
|
||||
Assert.notNull(collectionName, "Collection name must not be null");
|
||||
|
||||
return createMono(db -> Mono.just(db.getCollection(collectionName)));
|
||||
}
|
||||
@@ -795,11 +839,11 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
public <T> Flux<T> findDistinct(Query query, String field, String collectionName, Class<?> entityClass,
|
||||
Class<T> resultClass) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null!");
|
||||
Assert.notNull(resultClass, "ResultClass must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(field, "Field must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
Assert.notNull(entityClass, "EntityClass must not be null");
|
||||
Assert.notNull(resultClass, "ResultClass must not be null");
|
||||
|
||||
MongoPersistentEntity<?> entity = getPersistentEntity(entityClass);
|
||||
DistinctQueryContext distinctQueryContext = queryOperations.distinctQueryContext(query, field);
|
||||
@@ -839,13 +883,14 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public <O> Flux<O> aggregate(TypedAggregation<?> aggregation, String inputCollectionName, Class<O> outputType) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null");
|
||||
return doAggregate(aggregation, inputCollectionName, aggregation.getInputType(), outputType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <O> Flux<O> aggregate(TypedAggregation<?> aggregation, Class<O> outputType) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null");
|
||||
return aggregate(aggregation, getCollectionName(aggregation.getInputType()), outputType);
|
||||
}
|
||||
|
||||
@@ -862,12 +907,12 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
protected <O> Flux<O> doAggregate(Aggregation aggregation, String collectionName, @Nullable Class<?> inputType,
|
||||
Class<O> outputType) {
|
||||
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(outputType, "Output type must not be null!");
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
Assert.notNull(outputType, "Output type must not be null");
|
||||
|
||||
AggregationOptions options = aggregation.getOptions();
|
||||
Assert.isTrue(!options.isExplain(), "Cannot use explain option with streaming!");
|
||||
Assert.isTrue(!options.isExplain(), "Cannot use explain option with streaming");
|
||||
|
||||
AggregationDefinition ctx = queryOperations.createAggregation(aggregation, inputType);
|
||||
|
||||
@@ -925,11 +970,11 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
Class<T> returnType) {
|
||||
|
||||
if (near == null) {
|
||||
throw new InvalidDataAccessApiUsageException("NearQuery must not be null!");
|
||||
throw new InvalidDataAccessApiUsageException("NearQuery must not be null");
|
||||
}
|
||||
|
||||
if (entityClass == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Entity class must not be null!");
|
||||
throw new InvalidDataAccessApiUsageException("Entity class must not be null");
|
||||
}
|
||||
|
||||
String collection = StringUtils.hasText(collectionName) ? collectionName : getCollectionName(entityClass);
|
||||
@@ -966,14 +1011,14 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
public <T> Mono<T> findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options,
|
||||
Class<T> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(options, "Options must not be null! ");
|
||||
Assert.notNull(entityClass, "Entity class must not be null!");
|
||||
Assert.notNull(options, "Options must not be null ");
|
||||
Assert.notNull(entityClass, "Entity class must not be null");
|
||||
|
||||
FindAndModifyOptions optionsToUse = FindAndModifyOptions.of(options);
|
||||
|
||||
Optionals.ifAllPresent(query.getCollation(), optionsToUse.getCollation(), (l, r) -> {
|
||||
throw new IllegalArgumentException(
|
||||
"Both Query and FindAndModifyOptions define a collation. Please provide the collation only via one of the two.");
|
||||
"Both Query and FindAndModifyOptions define a collation; Please provide the collation only via one of the two");
|
||||
});
|
||||
|
||||
if (!optionsToUse.getCollation().isPresent()) {
|
||||
@@ -988,15 +1033,15 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
public <S, T> Mono<T> findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class<S> entityType,
|
||||
String collectionName, Class<T> resultType) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(replacement, "Replacement must not be null!");
|
||||
Assert.notNull(options, "Options must not be null! Use FindAndReplaceOptions#empty() instead.");
|
||||
Assert.notNull(entityType, "Entity class must not be null!");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
Assert.notNull(resultType, "ResultType must not be null! Use Object.class instead.");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(replacement, "Replacement must not be null");
|
||||
Assert.notNull(options, "Options must not be null Use FindAndReplaceOptions#empty() instead");
|
||||
Assert.notNull(entityType, "Entity class must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
Assert.notNull(resultType, "ResultType must not be null Use Object.class instead");
|
||||
|
||||
Assert.isTrue(query.getLimit() <= 1, "Query must not define a limit other than 1 ore none!");
|
||||
Assert.isTrue(query.getSkip() <= 0, "Query must not define skip.");
|
||||
Assert.isTrue(query.getLimit() <= 1, "Query must not define a limit other than 1 ore none");
|
||||
Assert.isTrue(query.getSkip() <= 0, "Query must not define skip");
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityType);
|
||||
QueryContext queryContext = queryOperations.createQueryContext(query);
|
||||
@@ -1053,7 +1098,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public Mono<Long> count(Query query, Class<?> entityClass) {
|
||||
|
||||
Assert.notNull(entityClass, "Entity class must not be null!");
|
||||
Assert.notNull(entityClass, "Entity class must not be null");
|
||||
|
||||
return count(query, entityClass, getCollectionName(entityClass));
|
||||
}
|
||||
@@ -1066,8 +1111,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public Mono<Long> count(Query query, @Nullable Class<?> entityClass, String collectionName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
|
||||
return createMono(collectionName, collection -> {
|
||||
|
||||
@@ -1152,7 +1197,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public <T> Mono<T> insert(Mono<? extends T> objectToSave) {
|
||||
|
||||
Assert.notNull(objectToSave, "Mono to insert must not be null!");
|
||||
Assert.notNull(objectToSave, "Mono to insert must not be null");
|
||||
|
||||
return objectToSave.flatMap(this::insert);
|
||||
}
|
||||
@@ -1165,7 +1210,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public <T> Flux<T> insertAll(Mono<? extends Collection<? extends T>> batchToSave, String collectionName) {
|
||||
|
||||
Assert.notNull(batchToSave, "Batch to insert must not be null!");
|
||||
Assert.notNull(batchToSave, "Batch to insert must not be null");
|
||||
|
||||
return Flux.from(batchToSave).flatMap(collection -> insert(collection, collectionName));
|
||||
}
|
||||
@@ -1173,7 +1218,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public <T> Mono<T> insert(T objectToSave) {
|
||||
|
||||
Assert.notNull(objectToSave, "Object to insert must not be null!");
|
||||
Assert.notNull(objectToSave, "Object to insert must not be null");
|
||||
|
||||
ensureNotCollectionLike(objectToSave);
|
||||
return insert(objectToSave, getCollectionName(ClassUtils.getUserClass(objectToSave)));
|
||||
@@ -1182,7 +1227,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public <T> Mono<T> insert(T objectToSave, String collectionName) {
|
||||
|
||||
Assert.notNull(objectToSave, "Object to insert must not be null!");
|
||||
Assert.notNull(objectToSave, "Object to insert must not be null");
|
||||
|
||||
ensureNotCollectionLike(objectToSave);
|
||||
return doInsert(collectionName, objectToSave, this.mongoConverter);
|
||||
@@ -1257,7 +1302,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
protected <T> Flux<T> doInsertBatch(String collectionName, Collection<? extends T> batchToSave,
|
||||
MongoWriter<Object> writer) {
|
||||
|
||||
Assert.notNull(writer, "MongoWriter must not be null!");
|
||||
Assert.notNull(writer, "MongoWriter must not be null");
|
||||
|
||||
Mono<List<Tuple2<AdaptibleEntity<T>, Document>>> prepareDocuments = Flux.fromIterable(batchToSave)
|
||||
.flatMap(uninitialized -> {
|
||||
@@ -1300,7 +1345,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public <T> Mono<T> save(Mono<? extends T> objectToSave) {
|
||||
|
||||
Assert.notNull(objectToSave, "Mono to save must not be null!");
|
||||
Assert.notNull(objectToSave, "Mono to save must not be null");
|
||||
|
||||
return objectToSave.flatMap(this::save);
|
||||
}
|
||||
@@ -1308,7 +1353,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public <T> Mono<T> save(Mono<? extends T> objectToSave, String collectionName) {
|
||||
|
||||
Assert.notNull(objectToSave, "Mono to save must not be null!");
|
||||
Assert.notNull(objectToSave, "Mono to save must not be null");
|
||||
|
||||
return objectToSave.flatMap(o -> save(o, collectionName));
|
||||
}
|
||||
@@ -1316,15 +1361,15 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public <T> Mono<T> save(T objectToSave) {
|
||||
|
||||
Assert.notNull(objectToSave, "Object to save must not be null!");
|
||||
Assert.notNull(objectToSave, "Object to save must not be null");
|
||||
return save(objectToSave, getCollectionName(ClassUtils.getUserClass(objectToSave)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Mono<T> save(T objectToSave, String collectionName) {
|
||||
|
||||
Assert.notNull(objectToSave, "Object to save must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(objectToSave, "Object to save must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
|
||||
AdaptibleEntity<T> source = operations.forEntity(objectToSave, mongoConverter.getConversionService());
|
||||
|
||||
@@ -1403,7 +1448,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
.format("Inserting Document containing fields: " + dbDoc.keySet() + " in collection: " + collectionName));
|
||||
}
|
||||
|
||||
Document document = new Document(dbDoc);
|
||||
MappedDocument document = MappedDocument.of(dbDoc);
|
||||
queryOperations.createInsertContext(document).prepareId(entityClass);
|
||||
|
||||
Flux<InsertOneResult> execute = execute(collectionName, collection -> {
|
||||
|
||||
@@ -1413,10 +1459,10 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
|
||||
MongoCollection<Document> collectionToUse = prepareCollection(collection, writeConcernToUse);
|
||||
|
||||
return collectionToUse.insertOne(document);
|
||||
return collectionToUse.insertOne(document.getDocument());
|
||||
});
|
||||
|
||||
return Flux.from(execute).last().map(success -> MappedDocument.of(document).getId());
|
||||
return Flux.from(execute).last().map(success -> document.getId());
|
||||
}
|
||||
|
||||
protected Flux<ObjectId> insertDocumentList(String collectionName, List<Document> dbDocList) {
|
||||
@@ -1429,7 +1475,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
LOGGER.debug(String.format("Inserting list of Documents containing %d items", dbDocList.size()));
|
||||
}
|
||||
|
||||
List<Document> documents = new ArrayList<>();
|
||||
List<Document> documents = new ArrayList<>(dbDocList.size());
|
||||
|
||||
return execute(collectionName, collection -> {
|
||||
|
||||
@@ -1480,7 +1526,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
|
||||
Publisher<?> publisher;
|
||||
if (!mapped.hasId()) {
|
||||
publisher = collectionToUse.insertOne(document);
|
||||
publisher = collectionToUse.insertOne(queryOperations.createInsertContext(mapped).prepareId(entityClass).getDocument());
|
||||
} else {
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||
@@ -1568,7 +1614,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
|
||||
if (query.isSorted() && LOGGER.isWarnEnabled()) {
|
||||
|
||||
LOGGER.warn(String.format("%s does not support sort ('%s'). Please use findAndModify() instead.",
|
||||
LOGGER.warn(String.format("%s does not support sort ('%s'); Please use findAndModify() instead",
|
||||
upsert ? "Upsert" : "UpdateFirst", serializeToJsonSafely(query.getSortObject())));
|
||||
}
|
||||
|
||||
@@ -1682,7 +1728,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public Mono<DeleteResult> remove(Object object) {
|
||||
|
||||
Assert.notNull(object, "Object must not be null!");
|
||||
Assert.notNull(object, "Object must not be null");
|
||||
|
||||
return remove(operations.forEntity(object).getRemoveByQuery(), object.getClass());
|
||||
}
|
||||
@@ -1690,8 +1736,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
@Override
|
||||
public Mono<DeleteResult> remove(Object object, String collectionName) {
|
||||
|
||||
Assert.notNull(object, "Object must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(object, "Object must not be null");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
|
||||
return doRemove(collectionName, operations.forEntity(object).getRemoveByQuery(), object.getClass());
|
||||
}
|
||||
@@ -1711,7 +1757,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
|
||||
if (!MongoSimpleTypes.AUTOGENERATED_ID_TYPES.contains(property.getType())) {
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
String.format("Cannot autogenerate id of type %s for entity of type %s!", property.getType().getName(),
|
||||
String.format("Cannot autogenerate id of type %s for entity of type %s", property.getType().getName(),
|
||||
value.getClass().getName()));
|
||||
}
|
||||
}
|
||||
@@ -1735,10 +1781,10 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
protected <T> Mono<DeleteResult> doRemove(String collectionName, Query query, @Nullable Class<T> entityClass) {
|
||||
|
||||
if (query == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null!");
|
||||
throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null");
|
||||
}
|
||||
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty");
|
||||
|
||||
MongoPersistentEntity<?> entity = getPersistentEntity(entityClass);
|
||||
|
||||
@@ -1850,7 +1896,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);
|
||||
@@ -1895,13 +1947,13 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
public <T> Flux<T> mapReduce(Query filterQuery, Class<?> domainType, String inputCollectionName, Class<T> resultType,
|
||||
String mapFunction, String reduceFunction, MapReduceOptions options) {
|
||||
|
||||
Assert.notNull(filterQuery, "Filter query must not be null!");
|
||||
Assert.notNull(domainType, "Domain type must not be null!");
|
||||
Assert.hasText(inputCollectionName, "Input collection name must not be null or empty!");
|
||||
Assert.notNull(resultType, "Result type must not be null!");
|
||||
Assert.notNull(mapFunction, "Map function must not be null!");
|
||||
Assert.notNull(reduceFunction, "Reduce function must not be null!");
|
||||
Assert.notNull(options, "MapReduceOptions must not be null!");
|
||||
Assert.notNull(filterQuery, "Filter query must not be null");
|
||||
Assert.notNull(domainType, "Domain type must not be null");
|
||||
Assert.hasText(inputCollectionName, "Input collection name must not be null or empty");
|
||||
Assert.notNull(resultType, "Result type must not be null");
|
||||
Assert.notNull(mapFunction, "Map function must not be null");
|
||||
Assert.notNull(reduceFunction, "Reduce function must not be null");
|
||||
Assert.notNull(options, "MapReduceOptions must not be null");
|
||||
|
||||
assertLocalFunctionNames(mapFunction, reduceFunction);
|
||||
|
||||
@@ -1927,7 +1979,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
|
||||
if (filterQuery.getLimit() > 0 && (options.getLimit() != null)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Both Query and MapReduceOptions define a limit. Please provide the limit only via one of the two.");
|
||||
"Both Query and MapReduceOptions define a limit; Please provide the limit only via one of the two.");
|
||||
}
|
||||
|
||||
if (filterQuery.getLimit() > 0) {
|
||||
@@ -1943,7 +1995,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
|
||||
Optionals.ifAllPresent(filterQuery.getCollation(), options.getCollation(), (l, r) -> {
|
||||
throw new IllegalArgumentException(
|
||||
"Both Query and MapReduceOptions define a collation. Please provide the collation only via one of the two.");
|
||||
"Both Query and MapReduceOptions define a collation; Please provide the collation only via one of the two.");
|
||||
});
|
||||
|
||||
if (options.getCollation().isPresent()) {
|
||||
@@ -1992,7 +2044,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
if (ResourceUtils.isUrl(function)) {
|
||||
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Blocking accessing to resource %s is not allowed using reactive infrastructure. You may load the resource at startup and cache its value.",
|
||||
"Blocking accessing to resource %s is not allowed using reactive infrastructure; You may load the resource at startup and cache its value.",
|
||||
function));
|
||||
}
|
||||
}
|
||||
@@ -2324,11 +2376,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
}
|
||||
|
||||
protected <E extends MongoMappingEvent<T>, T> E maybeEmitEvent(E event) {
|
||||
|
||||
if (eventPublisher != null) {
|
||||
eventPublisher.publishEvent(event);
|
||||
}
|
||||
|
||||
eventDelegate.publishEvent(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
@@ -2850,8 +2898,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
|
||||
ReadDocumentCallback(EntityReader<? super T, Bson> reader, Class<T> type, String collectionName) {
|
||||
|
||||
Assert.notNull(reader, "EntityReader must not be null!");
|
||||
Assert.notNull(type, "Entity type must not be null!");
|
||||
Assert.notNull(reader, "EntityReader must not be null");
|
||||
Assert.notNull(type, "Entity type must not be null");
|
||||
|
||||
this.reader = reader;
|
||||
this.type = type;
|
||||
@@ -2939,7 +2987,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
*/
|
||||
GeoNearResultDocumentCallback(String distanceField, DocumentCallback<T> delegate, Metric metric) {
|
||||
|
||||
Assert.notNull(delegate, "DocumentCallback must not be null!");
|
||||
Assert.notNull(delegate, "DocumentCallback must not be null");
|
||||
|
||||
this.distanceField = distanceField;
|
||||
this.delegate = delegate;
|
||||
|
||||
@@ -44,7 +44,7 @@ class ReactiveRemoveOperationSupport implements ReactiveRemoveOperation {
|
||||
@Override
|
||||
public <T> ReactiveRemove<T> remove(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ReactiveRemoveSupport<>(tempate, domainType, ALL_QUERY, null);
|
||||
}
|
||||
@@ -67,7 +67,7 @@ class ReactiveRemoveOperationSupport implements ReactiveRemoveOperation {
|
||||
@Override
|
||||
public RemoveWithQuery<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection must not be null nor empty");
|
||||
|
||||
return new ReactiveRemoveSupport<>(template, domainType, query, collection);
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class ReactiveRemoveOperationSupport implements ReactiveRemoveOperation {
|
||||
@Override
|
||||
public TerminatingRemove<T> matching(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
return new ReactiveRemoveSupport<>(template, domainType, query, collection);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class ReactiveUpdateOperationSupport implements ReactiveUpdateOperation {
|
||||
@Override
|
||||
public <T> ReactiveUpdate<T> update(Class<T> domainType) {
|
||||
|
||||
Assert.notNull(domainType, "DomainType must not be null!");
|
||||
Assert.notNull(domainType, "DomainType must not be null");
|
||||
|
||||
return new ReactiveUpdateSupport<>(template, domainType, ALL_QUERY, null, null, null, null, null, domainType);
|
||||
}
|
||||
@@ -82,7 +82,7 @@ class ReactiveUpdateOperationSupport implements ReactiveUpdateOperation {
|
||||
@Override
|
||||
public TerminatingUpdate<T> apply(org.springframework.data.mongodb.core.query.UpdateDefinition update) {
|
||||
|
||||
Assert.notNull(update, "Update must not be null!");
|
||||
Assert.notNull(update, "Update must not be null");
|
||||
|
||||
return new ReactiveUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
findAndReplaceOptions, replacement, targetType);
|
||||
@@ -91,7 +91,7 @@ class ReactiveUpdateOperationSupport implements ReactiveUpdateOperation {
|
||||
@Override
|
||||
public UpdateWithQuery<T> inCollection(String collection) {
|
||||
|
||||
Assert.hasText(collection, "Collection must not be null nor empty!");
|
||||
Assert.hasText(collection, "Collection must not be null nor empty");
|
||||
|
||||
return new ReactiveUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
findAndReplaceOptions, replacement, targetType);
|
||||
@@ -127,7 +127,7 @@ class ReactiveUpdateOperationSupport implements ReactiveUpdateOperation {
|
||||
@Override
|
||||
public UpdateWithUpdate<T> matching(Query query) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null!");
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
|
||||
return new ReactiveUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
findAndReplaceOptions, replacement, targetType);
|
||||
@@ -141,7 +141,7 @@ class ReactiveUpdateOperationSupport implements ReactiveUpdateOperation {
|
||||
@Override
|
||||
public TerminatingFindAndModify<T> withOptions(FindAndModifyOptions options) {
|
||||
|
||||
Assert.notNull(options, "Options must not be null!");
|
||||
Assert.notNull(options, "Options must not be null");
|
||||
|
||||
return new ReactiveUpdateSupport<>(template, domainType, query, update, collection, options,
|
||||
findAndReplaceOptions, replacement, targetType);
|
||||
@@ -150,7 +150,7 @@ class ReactiveUpdateOperationSupport implements ReactiveUpdateOperation {
|
||||
@Override
|
||||
public FindAndReplaceWithProjection<T> replaceWith(T replacement) {
|
||||
|
||||
Assert.notNull(replacement, "Replacement must not be null!");
|
||||
Assert.notNull(replacement, "Replacement must not be null");
|
||||
|
||||
return new ReactiveUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
findAndReplaceOptions, replacement, targetType);
|
||||
@@ -159,7 +159,7 @@ class ReactiveUpdateOperationSupport implements ReactiveUpdateOperation {
|
||||
@Override
|
||||
public FindAndReplaceWithProjection<T> withOptions(FindAndReplaceOptions options) {
|
||||
|
||||
Assert.notNull(options, "Options must not be null!");
|
||||
Assert.notNull(options, "Options must not be null");
|
||||
|
||||
return new ReactiveUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions, options,
|
||||
replacement, targetType);
|
||||
@@ -168,7 +168,7 @@ class ReactiveUpdateOperationSupport implements ReactiveUpdateOperation {
|
||||
@Override
|
||||
public <R> FindAndReplaceWithOptions<R> as(Class<R> resultType) {
|
||||
|
||||
Assert.notNull(resultType, "ResultType must not be null!");
|
||||
Assert.notNull(resultType, "ResultType must not be null");
|
||||
|
||||
return new ReactiveUpdateSupport<>(template, domainType, query, update, collection, findAndModifyOptions,
|
||||
findAndReplaceOptions, replacement, resultType);
|
||||
|
||||
@@ -77,10 +77,10 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React
|
||||
|
||||
private SimpleReactiveMongoDatabaseFactory(MongoClient client, String databaseName, boolean mongoInstanceCreated) {
|
||||
|
||||
Assert.notNull(client, "MongoClient must not be null!");
|
||||
Assert.hasText(databaseName, "Database name must not be empty!");
|
||||
Assert.notNull(client, "MongoClient must not be null");
|
||||
Assert.hasText(databaseName, "Database name must not be empty");
|
||||
Assert.isTrue(databaseName.matches("[^/\\\\.$\"\\s]+"),
|
||||
"Database name must not contain slashes, dots, spaces, quotes, or dollar signs!");
|
||||
"Database name must not contain slashes, dots, spaces, quotes, or dollar signs");
|
||||
|
||||
this.mongo = client;
|
||||
this.databaseName = databaseName;
|
||||
@@ -103,7 +103,7 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React
|
||||
|
||||
public Mono<MongoDatabase> getMongoDatabase(String dbName) throws DataAccessException {
|
||||
|
||||
Assert.hasText(dbName, "Database name must not be empty.");
|
||||
Assert.hasText(dbName, "Database name must not be empty");
|
||||
|
||||
return Mono.fromSupplier(() -> {
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.core;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.mongodb.core.query.Collation;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Immutable object holding additional options to be applied when creating a MongoDB
|
||||
* <a href="https://www.mongodb.com/docs/manual/core/views/">views</a>.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 4.0
|
||||
*/
|
||||
public class ViewOptions {
|
||||
|
||||
private final @Nullable Collation collation;
|
||||
|
||||
static ViewOptions none() {
|
||||
return new ViewOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new instance of {@link ViewOptions}.
|
||||
*/
|
||||
public ViewOptions() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
private ViewOptions(@Nullable Collation collation) {
|
||||
this.collation = collation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Collation} to be set.
|
||||
*
|
||||
* @return {@link Optional#empty()} if not set.
|
||||
*/
|
||||
public Optional<Collation> getCollation() {
|
||||
return Optional.ofNullable(collation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param collation the {@link Collation} to use for language-specific string comparison.
|
||||
* @return new instance of {@link ViewOptions}.
|
||||
*/
|
||||
public ViewOptions collation(Collation collation) {
|
||||
return new ViewOptions(collation);
|
||||
}
|
||||
}
|
||||
@@ -19,12 +19,16 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation.SystemVariable;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -69,8 +73,31 @@ abstract class AbstractAggregationExpression implements AggregationExpression {
|
||||
return ((AggregationExpression) value).toDocument(context);
|
||||
}
|
||||
|
||||
if (value instanceof Field) {
|
||||
return context.getReference((Field) value).toString();
|
||||
if (value instanceof Field field) {
|
||||
return context.getReference(field).toString();
|
||||
}
|
||||
|
||||
if (value instanceof Fields fields) {
|
||||
|
||||
List<Object> mapped = new ArrayList<>(fields.size());
|
||||
|
||||
for (Field field : fields) {
|
||||
mapped.add(unpack(field, context));
|
||||
}
|
||||
|
||||
return mapped;
|
||||
}
|
||||
|
||||
if (value instanceof Sort sort) {
|
||||
|
||||
Document sortDoc = new Document();
|
||||
for (Order order : sort) {
|
||||
|
||||
// Check reference
|
||||
FieldReference reference = context.getReference(order.getProperty());
|
||||
sortDoc.put(reference.getRaw(), order.isAscending() ? 1 : -1);
|
||||
}
|
||||
return sortDoc;
|
||||
}
|
||||
|
||||
if (value instanceof List) {
|
||||
@@ -78,7 +105,9 @@ abstract class AbstractAggregationExpression implements AggregationExpression {
|
||||
List<Object> sourceList = (List<Object>) value;
|
||||
List<Object> mappedList = new ArrayList<>(sourceList.size());
|
||||
|
||||
sourceList.stream().map((item) -> unpack(item, context)).forEach(mappedList::add);
|
||||
for (Object o : sourceList) {
|
||||
mappedList.add(unpack(o, context));
|
||||
}
|
||||
|
||||
return mappedList;
|
||||
}
|
||||
@@ -130,21 +159,53 @@ abstract class AbstractAggregationExpression implements AggregationExpression {
|
||||
return append(value, Expand.EXPAND_VALUES);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected Map<String, Object> append(String key, Object value) {
|
||||
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map!");
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map");
|
||||
|
||||
Map<String, Object> clone = new LinkedHashMap<>((java.util.Map) this.value);
|
||||
return append((Map<String, Object>) this.value, key, value);
|
||||
}
|
||||
|
||||
private Map<String, Object> append(Map<String, Object> existing, String key, Object value) {
|
||||
|
||||
Map<String, Object> clone = new LinkedHashMap<>(existing);
|
||||
clone.put(key, value);
|
||||
return clone;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
protected Map<String, Object> appendTo(String key, Object value) {
|
||||
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map");
|
||||
|
||||
if (this.value instanceof Map map) {
|
||||
|
||||
Map<String, Object> target = new HashMap<>(map);
|
||||
if (!target.containsKey(key)) {
|
||||
target.put(key, value);
|
||||
return target;
|
||||
}
|
||||
target.computeIfPresent(key, (k, v) -> {
|
||||
|
||||
if (v instanceof List<?> list) {
|
||||
List<Object> targetList = new ArrayList<>(list);
|
||||
targetList.add(value);
|
||||
return targetList;
|
||||
}
|
||||
return Arrays.asList(v, value);
|
||||
});
|
||||
return target;
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
String.format("Cannot append value to %s type", ObjectUtils.nullSafeClassName(this.value)));
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
protected Map<String, Object> remove(String key) {
|
||||
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map!");
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map");
|
||||
|
||||
Map<String, Object> clone = new LinkedHashMap<>((java.util.Map) this.value);
|
||||
clone.remove(key);
|
||||
@@ -163,7 +224,7 @@ abstract class AbstractAggregationExpression implements AggregationExpression {
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected Map<String, Object> appendAt(int index, String key, Object value) {
|
||||
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map!");
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map");
|
||||
|
||||
Map<String, Object> clone = new LinkedHashMap<>();
|
||||
|
||||
@@ -223,11 +284,15 @@ abstract class AbstractAggregationExpression implements AggregationExpression {
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T get(Object key) {
|
||||
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map!");
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map");
|
||||
|
||||
return (T) ((Map<String, Object>) this.value).get(key);
|
||||
}
|
||||
|
||||
protected boolean isArgumentMap() {
|
||||
return this.value instanceof Map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the argument map.
|
||||
*
|
||||
@@ -237,7 +302,7 @@ abstract class AbstractAggregationExpression implements AggregationExpression {
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<String, Object> argumentMap() {
|
||||
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map!");
|
||||
Assert.isInstanceOf(Map.class, this.value, "Value must be a type of Map");
|
||||
|
||||
return Collections.unmodifiableMap((java.util.Map<String, Object>) value);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public AccumulatorOperatorFactory(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
this.fieldReference = fieldReference;
|
||||
this.expression = null;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public AccumulatorOperatorFactory(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
this.fieldReference = null;
|
||||
this.expression = expression;
|
||||
}
|
||||
@@ -112,6 +112,17 @@ public class AccumulatorOperators {
|
||||
return usesFieldRef() ? Max.maxOf(fieldReference) : Max.maxOf(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that takes the associated numeric value expression and returns the
|
||||
* requested number of maximum values.
|
||||
*
|
||||
* @return new instance of {@link Max}.
|
||||
* @since 4.0
|
||||
*/
|
||||
public Max max(int numberOfResults) {
|
||||
return max().limit(numberOfResults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that takes the associated numeric value expression and returns the
|
||||
* minimum value.
|
||||
@@ -122,6 +133,17 @@ public class AccumulatorOperators {
|
||||
return usesFieldRef() ? Min.minOf(fieldReference) : Min.minOf(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that takes the associated numeric value expression and returns the
|
||||
* requested number of maximum values.
|
||||
*
|
||||
* @return new instance of {@link Max}.
|
||||
* @since 4.0
|
||||
*/
|
||||
public Min min(int numberOfResults) {
|
||||
return min().limit(numberOfResults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that takes the associated numeric value expression and calculates the
|
||||
* population standard deviation of the input values.
|
||||
@@ -278,7 +300,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static Sum sumOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Sum(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -290,7 +312,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static Sum sumOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Sum(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -303,7 +325,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public Sum and(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Sum(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -316,7 +338,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public Sum and(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Sum(append(expression));
|
||||
}
|
||||
|
||||
@@ -330,7 +352,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public Sum and(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Sum(append(value));
|
||||
}
|
||||
|
||||
@@ -372,7 +394,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static Avg avgOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Avg(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -384,7 +406,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static Avg avgOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Avg(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -397,7 +419,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public Avg and(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Avg(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -410,7 +432,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public Avg and(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Avg(append(expression));
|
||||
}
|
||||
|
||||
@@ -441,7 +463,7 @@ public class AccumulatorOperators {
|
||||
|
||||
@Override
|
||||
protected String getMongoMethod() {
|
||||
return "$max";
|
||||
return contains("n") ? "$maxN" : "$max";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,8 +474,8 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static Max maxOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
return new Max(asFields(fieldReference));
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Max(Collections.singletonMap("input", Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -464,8 +486,8 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static Max maxOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
return new Max(Collections.singletonList(expression));
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Max(Collections.singletonMap("input", expression));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -477,8 +499,8 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public Max and(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
return new Max(append(Fields.field(fieldReference)));
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Max(appendTo("input", Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -490,8 +512,27 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public Max and(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
return new Max(append(expression));
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Max(appendTo("input", expression));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link Max} that returns the given number of maxmimum values ({@literal $maxN}).
|
||||
* <strong>NOTE</strong>: Cannot be used with more than one {@literal input} value.
|
||||
*
|
||||
* @param numberOfResults
|
||||
* @return new instance of {@link Max}.
|
||||
*/
|
||||
public Max limit(int numberOfResults) {
|
||||
return new Max(append("n", numberOfResults));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document toDocument(AggregationOperationContext context) {
|
||||
if (get("n") == null) {
|
||||
return toDocument(get("input"), context);
|
||||
}
|
||||
return super.toDocument(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -521,7 +562,7 @@ public class AccumulatorOperators {
|
||||
|
||||
@Override
|
||||
protected String getMongoMethod() {
|
||||
return "$min";
|
||||
return contains("n") ? "$minN" : "$min";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -532,8 +573,8 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static Min minOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
return new Min(asFields(fieldReference));
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Min(Collections.singletonMap("input", Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -544,8 +585,8 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static Min minOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
return new Min(Collections.singletonList(expression));
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Min(Collections.singletonMap("input", expression));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -557,8 +598,8 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public Min and(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
return new Min(append(Fields.field(fieldReference)));
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Min(appendTo("input", Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -570,8 +611,28 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public Min and(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
return new Min(append(expression));
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Min(appendTo("input", expression));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link Min} that returns the given number of minimum values ({@literal $minN}).
|
||||
* <strong>NOTE</strong>: Cannot be used with more than one {@literal input} value.
|
||||
*
|
||||
* @param numberOfResults
|
||||
* @return new instance of {@link Min}.
|
||||
*/
|
||||
public Min limit(int numberOfResults) {
|
||||
return new Min(append("n", numberOfResults));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Document toDocument(AggregationOperationContext context) {
|
||||
|
||||
if (get("n") == null) {
|
||||
return toDocument(get("input"), context);
|
||||
}
|
||||
return super.toDocument(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -612,7 +673,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static StdDevPop stdDevPopOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new StdDevPop(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -624,7 +685,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static StdDevPop stdDevPopOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new StdDevPop(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -637,7 +698,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public StdDevPop and(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new StdDevPop(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -650,7 +711,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public StdDevPop and(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new StdDevPop(append(expression));
|
||||
}
|
||||
|
||||
@@ -692,7 +753,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static StdDevSamp stdDevSampOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new StdDevSamp(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -704,7 +765,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static StdDevSamp stdDevSampOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new StdDevSamp(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -717,7 +778,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public StdDevSamp and(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new StdDevSamp(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -730,7 +791,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public StdDevSamp and(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new StdDevSamp(append(expression));
|
||||
}
|
||||
|
||||
@@ -768,7 +829,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static CovariancePop covariancePopOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new CovariancePop(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -828,7 +889,7 @@ public class AccumulatorOperators {
|
||||
*/
|
||||
public static CovarianceSamp covarianceSampOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new CovarianceSamp(asFields(fieldReference));
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.aggregation.AddFieldsOperation.AddFieldsOperationBuilder;
|
||||
@@ -34,7 +35,6 @@ import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.SerializationUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -138,7 +138,7 @@ public class Aggregation {
|
||||
*/
|
||||
public Aggregation withOptions(AggregationOptions options) {
|
||||
|
||||
Assert.notNull(options, "AggregationOptions must not be null.");
|
||||
Assert.notNull(options, "AggregationOptions must not be null");
|
||||
return new Aggregation(this.pipeline.getOperations(), options);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ public class Aggregation {
|
||||
*/
|
||||
protected static List<AggregationOperation> asAggregationList(AggregationOperation... aggregationOperations) {
|
||||
|
||||
Assert.notEmpty(aggregationOperations, "AggregationOperations must not be null or empty!");
|
||||
Assert.notEmpty(aggregationOperations, "AggregationOperations must not be null or empty");
|
||||
|
||||
return Arrays.asList(aggregationOperations);
|
||||
}
|
||||
@@ -199,8 +199,8 @@ public class Aggregation {
|
||||
*/
|
||||
protected Aggregation(List<AggregationOperation> aggregationOperations, AggregationOptions options) {
|
||||
|
||||
Assert.notNull(aggregationOperations, "AggregationOperations must not be null!");
|
||||
Assert.notNull(options, "AggregationOptions must not be null!");
|
||||
Assert.notNull(aggregationOperations, "AggregationOperations must not be null");
|
||||
Assert.notNull(options, "AggregationOptions must not be null");
|
||||
|
||||
this.pipeline = new AggregationPipeline(aggregationOperations);
|
||||
this.options = options;
|
||||
@@ -238,6 +238,40 @@ public class Aggregation {
|
||||
return AddFieldsOperation.builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link AggregationOperation} taking the given {@link Bson bson value} as is. <br />
|
||||
*
|
||||
* <pre class="code">
|
||||
* Aggregation.stage(Aggregates.search(exists(fieldPath("..."))));
|
||||
* </pre>
|
||||
*
|
||||
* Field mapping against a potential domain type or previous aggregation stages will not happen.
|
||||
*
|
||||
* @param aggregationOperation the must not be {@literal null}.
|
||||
* @return new instance of {@link AggregationOperation}.
|
||||
* @since 4.0
|
||||
*/
|
||||
public static AggregationOperation stage(Bson aggregationOperation) {
|
||||
return new BasicAggregationOperation(aggregationOperation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link AggregationOperation} taking the given {@link String json value} as is. <br />
|
||||
*
|
||||
* <pre class="code">
|
||||
* Aggregation.stage("{ $search : { near : { path : 'released' , origin : ... } } }");
|
||||
* </pre>
|
||||
*
|
||||
* Field mapping against a potential domain type or previous aggregation stages will not happen.
|
||||
*
|
||||
* @param json the JSON representation of the pipeline stage. Must not be {@literal null}.
|
||||
* @return new instance of {@link AggregationOperation}.
|
||||
* @since 4.0
|
||||
*/
|
||||
public static AggregationOperation stage(String json) {
|
||||
return new BasicAggregationOperation(json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ProjectionOperation} including the given fields.
|
||||
*
|
||||
@@ -267,7 +301,7 @@ public class Aggregation {
|
||||
*/
|
||||
public static ProjectionOperation project(Class<?> type) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
Assert.notNull(type, "Type must not be null");
|
||||
return new ProjectionOperation(type);
|
||||
}
|
||||
|
||||
@@ -731,48 +765,4 @@ public class Aggregation {
|
||||
public String toString() {
|
||||
return SerializationUtils.serializeToJsonSafely(toDocument("__collection__", DEFAULT_CONTEXT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the system variables available in MongoDB aggregation framework pipeline expressions.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @see <a href="https://docs.mongodb.com/manual/reference/aggregation-variables">Aggregation Variables</a>.
|
||||
*/
|
||||
enum SystemVariable {
|
||||
|
||||
ROOT, CURRENT, REMOVE;
|
||||
|
||||
private static final String PREFIX = "$$";
|
||||
|
||||
/**
|
||||
* Return {@literal true} if the given {@code fieldRef} denotes a well-known system variable, {@literal false}
|
||||
* otherwise.
|
||||
*
|
||||
* @param fieldRef may be {@literal null}.
|
||||
* @return {@literal true} if the given field refers to a {@link SystemVariable}.
|
||||
*/
|
||||
public static boolean isReferingToSystemVariable(@Nullable String fieldRef) {
|
||||
|
||||
if (fieldRef == null || !fieldRef.startsWith(PREFIX) || fieldRef.length() <= 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int indexOfFirstDot = fieldRef.indexOf('.');
|
||||
String candidate = fieldRef.substring(2, indexOfFirstDot == -1 ? fieldRef.length() : indexOfFirstDot);
|
||||
|
||||
for (SystemVariable value : values()) {
|
||||
if (value.name().equals(candidate)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return PREFIX.concat(name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ interface AggregationExpressionTransformer
|
||||
|
||||
super(currentNode, parentNode, previousOperationObject);
|
||||
|
||||
Assert.notNull(context, "AggregationOperationContext must not be null!");
|
||||
Assert.notNull(context, "AggregationOperationContext must not be null");
|
||||
this.aggregationContext = context;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,16 @@ import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.codecs.configuration.CodecRegistry;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.data.mongodb.CodecRegistryProvider;
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.mongodb.MongoClientSettings;
|
||||
|
||||
/**
|
||||
* The context for an {@link AggregationOperation}.
|
||||
*
|
||||
@@ -33,7 +37,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author Christoph Strobl
|
||||
* @since 1.3
|
||||
*/
|
||||
public interface AggregationOperationContext {
|
||||
public interface AggregationOperationContext extends CodecRegistryProvider {
|
||||
|
||||
/**
|
||||
* Returns the mapped {@link Document}, potentially converting the source considering mapping metadata etc.
|
||||
@@ -86,7 +90,7 @@ public interface AggregationOperationContext {
|
||||
*/
|
||||
default Fields getFields(Class<?> type) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
Assert.notNull(type, "Type must not be null");
|
||||
|
||||
return Fields.fields(Arrays.stream(BeanUtils.getPropertyDescriptors(type)) //
|
||||
.filter(it -> { // object and default methods
|
||||
@@ -114,4 +118,9 @@ public interface AggregationOperationContext {
|
||||
default AggregationOperationContext continueOnMissingFieldReference() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default CodecRegistry getCodecRegistry() {
|
||||
return MongoClientSettings.getDefaultCodecRegistry();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ public class AggregationOptions {
|
||||
*/
|
||||
public static AggregationOptions fromDocument(Document document) {
|
||||
|
||||
Assert.notNull(document, "Document must not be null!");
|
||||
Assert.notNull(document, "Document must not be null");
|
||||
|
||||
boolean allowDiskUse = document.getBoolean(ALLOW_DISK_USE, false);
|
||||
boolean explain = document.getBoolean(EXPLAIN, false);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
@@ -34,6 +35,10 @@ public class AggregationPipeline {
|
||||
|
||||
private final List<AggregationOperation> pipeline;
|
||||
|
||||
public static AggregationPipeline of(AggregationOperation... stages) {
|
||||
return new AggregationPipeline(Arrays.asList(stages));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an empty pipeline
|
||||
*/
|
||||
@@ -48,7 +53,7 @@ public class AggregationPipeline {
|
||||
*/
|
||||
public AggregationPipeline(List<AggregationOperation> aggregationOperations) {
|
||||
|
||||
Assert.notNull(aggregationOperations, "AggregationOperations must not be null!");
|
||||
Assert.notNull(aggregationOperations, "AggregationOperations must not be null");
|
||||
pipeline = new ArrayList<>(aggregationOperations);
|
||||
}
|
||||
|
||||
@@ -60,7 +65,7 @@ public class AggregationPipeline {
|
||||
*/
|
||||
public AggregationPipeline add(AggregationOperation aggregationOperation) {
|
||||
|
||||
Assert.notNull(aggregationOperation, "AggregationOperation must not be null!");
|
||||
Assert.notNull(aggregationOperation, "AggregationOperation must not be null");
|
||||
|
||||
pipeline.add(aggregationOperation);
|
||||
return this;
|
||||
@@ -100,11 +105,11 @@ public class AggregationPipeline {
|
||||
for (AggregationOperation operation : pipeline) {
|
||||
|
||||
if (isOut(operation) && !isLast(operation)) {
|
||||
throw new IllegalArgumentException("The $out operator must be the last stage in the pipeline.");
|
||||
throw new IllegalArgumentException("The $out operator must be the last stage in the pipeline");
|
||||
}
|
||||
|
||||
if (isMerge(operation) && !isLast(operation)) {
|
||||
throw new IllegalArgumentException("The $merge operator must be the last stage in the pipeline.");
|
||||
throw new IllegalArgumentException("The $merge operator must be the last stage in the pipeline");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ public class AggregationResults<T> implements Iterable<T> {
|
||||
*/
|
||||
public AggregationResults(List<T> mappedResults, Document rawResults) {
|
||||
|
||||
Assert.notNull(mappedResults, "List of mapped results must not be null!");
|
||||
Assert.notNull(rawResults, "Raw results must not be null!");
|
||||
Assert.notNull(mappedResults, "List of mapped results must not be null");
|
||||
Assert.notNull(rawResults, "Raw results must not be null");
|
||||
|
||||
this.mappedResults = Collections.unmodifiableList(mappedResults);
|
||||
this.rawResults = rawResults;
|
||||
@@ -73,7 +73,7 @@ public class AggregationResults<T> implements Iterable<T> {
|
||||
*/
|
||||
@Nullable
|
||||
public T getUniqueMappedResult() {
|
||||
Assert.isTrue(mappedResults.size() < 2, "Expected unique result or null, but got more than one!");
|
||||
Assert.isTrue(mappedResults.size() < 2, "Expected unique result or null, but got more than one");
|
||||
return mappedResults.size() == 1 ? mappedResults.get(0) : null;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class AggregationSpELExpression implements AggregationExpression {
|
||||
*/
|
||||
public static AggregationSpELExpression expressionOf(String expressionString, Object... parameters) {
|
||||
|
||||
Assert.notNull(expressionString, "ExpressionString must not be null!");
|
||||
Assert.notNull(expressionString, "ExpressionString must not be null");
|
||||
return new AggregationSpELExpression(expressionString, parameters);
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ public class AggregationUpdate extends Aggregation implements UpdateDefinition {
|
||||
*/
|
||||
public AggregationUpdate set(SetOperation setOperation) {
|
||||
|
||||
Assert.notNull(setOperation, "SetOperation must not be null!");
|
||||
Assert.notNull(setOperation, "SetOperation must not be null");
|
||||
|
||||
setOperation.getFields().forEach(it -> {
|
||||
keysTouched.add(it.getName());
|
||||
@@ -152,7 +152,7 @@ public class AggregationUpdate extends Aggregation implements UpdateDefinition {
|
||||
*/
|
||||
public AggregationUpdate unset(UnsetOperation unsetOperation) {
|
||||
|
||||
Assert.notNull(unsetOperation, "UnsetOperation must not be null!");
|
||||
Assert.notNull(unsetOperation, "UnsetOperation must not be null");
|
||||
|
||||
pipeline.add(unsetOperation);
|
||||
keysTouched.addAll(unsetOperation.removedFieldNames());
|
||||
@@ -170,7 +170,7 @@ public class AggregationUpdate extends Aggregation implements UpdateDefinition {
|
||||
*/
|
||||
public AggregationUpdate replaceWith(ReplaceWithOperation replaceWithOperation) {
|
||||
|
||||
Assert.notNull(replaceWithOperation, "ReplaceWithOperation must not be null!");
|
||||
Assert.notNull(replaceWithOperation, "ReplaceWithOperation must not be null");
|
||||
pipeline.add(replaceWithOperation);
|
||||
return this;
|
||||
}
|
||||
@@ -183,7 +183,7 @@ public class AggregationUpdate extends Aggregation implements UpdateDefinition {
|
||||
*/
|
||||
public AggregationUpdate replaceWith(Object value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return replaceWith(ReplaceWithOperation.replaceWithValue(value));
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ public class AggregationUpdate extends Aggregation implements UpdateDefinition {
|
||||
*/
|
||||
public SetValueAppender set(String key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(key, "Key must not be null");
|
||||
|
||||
return new SetValueAppender() {
|
||||
|
||||
@@ -209,7 +209,7 @@ public class AggregationUpdate extends Aggregation implements UpdateDefinition {
|
||||
@Override
|
||||
public AggregationUpdate toValueOf(Object value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return set(SetOperation.builder().set(key).toValueOf(value));
|
||||
}
|
||||
};
|
||||
@@ -223,8 +223,8 @@ public class AggregationUpdate extends Aggregation implements UpdateDefinition {
|
||||
*/
|
||||
public AggregationUpdate unset(String... keys) {
|
||||
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements.");
|
||||
Assert.notNull(keys, "Keys must not be null");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements");
|
||||
|
||||
return unset(new UnsetOperation(Arrays.stream(keys).map(Fields::field).collect(Collectors.toList())));
|
||||
}
|
||||
|
||||
@@ -36,11 +36,11 @@ interface AggregationUtils {
|
||||
*/
|
||||
static List<Long> toRangeValues(Range<Long> range) {
|
||||
|
||||
Assert.notNull(range, "Range must not be null!");
|
||||
Assert.notNull(range, "Range must not be null");
|
||||
|
||||
List<Long> result = new ArrayList<Long>(2);
|
||||
result.add(range.getLowerBound().getValue()
|
||||
.orElseThrow(() -> new IllegalArgumentException("Lower bound of range must be bounded!")));
|
||||
.orElseThrow(() -> new IllegalArgumentException("Lower bound of range must be bounded")));
|
||||
range.getUpperBound().getValue().ifPresent(it -> result.add(it));
|
||||
|
||||
return result;
|
||||
|
||||
@@ -91,7 +91,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public ArithmeticOperatorFactory(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
this.fieldReference = fieldReference;
|
||||
this.expression = null;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public ArithmeticOperatorFactory(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
this.fieldReference = null;
|
||||
this.expression = expression;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Add add(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createAdd().add(fieldReference);
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Add add(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createAdd().add(expression);
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Add add(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return createAdd().add(value);
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Divide divideBy(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createDivide().divideBy(fieldReference);
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Divide divideBy(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createDivide().divideBy(expression);
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Divide divideBy(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return createDivide().divideBy(value);
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Integral integral(String unit) {
|
||||
|
||||
Assert.hasText(unit, "Unit must not be empty!");
|
||||
Assert.hasText(unit, "Unit must not be empty");
|
||||
|
||||
return integral().unit(unit);
|
||||
}
|
||||
@@ -328,7 +328,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Log log(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createLog().log(fieldReference);
|
||||
}
|
||||
|
||||
@@ -341,7 +341,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Log log(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createLog().log(fieldReference);
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Log log(Number base) {
|
||||
|
||||
Assert.notNull(base, "Base must not be null!");
|
||||
Assert.notNull(base, "Base must not be null");
|
||||
return createLog().log(base);
|
||||
}
|
||||
|
||||
@@ -380,7 +380,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Mod mod(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createMod().mod(fieldReference);
|
||||
}
|
||||
|
||||
@@ -393,7 +393,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Mod mod(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createMod().mod(expression);
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Mod mod(Number value) {
|
||||
|
||||
Assert.notNull(value, "Base must not be null!");
|
||||
Assert.notNull(value, "Base must not be null");
|
||||
return createMod().mod(value);
|
||||
}
|
||||
|
||||
@@ -422,7 +422,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Multiply multiplyBy(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createMultiply().multiplyBy(fieldReference);
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Multiply multiplyBy(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createMultiply().multiplyBy(expression);
|
||||
}
|
||||
|
||||
@@ -446,7 +446,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Multiply multiplyBy(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return createMultiply().multiplyBy(value);
|
||||
}
|
||||
|
||||
@@ -462,7 +462,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Pow pow(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createPow().pow(fieldReference);
|
||||
}
|
||||
|
||||
@@ -474,7 +474,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Pow pow(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createPow().pow(expression);
|
||||
}
|
||||
|
||||
@@ -486,7 +486,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Pow pow(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return createPow().pow(value);
|
||||
}
|
||||
|
||||
@@ -511,7 +511,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Subtract subtract(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createSubtract().subtract(fieldReference);
|
||||
}
|
||||
|
||||
@@ -523,7 +523,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Subtract subtract(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createSubtract().subtract(expression);
|
||||
}
|
||||
|
||||
@@ -535,7 +535,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Subtract subtract(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return createSubtract().subtract(value);
|
||||
}
|
||||
|
||||
@@ -851,7 +851,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public ATan2 atan2(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return createATan2().atan2of(value);
|
||||
}
|
||||
|
||||
@@ -865,7 +865,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public ATan2 atan2(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createATan2().atan2of(fieldReference);
|
||||
}
|
||||
|
||||
@@ -879,7 +879,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public ATan2 atan2(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createATan2().atan2of(expression);
|
||||
}
|
||||
|
||||
@@ -961,7 +961,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Abs absoluteValueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Abs(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -973,7 +973,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Abs absoluteValueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Abs(expression);
|
||||
}
|
||||
|
||||
@@ -985,7 +985,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Abs absoluteValueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Abs(value);
|
||||
}
|
||||
}
|
||||
@@ -1014,7 +1014,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Add valueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Add(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1026,7 +1026,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Add valueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Add(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -1038,7 +1038,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Add valueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Add(Collections.singletonList(value));
|
||||
}
|
||||
|
||||
@@ -1050,7 +1050,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Add add(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Add(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -1062,7 +1062,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Add add(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Add(append(expression));
|
||||
}
|
||||
|
||||
@@ -1101,7 +1101,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Ceil ceilValueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Ceil(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1113,7 +1113,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Ceil ceilValueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Ceil(expression);
|
||||
}
|
||||
|
||||
@@ -1125,7 +1125,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Ceil ceilValueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Ceil(value);
|
||||
}
|
||||
}
|
||||
@@ -1154,7 +1154,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Divide valueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Divide(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1166,7 +1166,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Divide valueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Divide(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -1178,7 +1178,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Divide valueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Divide(Collections.singletonList(value));
|
||||
}
|
||||
|
||||
@@ -1190,7 +1190,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Divide divideBy(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Divide(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -1202,7 +1202,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Divide divideBy(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Divide(append(expression));
|
||||
}
|
||||
|
||||
@@ -1241,7 +1241,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Exp expValueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Exp(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1253,7 +1253,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Exp expValueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Exp(expression);
|
||||
}
|
||||
|
||||
@@ -1265,7 +1265,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Exp expValueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Exp(value);
|
||||
}
|
||||
}
|
||||
@@ -1294,7 +1294,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Floor floorValueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Floor(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1306,7 +1306,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Floor floorValueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Floor(expression);
|
||||
}
|
||||
|
||||
@@ -1318,7 +1318,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Floor floorValueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Floor(value);
|
||||
}
|
||||
}
|
||||
@@ -1347,7 +1347,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Ln lnValueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Ln(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1359,7 +1359,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Ln lnValueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Ln(expression);
|
||||
}
|
||||
|
||||
@@ -1371,7 +1371,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Ln lnValueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Ln(value);
|
||||
}
|
||||
}
|
||||
@@ -1400,7 +1400,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Log valueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Log(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1412,7 +1412,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Log valueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Log(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -1424,7 +1424,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Log valueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Log(Collections.singletonList(value));
|
||||
}
|
||||
|
||||
@@ -1436,7 +1436,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Log log(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Log(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -1448,7 +1448,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Log log(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Log(append(expression));
|
||||
}
|
||||
|
||||
@@ -1487,7 +1487,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Log10 log10ValueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Log10(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1499,7 +1499,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Log10 log10ValueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Log10(expression);
|
||||
}
|
||||
|
||||
@@ -1511,7 +1511,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Log10 log10ValueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Log10(value);
|
||||
}
|
||||
}
|
||||
@@ -1540,7 +1540,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Mod valueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Mod(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1552,7 +1552,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Mod valueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Mod(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -1564,7 +1564,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Mod valueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Mod(Collections.singletonList(value));
|
||||
}
|
||||
|
||||
@@ -1576,7 +1576,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Mod mod(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Mod(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -1588,7 +1588,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Mod mod(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Mod(append(expression));
|
||||
}
|
||||
|
||||
@@ -1627,7 +1627,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Multiply valueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Multiply(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1639,7 +1639,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Multiply valueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Multiply(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -1651,7 +1651,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Multiply valueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Multiply(Collections.singletonList(value));
|
||||
}
|
||||
|
||||
@@ -1663,7 +1663,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Multiply multiplyBy(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Multiply(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -1675,7 +1675,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Multiply multiplyBy(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Multiply(append(expression));
|
||||
}
|
||||
|
||||
@@ -1714,7 +1714,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Pow valueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Pow(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1726,7 +1726,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Pow valueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Pow(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -1738,7 +1738,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Pow valueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Pow(Collections.singletonList(value));
|
||||
}
|
||||
|
||||
@@ -1750,7 +1750,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Pow pow(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Pow(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -1762,7 +1762,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Pow pow(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Pow(append(expression));
|
||||
}
|
||||
|
||||
@@ -1801,7 +1801,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Sqrt sqrtOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Sqrt(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1813,7 +1813,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Sqrt sqrtOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Sqrt(expression);
|
||||
}
|
||||
|
||||
@@ -1825,7 +1825,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Sqrt sqrtOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Sqrt(value);
|
||||
}
|
||||
}
|
||||
@@ -1854,7 +1854,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Subtract valueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Subtract(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1866,7 +1866,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Subtract valueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Subtract(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -1878,7 +1878,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Subtract valueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Subtract(Collections.singletonList(value));
|
||||
}
|
||||
|
||||
@@ -1890,7 +1890,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Subtract subtract(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Subtract(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -1902,7 +1902,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Subtract subtract(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Subtract(append(expression));
|
||||
}
|
||||
|
||||
@@ -1941,7 +1941,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Trunc truncValueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Trunc(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1953,7 +1953,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Trunc truncValueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Trunc(expression);
|
||||
}
|
||||
|
||||
@@ -1965,7 +1965,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Trunc truncValueOf(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Trunc(value);
|
||||
}
|
||||
}
|
||||
@@ -1997,7 +1997,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Round roundValueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Round(Collections.singletonList(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -2009,7 +2009,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Round roundValueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Round(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -2021,7 +2021,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static Round round(Number value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Round(Collections.singletonList(value));
|
||||
}
|
||||
|
||||
@@ -2043,7 +2043,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Round placeOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Round(append(expression));
|
||||
}
|
||||
|
||||
@@ -2056,7 +2056,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public Round placeOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "fieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "fieldReference must not be null");
|
||||
return new Round(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -2400,7 +2400,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static ASin asinOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new ASin(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -2704,7 +2704,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static ACos acosOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new ACos(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -2905,7 +2905,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static ATan atanOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new ATan(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -2958,7 +2958,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static ATan2 valueOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new ATan2(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -2971,7 +2971,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public static ATan2 valueOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new ATan2((Collections.singletonList(expression)));
|
||||
}
|
||||
|
||||
@@ -2985,7 +2985,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public ATan2 atan2of(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new ATan2(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -2999,7 +2999,7 @@ public class ArithmeticOperators {
|
||||
*/
|
||||
public ATan2 atan2of(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new ATan2(append(expression));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Filter.AsBuilder;
|
||||
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.PropertyExpression;
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
|
||||
@@ -87,7 +88,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ArrayOperatorFactory(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
this.fieldReference = fieldReference;
|
||||
this.expression = null;
|
||||
this.values = null;
|
||||
@@ -100,7 +101,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ArrayOperatorFactory(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
this.fieldReference = null;
|
||||
this.expression = expression;
|
||||
this.values = null;
|
||||
@@ -114,7 +115,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ArrayOperatorFactory(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.notNull(values, "Values must not be null");
|
||||
this.fieldReference = null;
|
||||
this.expression = null;
|
||||
this.values = values;
|
||||
@@ -140,7 +141,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ArrayElemAt elementAt(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createArrayElemAt().elementAt(expression);
|
||||
}
|
||||
|
||||
@@ -153,7 +154,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ArrayElemAt elementAt(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createArrayElemAt().elementAt(fieldReference);
|
||||
}
|
||||
|
||||
@@ -175,7 +176,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ConcatArrays concat(String arrayFieldReference) {
|
||||
|
||||
Assert.notNull(arrayFieldReference, "ArrayFieldReference must not be null!");
|
||||
Assert.notNull(arrayFieldReference, "ArrayFieldReference must not be null");
|
||||
return createConcatArrays().concat(arrayFieldReference);
|
||||
}
|
||||
|
||||
@@ -188,7 +189,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ConcatArrays concat(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createConcatArrays().concat(expression);
|
||||
}
|
||||
|
||||
@@ -213,7 +214,7 @@ public class ArrayOperators {
|
||||
return Filter.filter(fieldReference);
|
||||
}
|
||||
|
||||
Assert.state(values != null, "Values must not be null!");
|
||||
Assert.state(values != null, "Values must not be null");
|
||||
return Filter.filter(new ArrayList<>(values));
|
||||
}
|
||||
|
||||
@@ -224,7 +225,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public IsArray isArray() {
|
||||
|
||||
Assert.state(values == null, "Does it make sense to call isArray on an array? Maybe just skip it?");
|
||||
Assert.state(values == null, "Does it make sense to call isArray on an array; Maybe just skip it");
|
||||
|
||||
return usesFieldRef() ? IsArray.isArray(fieldReference) : IsArray.isArray(expression);
|
||||
}
|
||||
@@ -315,6 +316,21 @@ public class ArrayOperators {
|
||||
.withInitialValue(initialValue).reduce(expressions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that takes the associated array and sorts it by the given {@link Sort order}.
|
||||
*
|
||||
* @return new instance of {@link SortArray}.
|
||||
* @since 4.0
|
||||
*/
|
||||
public SortArray sort(Sort sort) {
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return SortArray.sortArrayOf(fieldReference).by(sort);
|
||||
}
|
||||
|
||||
return (usesExpression() ? SortArray.sortArrayOf(expression) : SortArray.sortArray(values)).by(sort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that transposes an array of input arrays so that the first element of
|
||||
* the output array would be an array containing, the first element of the first input array, the first element of
|
||||
@@ -363,7 +379,7 @@ public class ArrayOperators {
|
||||
|
||||
return usesExpression() ? ArrayToObject.arrayValueOfToObject(expression) : ArrayToObject.arrayToObject(values);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that return the first element in the associated array.
|
||||
* <strong>NOTE:</strong> Requires MongoDB 4.4 or later.
|
||||
@@ -379,7 +395,7 @@ public class ArrayOperators {
|
||||
|
||||
return usesExpression() ? First.firstOf(expression) : First.first(values);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that return the last element in the given array.
|
||||
* <strong>NOTE:</strong> Requires MongoDB 4.4 or later.
|
||||
@@ -450,7 +466,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static ArrayElemAt arrayOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new ArrayElemAt(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -462,7 +478,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static ArrayElemAt arrayOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new ArrayElemAt(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -475,7 +491,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static ArrayElemAt arrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.notNull(values, "Values must not be null");
|
||||
return new ArrayElemAt(Collections.singletonList(values));
|
||||
}
|
||||
|
||||
@@ -497,7 +513,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ArrayElemAt elementAt(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new ArrayElemAt(append(expression));
|
||||
}
|
||||
|
||||
@@ -509,7 +525,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ArrayElemAt elementAt(String arrayFieldReference) {
|
||||
|
||||
Assert.notNull(arrayFieldReference, "ArrayReference must not be null!");
|
||||
Assert.notNull(arrayFieldReference, "ArrayReference must not be null");
|
||||
return new ArrayElemAt(append(Fields.field(arrayFieldReference)));
|
||||
}
|
||||
}
|
||||
@@ -538,7 +554,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static ConcatArrays arrayOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new ConcatArrays(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -550,7 +566,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static ConcatArrays arrayOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new ConcatArrays(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -563,7 +579,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static ConcatArrays arrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.notNull(values, "Values must not be null");
|
||||
return new ConcatArrays(Collections.singletonList(values));
|
||||
}
|
||||
|
||||
@@ -575,7 +591,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ConcatArrays concat(String arrayFieldReference) {
|
||||
|
||||
Assert.notNull(arrayFieldReference, "ArrayFieldReference must not be null!");
|
||||
Assert.notNull(arrayFieldReference, "ArrayFieldReference must not be null");
|
||||
return new ConcatArrays(append(Fields.field(arrayFieldReference)));
|
||||
}
|
||||
|
||||
@@ -587,7 +603,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ConcatArrays concat(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new ConcatArrays(append(expression));
|
||||
}
|
||||
}
|
||||
@@ -617,7 +633,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static AsBuilder filter(String field) {
|
||||
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(field, "Field must not be null");
|
||||
return filter(Fields.field(field));
|
||||
}
|
||||
|
||||
@@ -629,7 +645,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static AsBuilder filter(Field field) {
|
||||
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(field, "Field must not be null");
|
||||
return new FilterExpressionBuilder().filter(field);
|
||||
}
|
||||
|
||||
@@ -641,7 +657,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static AsBuilder filter(List<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.notNull(values, "Values must not be null");
|
||||
return new FilterExpressionBuilder().filter(values);
|
||||
}
|
||||
|
||||
@@ -768,7 +784,7 @@ public class ArrayOperators {
|
||||
@Override
|
||||
public AsBuilder filter(List<?> array) {
|
||||
|
||||
Assert.notNull(array, "Array must not be null!");
|
||||
Assert.notNull(array, "Array must not be null");
|
||||
filter.input = new ArrayList<Object>(array);
|
||||
return this;
|
||||
}
|
||||
@@ -776,7 +792,7 @@ public class ArrayOperators {
|
||||
@Override
|
||||
public AsBuilder filter(Field field) {
|
||||
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(field, "Field must not be null");
|
||||
filter.input = field;
|
||||
return this;
|
||||
}
|
||||
@@ -784,7 +800,7 @@ public class ArrayOperators {
|
||||
@Override
|
||||
public ConditionBuilder as(String variableName) {
|
||||
|
||||
Assert.notNull(variableName, "Variable name must not be null!");
|
||||
Assert.notNull(variableName, "Variable name must not be null");
|
||||
filter.as = new ExposedField(variableName, true);
|
||||
return this;
|
||||
}
|
||||
@@ -792,7 +808,7 @@ public class ArrayOperators {
|
||||
@Override
|
||||
public Filter by(AggregationExpression condition) {
|
||||
|
||||
Assert.notNull(condition, "Condition must not be null!");
|
||||
Assert.notNull(condition, "Condition must not be null");
|
||||
filter.condition = condition;
|
||||
return filter;
|
||||
}
|
||||
@@ -800,7 +816,7 @@ public class ArrayOperators {
|
||||
@Override
|
||||
public Filter by(String expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
filter.condition = expression;
|
||||
return filter;
|
||||
}
|
||||
@@ -808,7 +824,7 @@ public class ArrayOperators {
|
||||
@Override
|
||||
public Filter by(Document expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
filter.condition = expression;
|
||||
return filter;
|
||||
}
|
||||
@@ -839,7 +855,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static IsArray isArray(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new IsArray(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -851,7 +867,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static IsArray isArray(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new IsArray(expression);
|
||||
}
|
||||
}
|
||||
@@ -880,7 +896,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static Size lengthOfArray(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Size(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -892,7 +908,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static Size lengthOfArray(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Size(expression);
|
||||
}
|
||||
|
||||
@@ -905,7 +921,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static Size lengthOfArray(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.notNull(values, "Values must not be null");
|
||||
return new Size(Collections.singletonList(values));
|
||||
}
|
||||
}
|
||||
@@ -934,7 +950,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static Slice sliceArrayOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Slice(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -946,7 +962,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static Slice sliceArrayOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Slice(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
@@ -959,7 +975,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static Slice sliceArrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.notNull(values, "Values must not be null");
|
||||
return new Slice(Collections.singletonList(values));
|
||||
}
|
||||
|
||||
@@ -1029,7 +1045,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static IndexOfArrayBuilder arrayOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new IndexOfArrayBuilder(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1041,7 +1057,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static IndexOfArrayBuilder arrayOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new IndexOfArrayBuilder(expression);
|
||||
}
|
||||
|
||||
@@ -1054,7 +1070,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static IndexOfArrayBuilder arrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.notNull(values, "Values must not be null");
|
||||
return new IndexOfArrayBuilder(values);
|
||||
}
|
||||
|
||||
@@ -1087,7 +1103,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public IndexOfArray indexOf(Object value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new IndexOfArray(Arrays.asList(targetArray, value));
|
||||
}
|
||||
}
|
||||
@@ -1411,8 +1427,8 @@ public class ArrayOperators {
|
||||
|
||||
protected PropertyExpression(String propertyName, AggregationExpression aggregationExpression) {
|
||||
|
||||
Assert.notNull(propertyName, "Property name must not be null!");
|
||||
Assert.notNull(aggregationExpression, "AggregationExpression must not be null!");
|
||||
Assert.notNull(propertyName, "Property name must not be null");
|
||||
Assert.notNull(aggregationExpression, "AggregationExpression must not be null");
|
||||
|
||||
this.propertyName = propertyName;
|
||||
this.aggregationExpression = aggregationExpression;
|
||||
@@ -1559,7 +1575,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static ZipBuilder arrayOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new ZipBuilder(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
@@ -1571,7 +1587,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static ZipBuilder arrayOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new ZipBuilder(expression);
|
||||
}
|
||||
|
||||
@@ -1584,7 +1600,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static ZipBuilder arrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Expression must not be null!");
|
||||
Assert.notNull(values, "Expression must not be null");
|
||||
return new ZipBuilder(values);
|
||||
}
|
||||
|
||||
@@ -1605,7 +1621,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public Zip defaultTo(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Zip(append("defaults", Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -1617,7 +1633,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public Zip defaultTo(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Zip(append("defaults", expression));
|
||||
}
|
||||
|
||||
@@ -1629,7 +1645,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public Zip defaultTo(Object[] array) {
|
||||
|
||||
Assert.notNull(array, "Array must not be null!");
|
||||
Assert.notNull(array, "Array must not be null");
|
||||
return new Zip(append("defaults", Arrays.asList(array)));
|
||||
}
|
||||
|
||||
@@ -1653,7 +1669,7 @@ public class ArrayOperators {
|
||||
*/
|
||||
public Zip zip(Object... arrays) {
|
||||
|
||||
Assert.notNull(arrays, "Arrays must not be null!");
|
||||
Assert.notNull(arrays, "Arrays must not be null");
|
||||
for (Object value : arrays) {
|
||||
|
||||
if (value instanceof String) {
|
||||
@@ -1696,11 +1712,11 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static InBuilder arrayOf(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
|
||||
return value -> {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new In(Arrays.asList(value, Fields.field(fieldReference)));
|
||||
};
|
||||
}
|
||||
@@ -1713,11 +1729,11 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static InBuilder arrayOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
|
||||
return value -> {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
|
||||
return new In(Arrays.asList(value, expression));
|
||||
};
|
||||
@@ -1732,11 +1748,11 @@ public class ArrayOperators {
|
||||
*/
|
||||
public static InBuilder arrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.notNull(values, "Values must not be null");
|
||||
|
||||
return value -> {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
|
||||
return new In(Arrays.asList(value, values));
|
||||
};
|
||||
@@ -1807,7 +1823,7 @@ public class ArrayOperators {
|
||||
return "$arrayToObject";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link AggregationExpression} for {@code $first} that returns the first element in an array. <br />
|
||||
* <strong>NOTE:</strong> Requires MongoDB 4.4 or later.
|
||||
@@ -1861,7 +1877,7 @@ public class ArrayOperators {
|
||||
return "$first";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link AggregationExpression} for {@code $last} that returns the last element in an array. <br />
|
||||
* <strong>NOTE:</strong> Requires MongoDB 4.4 or later.
|
||||
@@ -1915,4 +1931,66 @@ public class ArrayOperators {
|
||||
return "$last";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link AggregationExpression} for {@code $sortArray} that sorts elements in an array. <br />
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 4.0
|
||||
*/
|
||||
public static class SortArray extends AbstractAggregationExpression {
|
||||
|
||||
private SortArray(Object value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given array.
|
||||
*
|
||||
* @param array must not be {@literal null}.
|
||||
* @return new instance of {@link SortArray}.
|
||||
*/
|
||||
public static SortArray sortArray(Object array) {
|
||||
return new SortArray(Collections.singletonMap("input", array));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the elements in the array pointed to by the given {@link Field field reference}.
|
||||
*
|
||||
* @param fieldReference must not be {@literal null}.
|
||||
* @return new instance of {@link SortArray}.
|
||||
*/
|
||||
public static SortArray sortArrayOf(String fieldReference) {
|
||||
return sortArray(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the elements of the array computed buy the given {@link AggregationExpression expression}.
|
||||
*
|
||||
* @param expression must not be {@literal null}.
|
||||
* @return new instance of {@link SortArray}.
|
||||
*/
|
||||
public static SortArray sortArrayOf(AggregationExpression expression) {
|
||||
return sortArray(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the order to put elements in.
|
||||
*
|
||||
* @param sort must not be {@literal null}.
|
||||
* @return new instance of {@link SortArray}.
|
||||
*/
|
||||
public SortArray by(Sort sort) {
|
||||
return new SortArray(append("sortBy", sort));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.aggregation.AbstractAggregationExpression#getMongoMethod()
|
||||
*/
|
||||
@Override
|
||||
protected String getMongoMethod() {
|
||||
return "$sortArray";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.core.aggregation;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
import org.springframework.data.mongodb.util.BsonUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@link AggregationOperation} implementation that can return a {@link Document} from a {@link Bson} or {@link String}
|
||||
* document.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 4.0
|
||||
*/
|
||||
record BasicAggregationOperation(Object value) implements AggregationOperation {
|
||||
|
||||
@Override
|
||||
public Document toDocument(AggregationOperationContext context) {
|
||||
|
||||
if (value instanceof Bson bson) {
|
||||
return BsonUtils.asDocument(bson, context.getCodecRegistry());
|
||||
}
|
||||
|
||||
if (value instanceof String json && BsonUtils.isJsonDocument(json)) {
|
||||
return BsonUtils.parse(json, context);
|
||||
}
|
||||
|
||||
throw new IllegalStateException(
|
||||
String.format("%s cannot be converted to org.bson.Document", ObjectUtils.nullSafeClassName(value)));
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public BooleanOperatorFactory(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
this.fieldReference = fieldReference;
|
||||
this.expression = null;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public BooleanOperatorFactory(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
this.fieldReference = null;
|
||||
this.expression = expression;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public And and(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createAnd().andExpression(expression);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public And and(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createAnd().andField(fieldReference);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public Or or(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return createOr().orExpression(expression);
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public Or or(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return createOr().orField(fieldReference);
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public And andExpression(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new And(append(expression));
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public And andField(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new And(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public And andValue(Object value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new And(append(value));
|
||||
}
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public static Or or(Object... expressions) {
|
||||
|
||||
Assert.notNull(expressions, "Expressions must not be null!");
|
||||
Assert.notNull(expressions, "Expressions must not be null");
|
||||
return new Or(Arrays.asList(expressions));
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public Or orExpression(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Or(append(expression));
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public Or orField(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Or(append(Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public Or orValue(Object value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
return new Or(append(value));
|
||||
}
|
||||
}
|
||||
@@ -333,7 +333,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public static Not not(String fieldReference) {
|
||||
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null");
|
||||
return new Not(asFields(fieldReference));
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ public class BooleanOperators {
|
||||
*/
|
||||
public static Not not(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
Assert.notNull(expression, "Expression must not be null");
|
||||
return new Not(Collections.singletonList(expression));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class BucketAutoOperation extends BucketOperationSupport<BucketAutoOperat
|
||||
|
||||
super(groupByField);
|
||||
|
||||
Assert.isTrue(buckets > 0, "Number of buckets must be greater 0!");
|
||||
Assert.isTrue(buckets > 0, "Number of buckets must be greater 0");
|
||||
|
||||
this.buckets = buckets;
|
||||
this.granularity = null;
|
||||
@@ -66,7 +66,7 @@ public class BucketAutoOperation extends BucketOperationSupport<BucketAutoOperat
|
||||
|
||||
super(groupByExpression);
|
||||
|
||||
Assert.isTrue(buckets > 0, "Number of buckets must be greater 0!");
|
||||
Assert.isTrue(buckets > 0, "Number of buckets must be greater 0");
|
||||
|
||||
this.buckets = buckets;
|
||||
this.granularity = null;
|
||||
@@ -117,7 +117,7 @@ public class BucketAutoOperation extends BucketOperationSupport<BucketAutoOperat
|
||||
*/
|
||||
public BucketAutoOperation withBuckets(int buckets) {
|
||||
|
||||
Assert.isTrue(buckets > 0, "Number of buckets must be greater 0!");
|
||||
Assert.isTrue(buckets > 0, "Number of buckets must be greater 0");
|
||||
return new BucketAutoOperation(this, buckets, granularity);
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ public class BucketAutoOperation extends BucketOperationSupport<BucketAutoOperat
|
||||
*/
|
||||
public BucketAutoOperation withGranularity(Granularity granularity) {
|
||||
|
||||
Assert.notNull(granularity, "Granularity must not be null!");
|
||||
Assert.notNull(granularity, "Granularity must not be null");
|
||||
|
||||
return new BucketAutoOperation(this, buckets, granularity.getMongoRepresentation());
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ public class BucketOperation extends BucketOperationSupport<BucketOperation, Buc
|
||||
*/
|
||||
public BucketOperation withDefaultBucket(Object literal) {
|
||||
|
||||
Assert.notNull(literal, "Default bucket literal must not be null!");
|
||||
Assert.notNull(literal, "Default bucket literal must not be null");
|
||||
return new BucketOperation(this, boundaries, literal);
|
||||
}
|
||||
|
||||
@@ -126,8 +126,8 @@ public class BucketOperation extends BucketOperationSupport<BucketOperation, Buc
|
||||
*/
|
||||
public BucketOperation withBoundaries(Object... boundaries) {
|
||||
|
||||
Assert.notNull(boundaries, "Boundaries must not be null!");
|
||||
Assert.noNullElements(boundaries, "Boundaries must not contain null values!");
|
||||
Assert.notNull(boundaries, "Boundaries must not be null");
|
||||
Assert.noNullElements(boundaries, "Boundaries must not contain null values");
|
||||
|
||||
List<Object> newBoundaries = new ArrayList<Object>(this.boundaries.size() + boundaries.length);
|
||||
newBoundaries.addAll(this.boundaries);
|
||||
|
||||
@@ -51,7 +51,7 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
|
||||
*/
|
||||
protected BucketOperationSupport(Field groupByField) {
|
||||
|
||||
Assert.notNull(groupByField, "Group by field must not be null!");
|
||||
Assert.notNull(groupByField, "Group by field must not be null");
|
||||
|
||||
this.groupByField = groupByField;
|
||||
this.groupByExpression = null;
|
||||
@@ -65,7 +65,7 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
|
||||
*/
|
||||
protected BucketOperationSupport(AggregationExpression groupByExpression) {
|
||||
|
||||
Assert.notNull(groupByExpression, "Group by AggregationExpression must not be null!");
|
||||
Assert.notNull(groupByExpression, "Group by AggregationExpression must not be null");
|
||||
|
||||
this.groupByExpression = groupByExpression;
|
||||
this.groupByField = null;
|
||||
@@ -89,8 +89,8 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
|
||||
*/
|
||||
protected BucketOperationSupport(BucketOperationSupport<?, ?> operationSupport, Outputs outputs) {
|
||||
|
||||
Assert.notNull(operationSupport, "BucketOperationSupport must not be null!");
|
||||
Assert.notNull(outputs, "Outputs must not be null!");
|
||||
Assert.notNull(operationSupport, "BucketOperationSupport must not be null");
|
||||
Assert.notNull(outputs, "Outputs must not be null");
|
||||
|
||||
this.groupByField = operationSupport.groupByField;
|
||||
this.groupByExpression = operationSupport.groupByExpression;
|
||||
@@ -213,8 +213,8 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
|
||||
*/
|
||||
protected OutputBuilder(Object value, T operation) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null or empty!");
|
||||
Assert.notNull(operation, "ProjectionOperation must not be null!");
|
||||
Assert.notNull(value, "Value must not be null or empty");
|
||||
Assert.notNull(operation, "ProjectionOperation must not be null");
|
||||
|
||||
this.value = value;
|
||||
this.operation = operation;
|
||||
@@ -321,8 +321,8 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
|
||||
*/
|
||||
public B apply(String operation, Object... values) {
|
||||
|
||||
Assert.hasText(operation, "Operation must not be empty or null!");
|
||||
Assert.notNull(value, "Values must not be null!");
|
||||
Assert.hasText(operation, "Operation must not be empty or null");
|
||||
Assert.notNull(value, "Values must not be null");
|
||||
|
||||
List<Object> objects = new ArrayList<Object>(values.length + 1);
|
||||
objects.add(value);
|
||||
@@ -355,7 +355,7 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
|
||||
}
|
||||
|
||||
if (value instanceof Field) {
|
||||
throw new IllegalStateException("Cannot add a field as top-level output. Use accumulator expressions.");
|
||||
throw new IllegalStateException("Cannot add a field as top-level output; Use accumulator expressions");
|
||||
}
|
||||
|
||||
return this.operation
|
||||
@@ -437,7 +437,7 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
|
||||
*/
|
||||
protected Outputs and(Output output) {
|
||||
|
||||
Assert.notNull(output, "BucketOutput must not be null!");
|
||||
Assert.notNull(output, "BucketOutput must not be null");
|
||||
return new Outputs(this.outputs, output);
|
||||
}
|
||||
|
||||
@@ -480,7 +480,7 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
|
||||
*/
|
||||
protected Output(Field field) {
|
||||
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(field, "Field must not be null");
|
||||
this.field = new ExposedField(field, true);
|
||||
}
|
||||
|
||||
@@ -516,8 +516,8 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
|
||||
|
||||
super(Fields.field(operation));
|
||||
|
||||
Assert.hasText(operation, "Operation must not be null or empty!");
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.hasText(operation, "Operation must not be null or empty");
|
||||
Assert.notNull(values, "Values must not be null");
|
||||
|
||||
this.operation = operation;
|
||||
this.values = new ArrayList<Object>(values);
|
||||
@@ -616,8 +616,8 @@ public abstract class BucketOperationSupport<T extends BucketOperationSupport<T,
|
||||
|
||||
super(Fields.field(expression));
|
||||
|
||||
Assert.hasText(expression, "Expression must not be null!");
|
||||
Assert.notNull(parameters, "Parameters must not be null!");
|
||||
Assert.hasText(expression, "Expression must not be null");
|
||||
Assert.notNull(parameters, "Parameters must not be null");
|
||||
|
||||
this.expression = expression;
|
||||
this.params = parameters.clone();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user