Compare commits
146 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b502a095f | ||
|
|
7552329598 | ||
|
|
fa4f8bfe9f | ||
|
|
58fde292d5 | ||
|
|
e71f8b34be | ||
|
|
152d84a200 | ||
|
|
ddf77d55ff | ||
|
|
2acf1bc5d4 | ||
|
|
26f230036a | ||
|
|
3ee696dab2 | ||
|
|
7ee12e9637 | ||
|
|
414d716c07 | ||
|
|
5f9e25cd8a | ||
|
|
caa2dd4e85 | ||
|
|
28fc1e4823 | ||
|
|
d62639d11c | ||
|
|
b13e47d8ac | ||
|
|
3743ca56df | ||
|
|
0f974130d1 | ||
|
|
020da42800 | ||
|
|
4307b4cd91 | ||
|
|
af874b635c | ||
|
|
017e01810d | ||
|
|
05b46779cb | ||
|
|
ba56d247c9 | ||
|
|
4484dac574 | ||
|
|
af4b1788fc | ||
|
|
af40f15a36 | ||
|
|
193b7de2d9 | ||
|
|
f5204e859f | ||
|
|
16818324d8 | ||
|
|
a9269c0086 | ||
|
|
d3624b9af4 | ||
|
|
3711ed5b50 | ||
|
|
c20feabada | ||
|
|
f93e40fdee | ||
|
|
dca508f3dc | ||
|
|
742448a281 | ||
|
|
1a4749e97c | ||
|
|
a3cbe829b2 | ||
|
|
4ca6f29666 | ||
|
|
df65644d59 | ||
|
|
05a169c858 | ||
|
|
e49119038d | ||
|
|
f2df84e8c4 | ||
|
|
1504fd0529 | ||
|
|
f63610c925 | ||
|
|
06eb52cf13 | ||
|
|
c9a4a8a370 | ||
|
|
8d17ddb92c | ||
|
|
0e96ef2d0c | ||
|
|
4d8b965176 | ||
|
|
37bb390447 | ||
|
|
5c79e1e4ef | ||
|
|
9b41d70f75 | ||
|
|
b2e52ab28f | ||
|
|
fed33444e9 | ||
|
|
a4ad37703f | ||
|
|
42e95e9600 | ||
|
|
ed894aa51a | ||
|
|
693ff04294 | ||
|
|
b018b31e20 | ||
|
|
bacb75d098 | ||
|
|
ec0fe6f994 | ||
|
|
d3d690b908 | ||
|
|
b98b5125f1 | ||
|
|
d68bd4b44a | ||
|
|
a73ae9a1a5 | ||
|
|
ac3c578e93 | ||
|
|
9872f8cb07 | ||
|
|
1b1ab2c495 | ||
|
|
6554274dde | ||
|
|
34f91acbfe | ||
|
|
8e7d508cfe | ||
|
|
04dd78cb36 | ||
|
|
52c554cfe1 | ||
|
|
c1bb8c4ba5 | ||
|
|
ed9a367bb8 | ||
|
|
b88ce46239 | ||
|
|
42ec94d321 | ||
|
|
53f35e185f | ||
|
|
e08bfd253c | ||
|
|
caaafa275d | ||
|
|
1f082abc7f | ||
|
|
df77fcc19d | ||
|
|
007b965673 | ||
|
|
1b9680cece | ||
|
|
13f1d21919 | ||
|
|
4c10bf30bc | ||
|
|
8f78d0e0d8 | ||
|
|
56115a263c | ||
|
|
66b809318a | ||
|
|
bfff60d915 | ||
|
|
051e973226 | ||
|
|
eb61629f10 | ||
|
|
85783e5354 | ||
|
|
433b012b91 | ||
|
|
8dca0049ca | ||
|
|
635f3b82be | ||
|
|
e69c7e1134 | ||
|
|
1f94e74b75 | ||
|
|
98858e0f5f | ||
|
|
90f311de51 | ||
|
|
7f7015fd86 | ||
|
|
ab9c5d73a0 | ||
|
|
13caa162db | ||
|
|
d5d620d777 | ||
|
|
21d50f2a72 | ||
|
|
4912d62be6 | ||
|
|
2bf6f226d6 | ||
|
|
1a6f7e371a | ||
|
|
2ef5d795ce | ||
|
|
e3d2f16202 | ||
|
|
c44232ff39 | ||
|
|
385e911708 | ||
|
|
171d8b2b1e | ||
|
|
7ac7eefad6 | ||
|
|
7a39e94e4b | ||
|
|
25733664b3 | ||
|
|
81da10f499 | ||
|
|
bde114ed19 | ||
|
|
a2403f58ec | ||
|
|
875b8eda9f | ||
|
|
fc0a021937 | ||
|
|
a6aa174ff5 | ||
|
|
8b36617752 | ||
|
|
56e8799c22 | ||
|
|
88e60070d6 | ||
|
|
6c7039580f | ||
|
|
fba003f215 | ||
|
|
1a3239554c | ||
|
|
37b541931d | ||
|
|
9038280f68 | ||
|
|
75935a2bdb | ||
|
|
d9ca3d7eb3 | ||
|
|
04e77ad5ab | ||
|
|
0ab39a17a7 | ||
|
|
49a6f13797 | ||
|
|
b0fd6f691b | ||
|
|
b5778772d9 | ||
|
|
0f55fb305d | ||
|
|
5ae7547465 | ||
|
|
cf4e04a30e | ||
|
|
89c1dc77d9 | ||
|
|
a2c842b59b | ||
|
|
0cd0be9478 |
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -6,6 +6,7 @@ Make sure that:
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
- [ ] You have read the [Spring Data contribution guidelines](https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.adoc).
|
- [ ] You have read the [Spring Data contribution guidelines](https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.adoc).
|
||||||
|
- [ ] There is a ticket in the bug tracker for the project in our [JIRA](https://jira.spring.io/browse/DATAMONGO).
|
||||||
- [ ] You use the code formatters provided [here](https://github.com/spring-projects/spring-data-build/tree/master/etc/ide) and have them applied to your changes. Don’t submit any formatting related changes.
|
- [ ] You use the code formatters provided [here](https://github.com/spring-projects/spring-data-build/tree/master/etc/ide) and have them applied to your changes. Don’t submit any formatting related changes.
|
||||||
- [ ] You submit test cases (unit or integration tests) that back your changes.
|
- [ ] You submit test cases (unit or integration tests) that back your changes.
|
||||||
- [ ] You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).
|
- [ ] You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).
|
||||||
|
|||||||
47
.github/workflows/project.yml
vendored
47
.github/workflows/project.yml
vendored
@@ -1,47 +0,0 @@
|
|||||||
# GitHub Actions to automate GitHub issues for Spring Data Project Management
|
|
||||||
|
|
||||||
name: Spring Data GitHub Issues
|
|
||||||
|
|
||||||
on:
|
|
||||||
issues:
|
|
||||||
types: [opened, edited, reopened]
|
|
||||||
issue_comment:
|
|
||||||
types: [created]
|
|
||||||
pull_request_target:
|
|
||||||
types: [opened, edited, reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
Inbox:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.repository_owner == 'spring-projects' && (github.event.action == 'opened' || github.event.action == 'reopened') && github.event.pull_request == null
|
|
||||||
steps:
|
|
||||||
- name: Create or Update Issue Card
|
|
||||||
uses: peter-evans/create-or-update-project-card@v1.1.2
|
|
||||||
with:
|
|
||||||
project-name: 'Spring Data'
|
|
||||||
column-name: 'Inbox'
|
|
||||||
project-location: 'spring-projects'
|
|
||||||
token: ${{ secrets.GH_ISSUES_TOKEN_SPRING_DATA }}
|
|
||||||
Pull-Request:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.repository_owner == 'spring-projects' && (github.event.action == 'opened' || github.event.action == 'reopened') && github.event.pull_request != null
|
|
||||||
steps:
|
|
||||||
- name: Create or Update Pull Request Card
|
|
||||||
uses: peter-evans/create-or-update-project-card@v1.1.2
|
|
||||||
with:
|
|
||||||
project-name: 'Spring Data'
|
|
||||||
column-name: 'Review pending'
|
|
||||||
project-location: 'spring-projects'
|
|
||||||
issue-number: ${{ github.event.pull_request.number }}
|
|
||||||
token: ${{ secrets.GH_ISSUES_TOKEN_SPRING_DATA }}
|
|
||||||
Feedback-Provided:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.repository_owner == 'spring-projects' && github.event_name == 'issue_comment' && github.event.action == 'created' && github.actor != 'spring-projects-issues' && github.event.pull_request == null && github.event.issue.state == 'open' && contains(toJSON(github.event.issue.labels), 'waiting-for-feedback')
|
|
||||||
steps:
|
|
||||||
- name: Update Project Card
|
|
||||||
uses: peter-evans/create-or-update-project-card@v1.1.2
|
|
||||||
with:
|
|
||||||
project-name: 'Spring Data'
|
|
||||||
column-name: 'Feedback provided'
|
|
||||||
project-location: 'spring-projects'
|
|
||||||
token: ${{ secrets.GH_ISSUES_TOKEN_SPRING_DATA }}
|
|
||||||
3
.mvn/wrapper/maven-wrapper.properties
vendored
3
.mvn/wrapper/maven-wrapper.properties
vendored
@@ -1,2 +1 @@
|
|||||||
#Mon Oct 11 14:30:24 CEST 2021
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
|
||||||
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip
|
|
||||||
2
CI.adoc
2
CI.adoc
@@ -1,6 +1,6 @@
|
|||||||
= Continuous Integration
|
= Continuous Integration
|
||||||
|
|
||||||
image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-mongodb%2Fmain&subject=Moore%20(main)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-mongodb/]
|
image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-mongodb%2Fmaster&subject=Moore%20(master)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-mongodb/]
|
||||||
image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-mongodb%2F2.1.x&subject=Lovelace%20(2.1.x)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-mongodb/]
|
image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-mongodb%2F2.1.x&subject=Lovelace%20(2.1.x)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-mongodb/]
|
||||||
image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-mongodb%2F1.10.x&subject=Ingalls%20(1.10.x)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-mongodb/]
|
image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-mongodb%2F1.10.x&subject=Ingalls%20(1.10.x)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-mongodb/]
|
||||||
|
|
||||||
|
|||||||
27
CODE_OF_CONDUCT.adoc
Normal file
27
CODE_OF_CONDUCT.adoc
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
= Contributor Code of Conduct
|
||||||
|
|
||||||
|
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||||
|
|
||||||
|
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery
|
||||||
|
* Personal attacks
|
||||||
|
* Trolling or insulting/derogatory comments
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing other's private information, such as physical or electronic addresses,
|
||||||
|
without explicit permission
|
||||||
|
* Other unethical or unprofessional conduct
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at spring-code-of-conduct@pivotal.io.
|
||||||
|
All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
|
||||||
|
Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/].
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
= Spring Data contribution guidelines
|
= Spring Data contribution guidelines
|
||||||
|
|
||||||
You find the contribution guidelines for Spring Data projects https://github.com/spring-projects/spring-data-build/blob/main/CONTRIBUTING.adoc[here].
|
You find the contribution guidelines for Spring Data projects https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.adoc[here].
|
||||||
|
|||||||
128
Jenkinsfile
vendored
128
Jenkinsfile
vendored
@@ -3,7 +3,7 @@ pipeline {
|
|||||||
|
|
||||||
triggers {
|
triggers {
|
||||||
pollSCM 'H/10 * * * *'
|
pollSCM 'H/10 * * * *'
|
||||||
upstream(upstreamProjects: "spring-data-commons/main", threshold: hudson.model.Result.SUCCESS)
|
upstream(upstreamProjects: "spring-data-commons/2.3.x", threshold: hudson.model.Result.SUCCESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
options {
|
options {
|
||||||
@@ -14,32 +14,48 @@ pipeline {
|
|||||||
stages {
|
stages {
|
||||||
stage("Docker images") {
|
stage("Docker images") {
|
||||||
parallel {
|
parallel {
|
||||||
stage('Publish JDK 17 + MongoDB 4.4') {
|
stage('Publish JDK 8 + MongoDB 4.0') {
|
||||||
when {
|
when {
|
||||||
changeset "ci/openjdk17-mongodb-4.4/**"
|
changeset "ci/openjdk8-mongodb-4.0/**"
|
||||||
}
|
}
|
||||||
agent { label 'data' }
|
agent { label 'data' }
|
||||||
options { timeout(time: 30, unit: 'MINUTES') }
|
options { timeout(time: 30, unit: 'MINUTES') }
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
def image = docker.build("springci/spring-data-openjdk17-with-mongodb-4.4.4", "ci/openjdk17-mongodb-4.4/")
|
def image = docker.build("springci/spring-data-openjdk8-with-mongodb-4.0", "ci/openjdk8-mongodb-4.0/")
|
||||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
||||||
image.push()
|
image.push()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Publish JDK 17 + MongoDB 5.0') {
|
stage('Publish JDK 8 + MongoDB 4.2') {
|
||||||
when {
|
when {
|
||||||
changeset "ci/openjdk17-mongodb-5.0/**"
|
changeset "ci/openjdk8-mongodb-4.2/**"
|
||||||
}
|
}
|
||||||
agent { label 'data' }
|
agent { label 'data' }
|
||||||
options { timeout(time: 30, unit: 'MINUTES') }
|
options { timeout(time: 30, unit: 'MINUTES') }
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
def image = docker.build("springci/spring-data-openjdk17-with-mongodb-5.0.3", "ci/openjdk17-mongodb-5.0/")
|
def image = docker.build("springci/spring-data-openjdk8-with-mongodb-4.2.0", "ci/openjdk8-mongodb-4.2/")
|
||||||
|
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
||||||
|
image.push()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Publish JDK 14 + MongoDB 4.2') {
|
||||||
|
when {
|
||||||
|
changeset "ci/openjdk14-mongodb-4.2/**"
|
||||||
|
}
|
||||||
|
agent { label 'data' }
|
||||||
|
options { timeout(time: 30, unit: 'MINUTES') }
|
||||||
|
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def image = docker.build("springci/spring-data-openjdk14-with-mongodb-4.2.0", "ci/openjdk14-mongodb-4.2/")
|
||||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
||||||
image.push()
|
image.push()
|
||||||
}
|
}
|
||||||
@@ -49,11 +65,10 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage("test: baseline Mongo 5.0 (jdk17)") {
|
stage("test: baseline (jdk8)") {
|
||||||
when {
|
when {
|
||||||
beforeAgent(true)
|
|
||||||
anyOf {
|
anyOf {
|
||||||
branch(pattern: "main|(\\d\\.\\d\\.x)", comparator: "REGEXP")
|
branch '3.0.x'
|
||||||
not { triggeredBy 'UpstreamCause' }
|
not { triggeredBy 'UpstreamCause' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +82,7 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
||||||
docker.image('springci/spring-data-openjdk17-with-mongodb-5.0.3:latest').inside('-v $HOME:/tmp/jenkins-home') {
|
docker.image('springci/spring-data-openjdk8-with-mongodb-4.2.0:latest').inside('-v $HOME:/tmp/jenkins-home') {
|
||||||
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
|
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 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
|
||||||
sh 'sleep 10'
|
sh 'sleep 10'
|
||||||
@@ -82,14 +97,13 @@ pipeline {
|
|||||||
|
|
||||||
stage("Test other configurations") {
|
stage("Test other configurations") {
|
||||||
when {
|
when {
|
||||||
beforeAgent(true)
|
anyOf {
|
||||||
allOf {
|
branch '3.0.x'
|
||||||
branch(pattern: "main|(\\d\\.\\d\\.x)", comparator: "REGEXP")
|
|
||||||
not { triggeredBy 'UpstreamCause' }
|
not { triggeredBy 'UpstreamCause' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parallel {
|
parallel {
|
||||||
stage("test: baseline MongoDB 4.4 (jdk17)") {
|
stage("test: mongodb 4.0 (jdk8)") {
|
||||||
agent {
|
agent {
|
||||||
label 'data'
|
label 'data'
|
||||||
}
|
}
|
||||||
@@ -100,7 +114,7 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
||||||
docker.image('springci/spring-data-openjdk17-with-mongodb-4.4.4:latest').inside('-v $HOME:/tmp/jenkins-home') {
|
docker.image('springci/spring-data-openjdk8-with-mongodb-4.0:latest').inside('-v $HOME:/tmp/jenkins-home') {
|
||||||
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
|
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 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
|
||||||
sh 'sleep 10'
|
sh 'sleep 10'
|
||||||
@@ -112,14 +126,61 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stage("test: mongodb 4.2 (jdk8)") {
|
||||||
|
agent {
|
||||||
|
label 'data'
|
||||||
|
}
|
||||||
|
options { timeout(time: 30, unit: 'MINUTES') }
|
||||||
|
environment {
|
||||||
|
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
||||||
|
docker.image('springci/spring-data-openjdk8-with-mongodb-4.2.0:latest').inside('-v $HOME:/tmp/jenkins-home') {
|
||||||
|
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: baseline (jdk14)") {
|
||||||
|
agent {
|
||||||
|
label 'data'
|
||||||
|
}
|
||||||
|
options { timeout(time: 30, unit: 'MINUTES') }
|
||||||
|
environment {
|
||||||
|
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
||||||
|
docker.image('springci/spring-data-openjdk15-with-mongodb-4.2.0:latest').inside('-v $HOME:/tmp/jenkins-home') {
|
||||||
|
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
|
||||||
|
sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
|
||||||
|
sh 'sleep 10'
|
||||||
|
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
|
||||||
|
sh 'sleep 15'
|
||||||
|
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pjava11 clean dependency:list test -Duser.name=jenkins -Dsort -U -B'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Release to artifactory') {
|
stage('Release to artifactory') {
|
||||||
when {
|
when {
|
||||||
beforeAgent(true)
|
|
||||||
anyOf {
|
anyOf {
|
||||||
branch(pattern: "main|(\\d\\.\\d\\.x)", comparator: "REGEXP")
|
branch '3.0.x'
|
||||||
not { triggeredBy 'UpstreamCause' }
|
not { triggeredBy 'UpstreamCause' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,7 +196,7 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
||||||
docker.image('openjdk:17-bullseye').inside('-v $HOME:/tmp/jenkins-home') {
|
docker.image('adoptopenjdk/openjdk8:latest').inside('-v $HOME:/tmp/jenkins-home') {
|
||||||
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory ' +
|
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory ' +
|
||||||
'-Dartifactory.server=https://repo.spring.io ' +
|
'-Dartifactory.server=https://repo.spring.io ' +
|
||||||
"-Dartifactory.username=${ARTIFACTORY_USR} " +
|
"-Dartifactory.username=${ARTIFACTORY_USR} " +
|
||||||
@@ -149,6 +210,35 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stage('Publish documentation') {
|
||||||
|
when {
|
||||||
|
branch '3.0.x'
|
||||||
|
}
|
||||||
|
agent {
|
||||||
|
label 'data'
|
||||||
|
}
|
||||||
|
options { timeout(time: 20, unit: 'MINUTES') }
|
||||||
|
|
||||||
|
environment {
|
||||||
|
ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c')
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
||||||
|
docker.image('adoptopenjdk/openjdk8:latest').inside('-v $HOME:/tmp/jenkins-home') {
|
||||||
|
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,distribute ' +
|
||||||
|
'-Dartifactory.server=https://repo.spring.io ' +
|
||||||
|
"-Dartifactory.username=${ARTIFACTORY_USR} " +
|
||||||
|
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
|
||||||
|
"-Dartifactory.distribution-repository=temp-private-local " +
|
||||||
|
'-Dmaven.test.skip=true clean deploy -U -B'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
post {
|
||||||
|
|||||||
125
README.adoc
125
README.adoc
@@ -1,6 +1,6 @@
|
|||||||
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://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]
|
||||||
|
|
||||||
= 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]]
|
= Spring Data MongoDB image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-mongodb%2Fmaster&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://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.
|
||||||
|
|
||||||
@@ -8,12 +8,10 @@ The Spring Data MongoDB project aims to provide a familiar and consistent Spring
|
|||||||
The Spring Data MongoDB project provides integration with the MongoDB document database.
|
The Spring Data MongoDB project provides integration with the MongoDB document database.
|
||||||
Key functional areas of Spring Data MongoDB are a POJO centric model for interacting with a MongoDB `+Document+` and easily writing a repository style data access layer.
|
Key functional areas of Spring Data MongoDB are a POJO centric model for interacting with a MongoDB `+Document+` and easily writing a repository style data access layer.
|
||||||
|
|
||||||
[[code-of-conduct]]
|
|
||||||
== Code of Conduct
|
== Code of Conduct
|
||||||
|
|
||||||
This project is governed by the https://github.com/spring-projects/.github/blob/e3cc2ff230d8f1dca06535aa6b5a4a23815861d4/CODE_OF_CONDUCT.md[Spring Code of Conduct]. By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
This project is governed by the link:CODE_OF_CONDUCT.adoc[Spring Code of Conduct]. By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||||
|
|
||||||
[[getting-started]]
|
|
||||||
== Getting Started
|
== Getting Started
|
||||||
|
|
||||||
Here is a quick teaser of an application using Spring Data Repositories in Java:
|
Here is a quick teaser of an application using Spring Data Repositories in Java:
|
||||||
@@ -61,7 +59,6 @@ class ApplicationConfig extends AbstractMongoClientConfiguration {
|
|||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
[[maven-configuration]]
|
|
||||||
=== Maven configuration
|
=== Maven configuration
|
||||||
|
|
||||||
Add the Maven dependency:
|
Add the Maven dependency:
|
||||||
@@ -71,25 +68,24 @@ Add the Maven dependency:
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb</artifactId>
|
<artifactId>spring-data-mongodb</artifactId>
|
||||||
<version>${version}</version>
|
<version>${version}.RELEASE</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
----
|
----
|
||||||
|
|
||||||
If you'd rather like the latest snapshots of the upcoming major version, use our Maven snapshot repository
|
If you'd rather like the latest snapshots of the upcoming major version, use our Maven snapshot repository and declare the appropriate dependency version.
|
||||||
and declare the appropriate dependency version.
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb</artifactId>
|
<artifactId>spring-data-mongodb</artifactId>
|
||||||
<version>${version}-SNAPSHOT</version>
|
<version>${version}.BUILD-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
<id>spring-snapshot</id>
|
<id>spring-libs-snapshot</id>
|
||||||
<name>Spring Snapshot Repository</name>
|
<name>Spring Snapshot Repository</name>
|
||||||
<url>https://repo.spring.io/snapshot</url>
|
<url>https://repo.spring.io/libs-snapshot</url>
|
||||||
</repository>
|
</repository>
|
||||||
----
|
----
|
||||||
|
|
||||||
@@ -102,7 +98,7 @@ Some of the changes affect the initial setup configuration as well as compile/ru
|
|||||||
|
|
||||||
.Changed XML Namespace Elements and Attributes:
|
.Changed XML Namespace Elements and Attributes:
|
||||||
|===
|
|===
|
||||||
| Element / Attribute | 2.x | 3.x
|
Element / Attribute | 2.x | 3.x
|
||||||
|
|
||||||
| `<mongo:mongo-client />`
|
| `<mongo:mongo-client />`
|
||||||
| Used to create a `com.mongodb.MongoClient`
|
| Used to create a `com.mongodb.MongoClient`
|
||||||
@@ -120,7 +116,7 @@ Use `<mongo:client-settings cluster-hosts="..." />` instead
|
|||||||
|
|
||||||
.Removed XML Namespace Elements and Attributes:
|
.Removed XML Namespace Elements and Attributes:
|
||||||
|===
|
|===
|
||||||
| Element / Attribute | Replacement in 3.x | Comment
|
Element / Attribute | Replacement in 3.x | Comment
|
||||||
|
|
||||||
| `<mongo:db-factory mongo-ref="..." />`
|
| `<mongo:db-factory mongo-ref="..." />`
|
||||||
| `<mongo:db-factory mongo-client-ref="..." />`
|
| `<mongo:db-factory mongo-client-ref="..." />`
|
||||||
@@ -137,7 +133,7 @@ Use `<mongo:client-settings cluster-hosts="..." />` instead
|
|||||||
|
|
||||||
.New XML Namespace Elements and Attributes:
|
.New XML Namespace Elements and Attributes:
|
||||||
|===
|
|===
|
||||||
| Element | Comment
|
Element | Comment
|
||||||
|
|
||||||
| `<mongo:db-factory mongo-client-ref="..." />`
|
| `<mongo:db-factory mongo-client-ref="..." />`
|
||||||
| Replacement for `<mongo:db-factory mongo-ref="..." />`
|
| Replacement for `<mongo:db-factory mongo-ref="..." />`
|
||||||
@@ -157,7 +153,7 @@ Use `<mongo:client-settings cluster-hosts="..." />` instead
|
|||||||
|
|
||||||
.Java API changes
|
.Java API changes
|
||||||
|===
|
|===
|
||||||
| Type | Comment
|
Type | Comment
|
||||||
|
|
||||||
| `MongoClientFactoryBean`
|
| `MongoClientFactoryBean`
|
||||||
| Creates `com.mongodb.client.MongoClient` instead of `com.mongodb.MongoClient` +
|
| Creates `com.mongodb.client.MongoClient` instead of `com.mongodb.MongoClient` +
|
||||||
@@ -178,7 +174,7 @@ Uses `MongoClientSettings` instead of `MongoClientOptions`.
|
|||||||
|
|
||||||
.Removed Java API:
|
.Removed Java API:
|
||||||
|===
|
|===
|
||||||
| 2.x | Replacement in 3.x | Comment
|
2.x | Replacement in 3.x | Comment
|
||||||
|
|
||||||
| `MongoClientOptionsFactoryBean`
|
| `MongoClientOptionsFactoryBean`
|
||||||
| `MongoClientSettingsFactoryBean`
|
| `MongoClientSettingsFactoryBean`
|
||||||
@@ -230,7 +226,6 @@ static class Config extends AbstractMongoClientConfiguration {
|
|||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
[[getting-help]]
|
|
||||||
== Getting Help
|
== Getting Help
|
||||||
|
|
||||||
Having trouble with Spring Data? We’d love to help!
|
Having trouble with Spring Data? We’d love to help!
|
||||||
@@ -244,7 +239,6 @@ If you are just starting out with Spring, try one of the https://spring.io/guide
|
|||||||
You can also chat with the community on https://gitter.im/spring-projects/spring-data[Gitter].
|
You can also chat with the community on https://gitter.im/spring-projects/spring-data[Gitter].
|
||||||
* Report bugs with Spring Data MongoDB at https://github.com/spring-projects/spring-data-mongodb/issues[github.com/spring-projects/spring-data-mongodb/issues].
|
* Report bugs with Spring Data MongoDB at https://github.com/spring-projects/spring-data-mongodb/issues[github.com/spring-projects/spring-data-mongodb/issues].
|
||||||
|
|
||||||
[[reporting-issues]]
|
|
||||||
== Reporting Issues
|
== Reporting Issues
|
||||||
|
|
||||||
Spring Data uses Github as issue tracking system to record bugs and feature requests.
|
Spring Data uses Github as issue tracking system to record bugs and feature requests.
|
||||||
@@ -255,86 +249,10 @@ If you want to raise an issue, please follow the recommendations below:
|
|||||||
* Please provide as much information as possible with the issue report, we like to know the version of Spring Data that you are using, the JVM version, Stacktrace, etc.
|
* Please provide as much information as possible with the issue report, we like to know the version of Spring Data that you are using, the JVM version, Stacktrace, etc.
|
||||||
* If you need to paste code, or include a stack trace use https://guides.github.com/features/mastering-markdown/[Markdown] code fences +++```+++.
|
* If you need to paste code, or include a stack trace use https://guides.github.com/features/mastering-markdown/[Markdown] code fences +++```+++.
|
||||||
|
|
||||||
[[guides]]
|
|
||||||
== Guides
|
|
||||||
|
|
||||||
The https://spring.io/[spring.io] site contains several guides that show how to use Spring Data step-by-step:
|
|
||||||
|
|
||||||
* https://spring.io/guides/gs/accessing-data-mongodb/[Accessing Data with MongoDB] is a very basic guide that shows you how to create a simple application and how to access data using repositories.
|
|
||||||
* https://spring.io/guides/gs/accessing-mongodb-data-rest/[Accessing MongoDB Data with REST] is a guide to creating a REST web service exposing data stored in MongoDB through repositories.
|
|
||||||
|
|
||||||
[[examples]]
|
|
||||||
== Examples
|
|
||||||
|
|
||||||
* https://github.com/spring-projects/spring-data-examples/[Spring Data Examples] contains example projects that explain specific features in more detail.
|
|
||||||
|
|
||||||
[[building-from-source]]
|
|
||||||
== Building from Source
|
== Building from Source
|
||||||
|
|
||||||
You do not need to build from source to use Spring Data. Binaries are available in https://repo.spring.io[repo.spring.io]
|
You don’t need to build from source to use Spring Data (binaries in https://repo.spring.io[repo.spring.io]), but if you want to try out the latest and greatest, Spring Data can be easily built with the https://github.com/takari/maven-wrapper[maven wrapper].
|
||||||
and accessible from Maven using the Maven configuration noted <<maven-configuration,above>>.
|
You also need JDK 1.8.
|
||||||
|
|
||||||
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]
|
|
||||||
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]).
|
|
||||||
|
|
||||||
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].
|
|
||||||
|
|
||||||
Once you have installed MongoDB, you need to start a MongoDB server. It is convenient to set an environment variable to
|
|
||||||
your MongoDB installation directory (e.g. `MONGODB_HOME`).
|
|
||||||
|
|
||||||
To run the full test suite, a https://docs.mongodb.com/manual/tutorial/deploy-replica-set/[MongoDB Replica Set]
|
|
||||||
is required.
|
|
||||||
|
|
||||||
To run the MongoDB server enter the following command from a command-line:
|
|
||||||
|
|
||||||
[source,bash]
|
|
||||||
----
|
|
||||||
$ $MONGODB_HOME/bin/mongod --dbpath $MONGODB_HOME/runtime/data --ipv6 --port 27017 --replSet rs0
|
|
||||||
...
|
|
||||||
"msg":"Successfully connected to host"
|
|
||||||
----
|
|
||||||
|
|
||||||
Once the MongoDB server starts up, you should see the message (`msg`), "_Successfully connected to host_".
|
|
||||||
|
|
||||||
Notice the `--dbpath` option to the `mongod` command. You can set this to anything you like, but in this case, we set
|
|
||||||
the absolute path to a sub-directory (`runtime/data/`) under the MongoDB installation directory (in `$MONGODB_HOME`).
|
|
||||||
|
|
||||||
You need to initialize the MongoDB replica set only once on the first time the MongoDB server is started.
|
|
||||||
To initialize the replica set, start a mongo client:
|
|
||||||
|
|
||||||
[source,bash]
|
|
||||||
----
|
|
||||||
$ $MONGODB_HOME/bin/mongo
|
|
||||||
MongoDB server version: 5.0.0
|
|
||||||
...
|
|
||||||
----
|
|
||||||
|
|
||||||
Then enter the following command:
|
|
||||||
|
|
||||||
[source,bash]
|
|
||||||
----
|
|
||||||
mongo> rs.initiate({ _id: 'rs0', members: [ { _id: 0, host: '127.0.0.1:27017' } ] })
|
|
||||||
----
|
|
||||||
|
|
||||||
Finally, on UNIX-based system (for example, Linux or Mac OS X) you may need to adjust the `ulimit`.
|
|
||||||
In case you need to, you can adjust the `ulimit` with the following command (32768 is just a recommendation):
|
|
||||||
|
|
||||||
[source,bash]
|
|
||||||
----
|
|
||||||
$ ulimit -n 32768
|
|
||||||
----
|
|
||||||
|
|
||||||
You can use `ulimit -a` again to verify the `ulimit` for "_open files_" was set appropriately.
|
|
||||||
|
|
||||||
Now you are ready to build Spring Data MongoDB. Simply enter the following `mvnw` (Maven Wrapper) command:
|
|
||||||
|
|
||||||
[source,bash]
|
[source,bash]
|
||||||
----
|
----
|
||||||
@@ -343,8 +261,7 @@ Now you are ready to build Spring Data MongoDB. Simply enter the following `mvnw
|
|||||||
|
|
||||||
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.5.0 or above].
|
||||||
|
|
||||||
_Also see link:CONTRIBUTING.adoc[CONTRIBUTING.adoc] if you wish to submit pull requests, and in particular, please sign
|
_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._
|
||||||
the https://cla.pivotal.io/sign/spring[Contributor’s Agreement] before your first non-trivial change._
|
|
||||||
|
|
||||||
=== Building reference documentation
|
=== Building reference documentation
|
||||||
|
|
||||||
@@ -357,7 +274,17 @@ Building the documentation builds also the project without running tests.
|
|||||||
|
|
||||||
The generated documentation is available from `target/site/reference/html/index.html`.
|
The generated documentation is available from `target/site/reference/html/index.html`.
|
||||||
|
|
||||||
[[license]]
|
== Guides
|
||||||
|
|
||||||
|
The https://spring.io/[spring.io] site contains several guides that show how to use Spring Data step-by-step:
|
||||||
|
|
||||||
|
* https://spring.io/guides/gs/accessing-data-mongodb/[Accessing Data with MongoDB] is a very basic guide that shows you how to create a simple application and how to access data using repositories.
|
||||||
|
* https://spring.io/guides/gs/accessing-mongodb-data-rest/[Accessing MongoDB Data with REST] is a guide to creating a REST web service exposing data stored in MongoDB through repositories.
|
||||||
|
|
||||||
|
== Examples
|
||||||
|
|
||||||
|
* https://github.com/spring-projects/spring-data-examples/[Spring Data Examples] contains example projects that explain specific features in more detail.
|
||||||
|
|
||||||
== License
|
== License
|
||||||
|
|
||||||
Spring Data MongoDB is Open Source software released under the https://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0 license].
|
Spring Data MongoDB is Open Source software released under the https://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0 license].
|
||||||
|
|||||||
15
ci/openjdk11-mongodb-4.2/Dockerfile
Normal file
15
ci/openjdk11-mongodb-4.2/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
FROM adoptopenjdk/openjdk11:latest
|
||||||
|
|
||||||
|
ENV TZ=Etc/UTC
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
|
||||||
|
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv e162f504a20cdf15827f718d4b7c549a058f8b6b ; \
|
||||||
|
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list; \
|
||||||
|
echo ${TZ} > /etc/timezone;
|
||||||
|
|
||||||
|
RUN apt-get update ; \
|
||||||
|
apt-get install -y mongodb-org=4.2.0 mongodb-org-server=4.2.0 mongodb-org-shell=4.2.0 mongodb-org-mongos=4.2.0 mongodb-org-tools=4.2.0 ; \
|
||||||
|
apt-get clean; \
|
||||||
|
rm -rf /var/lib/apt/lists/*;
|
||||||
15
ci/openjdk14-mongodb-4.2/Dockerfile
Normal file
15
ci/openjdk14-mongodb-4.2/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
FROM adoptopenjdk/openjdk14:latest
|
||||||
|
|
||||||
|
ENV TZ=Etc/UTC
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
|
||||||
|
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv e162f504a20cdf15827f718d4b7c549a058f8b6b ; \
|
||||||
|
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list; \
|
||||||
|
echo ${TZ} > /etc/timezone;
|
||||||
|
|
||||||
|
RUN apt-get update ; \
|
||||||
|
apt-get install -y mongodb-org=4.2.0 mongodb-org-server=4.2.0 mongodb-org-shell=4.2.0 mongodb-org-mongos=4.2.0 mongodb-org-tools=4.2.0 ; \
|
||||||
|
apt-get clean; \
|
||||||
|
rm -rf /var/lib/apt/lists/*;
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
FROM openjdk:17-bullseye
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
RUN apt-get update ; \
|
|
||||||
apt-get install -y mongodb-org=4.4.4 mongodb-org-server=4.4.4 mongodb-org-shell=4.4.4 mongodb-org-mongos=4.4.4 mongodb-org-tools=4.4.4 ; \
|
|
||||||
apt-get clean; \
|
|
||||||
rm -rf /var/lib/apt/lists/*;
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
FROM openjdk:17-bullseye
|
|
||||||
|
|
||||||
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 5.0 release signing key
|
|
||||||
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;
|
|
||||||
|
|
||||||
RUN apt-get update; \
|
|
||||||
apt-get install -y mongodb-org=5.0.3 mongodb-org-server=5.0.3 mongodb-org-shell=5.0.3 mongodb-org-mongos=5.0.3 mongodb-org-tools=5.0.3; \
|
|
||||||
apt-get clean; \
|
|
||||||
rm -rf /var/lib/apt/lists/*;
|
|
||||||
|
|
||||||
15
ci/openjdk8-mongodb-4.0/Dockerfile
Normal file
15
ci/openjdk8-mongodb-4.0/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
FROM adoptopenjdk/openjdk8:latest
|
||||||
|
|
||||||
|
ENV TZ=Etc/UTC
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN RUN set -eux; \
|
||||||
|
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
|
||||||
|
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4 ; \
|
||||||
|
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list; \
|
||||||
|
echo ${TZ} > /etc/timezone;
|
||||||
|
|
||||||
|
RUN apt-get update ; \
|
||||||
|
apt-get install -y mongodb-org=4.0.14 mongodb-org-server=4.0.14 mongodb-org-shell=4.0.14 mongodb-org-mongos=4.0.14 mongodb-org-tools=4.0.14 ; \
|
||||||
|
apt-get clean; \
|
||||||
|
rm -rf /var/lib/apt/lists/*;
|
||||||
15
ci/openjdk8-mongodb-4.2/Dockerfile
Normal file
15
ci/openjdk8-mongodb-4.2/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
FROM adoptopenjdk/openjdk8:latest
|
||||||
|
|
||||||
|
ENV TZ=Etc/UTC
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 ; \
|
||||||
|
apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv e162f504a20cdf15827f718d4b7c549a058f8b6b ; \
|
||||||
|
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list; \
|
||||||
|
echo ${TZ} > /etc/timezone;
|
||||||
|
|
||||||
|
RUN apt-get update ; \
|
||||||
|
apt-get install -y mongodb-org=4.2.0 mongodb-org-server=4.2.0 mongodb-org-shell=4.2.0 mongodb-org-mongos=4.2.0 mongodb-org-tools=4.2.0 ; \
|
||||||
|
apt-get clean; \
|
||||||
|
rm -rf /var/lib/apt/lists/*;
|
||||||
13
pom.xml
13
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>4.0.0-M1</version>
|
<version>3.0.10.BUILD-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<name>Spring Data MongoDB</name>
|
<name>Spring Data MongoDB</name>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data.build</groupId>
|
<groupId>org.springframework.data.build</groupId>
|
||||||
<artifactId>spring-data-parent</artifactId>
|
<artifactId>spring-data-parent</artifactId>
|
||||||
<version>3.0.0-M1</version>
|
<version>2.3.10.BUILD-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
@@ -24,11 +24,10 @@
|
|||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<source.level>16</source.level>
|
|
||||||
<project.type>multi</project.type>
|
<project.type>multi</project.type>
|
||||||
<dist.id>spring-data-mongodb</dist.id>
|
<dist.id>spring-data-mongodb</dist.id>
|
||||||
<springdata.commons>3.0.0-M1</springdata.commons>
|
<springdata.commons>2.3.10.BUILD-SNAPSHOT</springdata.commons>
|
||||||
<mongo>4.4.1</mongo>
|
<mongo>4.0.6</mongo>
|
||||||
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
|
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
|
||||||
<jmh.version>1.19</jmh.version>
|
<jmh.version>1.19</jmh.version>
|
||||||
</properties>
|
</properties>
|
||||||
@@ -135,8 +134,8 @@
|
|||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>spring-libs-milestone</id>
|
<id>spring-libs-snapshot</id>
|
||||||
<url>https://repo.spring.io/libs-milestone</url>
|
<url>https://repo.spring.io/libs-snapshot</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>sonatype-libs-snapshot</id>
|
<id>sonatype-libs-snapshot</id>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>4.0.0-M1</version>
|
<version>3.0.10.BUILD-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>4.0.0-M1</version>
|
<version>3.0.10.BUILD-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>4.0.0-M1</version>
|
<version>3.0.10.BUILD-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -87,13 +87,6 @@
|
|||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.findbugs</groupId>
|
|
||||||
<artifactId>jsr305</artifactId>
|
|
||||||
<version>3.0.2</version>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- reactive -->
|
<!-- reactive -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -123,14 +116,34 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.reactivex.rxjava3</groupId>
|
<groupId>io.reactivex</groupId>
|
||||||
<artifactId>rxjava</artifactId>
|
<artifactId>rxjava</artifactId>
|
||||||
<version>${rxjava3}</version>
|
<version>${rxjava}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.reactivex</groupId>
|
||||||
|
<artifactId>rxjava-reactive-streams</artifactId>
|
||||||
|
<version>${rxjava-reactive-streams}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.reactivex.rxjava2</groupId>
|
||||||
|
<artifactId>rxjava</artifactId>
|
||||||
|
<version>${rxjava2}</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- CDI -->
|
<!-- CDI -->
|
||||||
<!-- Dependency order required to build against CDI 1.0 and test with CDI 2.0 -->
|
<!-- Dependency order required to build against CDI 1.0 and test with CDI 2.0 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.geronimo.specs</groupId>
|
||||||
|
<artifactId>geronimo-jcdi_2.0_spec</artifactId>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.interceptor</groupId>
|
<groupId>javax.interceptor</groupId>
|
||||||
@@ -140,48 +153,31 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.enterprise</groupId>
|
<groupId>javax.enterprise</groupId>
|
||||||
<artifactId>jakarta.enterprise.cdi-api</artifactId>
|
<artifactId>cdi-api</artifactId>
|
||||||
<version>${cdi}</version>
|
<version>${cdi}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.annotation</groupId>
|
<groupId>javax.annotation</groupId>
|
||||||
<artifactId>jakarta.annotation-api</artifactId>
|
<artifactId>javax.annotation-api</artifactId>
|
||||||
<version>${jakarta-annotation-api}</version>
|
<version>${javax-annotation-api}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.openwebbeans</groupId>
|
<groupId>org.apache.openwebbeans</groupId>
|
||||||
<artifactId>openwebbeans-se</artifactId>
|
<artifactId>openwebbeans-se</artifactId>
|
||||||
<classifier>jakarta</classifier>
|
|
||||||
<version>${webbeans}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.openwebbeans</groupId>
|
|
||||||
<artifactId>openwebbeans-spi</artifactId>
|
|
||||||
<classifier>jakarta</classifier>
|
|
||||||
<version>${webbeans}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.openwebbeans</groupId>
|
|
||||||
<artifactId>openwebbeans-impl</artifactId>
|
|
||||||
<classifier>jakarta</classifier>
|
|
||||||
<version>${webbeans}</version>
|
<version>${webbeans}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- JSR 303 Validation -->
|
<!-- JSR 303 Validation -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.validation</groupId>
|
<groupId>javax.validation</groupId>
|
||||||
<artifactId>jakarta.validation-api</artifactId>
|
<artifactId>validation-api</artifactId>
|
||||||
<version>${validation}</version>
|
<version>${validation}</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
@@ -196,30 +192,21 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<groupId>org.hibernate</groupId>
|
||||||
<artifactId>hibernate-validator</artifactId>
|
<artifactId>hibernate-validator</artifactId>
|
||||||
<version>7.0.1.Final</version>
|
<version>5.2.4.Final</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.el</groupId>
|
<groupId>joda-time</groupId>
|
||||||
<artifactId>jakarta.el-api</artifactId>
|
<artifactId>joda-time</artifactId>
|
||||||
<version>4.0.0</version>
|
<version>${jodatime}</version>
|
||||||
<scope>provided</scope>
|
<scope>test</scope>
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish</groupId>
|
<groupId>org.threeten</groupId>
|
||||||
<artifactId>jakarta.el</artifactId>
|
<artifactId>threetenbp</artifactId>
|
||||||
<version>4.0.2</version>
|
<version>${threetenbp}</version>
|
||||||
<scope>provided</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>jakarta.enterprise</groupId>
|
|
||||||
<artifactId>jakarta.enterprise.cdi-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -229,6 +216,13 @@
|
|||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>jul-to-slf4j</artifactId>
|
||||||
|
<version>${slf4j}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>nl.jqno.equalsverifier</groupId>
|
<groupId>nl.jqno.equalsverifier</groupId>
|
||||||
<artifactId>equalsverifier</artifactId>
|
<artifactId>equalsverifier</artifactId>
|
||||||
@@ -264,9 +258,9 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.transaction</groupId>
|
<groupId>javax.transaction</groupId>
|
||||||
<artifactId>jakarta.transaction-api</artifactId>
|
<artifactId>jta</artifactId>
|
||||||
<version>2.0.0</version>
|
<version>1.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -302,15 +296,6 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- jMolecules -->
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jmolecules</groupId>
|
|
||||||
<artifactId>jmolecules-ddd</artifactId>
|
|
||||||
<version>${jmolecules}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021 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 org.bson.Document;
|
|
||||||
import org.bson.codecs.DocumentCodec;
|
|
||||||
import org.bson.codecs.configuration.CodecRegistry;
|
|
||||||
import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec;
|
|
||||||
import org.springframework.data.util.Lazy;
|
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import org.springframework.util.ObjectUtils;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link MongoExpression} using the {@link ParameterBindingDocumentCodec} for parsing a raw ({@literal json})
|
|
||||||
* expression. The expression will be wrapped within <code>{ ... }</code> if necessary. The actual parsing and parameter
|
|
||||||
* binding of placeholders like {@code ?0} is delayed upon first call on the the target {@link Document} via
|
|
||||||
* {@link #toDocument()}.
|
|
||||||
* <br />
|
|
||||||
*
|
|
||||||
* <pre class="code">
|
|
||||||
* $toUpper : $name -> { '$toUpper' : '$name' }
|
|
||||||
*
|
|
||||||
* { '$toUpper' : '$name' } -> { '$toUpper' : '$name' }
|
|
||||||
*
|
|
||||||
* { '$toUpper' : '?0' }, "$name" -> { '$toUpper' : '$name' }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* Some types might require a special {@link org.bson.codecs.Codec}. If so, make sure to provide a {@link CodecRegistry}
|
|
||||||
* containing the required {@link org.bson.codecs.Codec codec} via {@link #withCodecRegistry(CodecRegistry)}.
|
|
||||||
*
|
|
||||||
* @author Christoph Strobl
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
public class BindableMongoExpression implements MongoExpression {
|
|
||||||
|
|
||||||
private final String expressionString;
|
|
||||||
|
|
||||||
private final @Nullable CodecRegistryProvider codecRegistryProvider;
|
|
||||||
|
|
||||||
private final @Nullable Object[] args;
|
|
||||||
|
|
||||||
private final Lazy<Document> target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance of {@link BindableMongoExpression}.
|
|
||||||
*
|
|
||||||
* @param expression must not be {@literal null}.
|
|
||||||
* @param args can be {@literal null}.
|
|
||||||
*/
|
|
||||||
public BindableMongoExpression(String expression, @Nullable Object[] args) {
|
|
||||||
this(expression, null, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance of {@link BindableMongoExpression}.
|
|
||||||
*
|
|
||||||
* @param expression must not be {@literal null}.
|
|
||||||
* @param codecRegistryProvider can be {@literal null}.
|
|
||||||
* @param args can be {@literal null}.
|
|
||||||
*/
|
|
||||||
public BindableMongoExpression(String expression, @Nullable CodecRegistryProvider codecRegistryProvider,
|
|
||||||
@Nullable Object[] args) {
|
|
||||||
|
|
||||||
this.expressionString = expression;
|
|
||||||
this.codecRegistryProvider = codecRegistryProvider;
|
|
||||||
this.args = args;
|
|
||||||
this.target = Lazy.of(this::parse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide the {@link CodecRegistry} used to convert expressions.
|
|
||||||
*
|
|
||||||
* @param codecRegistry must not be {@literal null}.
|
|
||||||
* @return new instance of {@link BindableMongoExpression}.
|
|
||||||
*/
|
|
||||||
public BindableMongoExpression withCodecRegistry(CodecRegistry codecRegistry) {
|
|
||||||
return new BindableMongoExpression(expressionString, () -> codecRegistry, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide the arguments to bind to the placeholders via their index.
|
|
||||||
*
|
|
||||||
* @param args must not be {@literal null}.
|
|
||||||
* @return new instance of {@link BindableMongoExpression}.
|
|
||||||
*/
|
|
||||||
public BindableMongoExpression bind(Object... args) {
|
|
||||||
return new BindableMongoExpression(expressionString, codecRegistryProvider, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document toDocument() {
|
|
||||||
return target.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "BindableMongoExpression{" + "expressionString='" + expressionString + '\'' + ", args="
|
|
||||||
+ Arrays.toString(args) + '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
private Document parse() {
|
|
||||||
|
|
||||||
String expression = wrapJsonIfNecessary(expressionString);
|
|
||||||
|
|
||||||
if (ObjectUtils.isEmpty(args)) {
|
|
||||||
|
|
||||||
if (codecRegistryProvider == null) {
|
|
||||||
return Document.parse(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Document.parse(expression, codecRegistryProvider.getCodecFor(Document.class)
|
|
||||||
.orElseGet(() -> new DocumentCodec(codecRegistryProvider.getCodecRegistry())));
|
|
||||||
}
|
|
||||||
|
|
||||||
ParameterBindingDocumentCodec codec = codecRegistryProvider == null ? new ParameterBindingDocumentCodec()
|
|
||||||
: new ParameterBindingDocumentCodec(codecRegistryProvider.getCodecRegistry());
|
|
||||||
return codec.decode(expression, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String wrapJsonIfNecessary(String json) {
|
|
||||||
|
|
||||||
if (StringUtils.hasText(json) && (json.startsWith("{") && json.endsWith("}"))) {
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "{" + json + "}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,8 +20,8 @@ import org.springframework.util.StringUtils;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class featuring helper methods for working with MongoDb collections.
|
* Helper class featuring helper methods for working with MongoDb collections.
|
||||||
* <br />
|
* <p/>
|
||||||
* <br />
|
* <p/>
|
||||||
* Mainly intended for internal use within the framework.
|
* Mainly intended for internal use within the framework.
|
||||||
*
|
*
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import com.mongodb.client.MongoDatabase;
|
|||||||
* Helper class for managing a {@link MongoDatabase} instances via {@link MongoDatabaseFactory}. Used for obtaining
|
* Helper class for managing a {@link MongoDatabase} instances via {@link MongoDatabaseFactory}. Used for obtaining
|
||||||
* {@link ClientSession session bound} resources, such as {@link MongoDatabase} and
|
* {@link ClientSession session bound} resources, such as {@link MongoDatabase} and
|
||||||
* {@link com.mongodb.client.MongoCollection} suitable for transactional usage.
|
* {@link com.mongodb.client.MongoCollection} suitable for transactional usage.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>Note:</strong> Intended for internal usage only.
|
* <strong>Note:</strong> Intended for internal usage only.
|
||||||
*
|
*
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
@@ -43,7 +43,7 @@ public class MongoDatabaseUtils {
|
|||||||
/**
|
/**
|
||||||
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory} using
|
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory} using
|
||||||
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
|
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
|
||||||
* <br />
|
* <p />
|
||||||
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
|
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
|
||||||
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
||||||
*
|
*
|
||||||
@@ -56,7 +56,7 @@ public class MongoDatabaseUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory}.
|
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory}.
|
||||||
* <br />
|
* <p />
|
||||||
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
|
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
|
||||||
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
||||||
*
|
*
|
||||||
@@ -71,7 +71,7 @@ public class MongoDatabaseUtils {
|
|||||||
/**
|
/**
|
||||||
* Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDatabaseFactory factory} using
|
* Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDatabaseFactory factory} using
|
||||||
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
|
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
|
||||||
* <br />
|
* <p />
|
||||||
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
|
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
|
||||||
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
||||||
*
|
*
|
||||||
@@ -85,7 +85,7 @@ public class MongoDatabaseUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDatabaseFactory factory}.
|
* Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDatabaseFactory factory}.
|
||||||
* <br />
|
* <p />
|
||||||
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
|
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
|
||||||
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
||||||
*
|
*
|
||||||
@@ -104,8 +104,7 @@ public class MongoDatabaseUtils {
|
|||||||
|
|
||||||
Assert.notNull(factory, "Factory must not be null!");
|
Assert.notNull(factory, "Factory must not be null!");
|
||||||
|
|
||||||
if (sessionSynchronization == SessionSynchronization.NEVER
|
if (!TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||||
|| !TransactionSynchronizationManager.isSynchronizationActive()) {
|
|
||||||
return StringUtils.hasText(dbName) ? factory.getMongoDatabase(dbName) : factory.getMongoDatabase();
|
return StringUtils.hasText(dbName) ? factory.getMongoDatabase(dbName) : factory.getMongoDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,11 +192,19 @@ public class MongoDatabaseUtils {
|
|||||||
this.resourceHolder = resourceHolder;
|
this.resourceHolder = resourceHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.support.ResourceHolderSynchronization#shouldReleaseBeforeCompletion()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldReleaseBeforeCompletion() {
|
protected boolean shouldReleaseBeforeCompletion() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.support.ResourceHolderSynchronization#processResourceAfterCommit(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void processResourceAfterCommit(MongoResourceHolder resourceHolder) {
|
protected void processResourceAfterCommit(MongoResourceHolder resourceHolder) {
|
||||||
|
|
||||||
@@ -206,6 +213,10 @@ public class MongoDatabaseUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.support.ResourceHolderSynchronization#afterCompletion(int)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void afterCompletion(int status) {
|
public void afterCompletion(int status) {
|
||||||
|
|
||||||
@@ -216,6 +227,10 @@ public class MongoDatabaseUtils {
|
|||||||
super.afterCompletion(status);
|
super.afterCompletion(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.support.ResourceHolderSynchronization#releaseResource(java.lang.Object, java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void releaseResource(MongoResourceHolder resourceHolder, Object resourceKey) {
|
protected void releaseResource(MongoResourceHolder resourceHolder, Object resourceKey) {
|
||||||
|
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021 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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper object for MongoDB expressions like {@code $toUpper : $name} that manifest as {@link org.bson.Document} when
|
|
||||||
* passed on to the driver.
|
|
||||||
* <br />
|
|
||||||
* A set of predefined {@link MongoExpression expressions}, including a
|
|
||||||
* {@link org.springframework.data.mongodb.core.aggregation.AggregationSpELExpression SpEL based variant} for method
|
|
||||||
* like expressions (eg. {@code toUpper(name)}) are available via the
|
|
||||||
* {@link org.springframework.data.mongodb.core.aggregation Aggregation API}.
|
|
||||||
*
|
|
||||||
* @author Christoph Strobl
|
|
||||||
* @since 3.2
|
|
||||||
* @see org.springframework.data.mongodb.core.aggregation.ArithmeticOperators
|
|
||||||
* @see org.springframework.data.mongodb.core.aggregation.ArrayOperators
|
|
||||||
* @see org.springframework.data.mongodb.core.aggregation.ComparisonOperators
|
|
||||||
* @see org.springframework.data.mongodb.core.aggregation.ConditionalOperators
|
|
||||||
* @see org.springframework.data.mongodb.core.aggregation.ConvertOperators
|
|
||||||
* @see org.springframework.data.mongodb.core.aggregation.DateOperators
|
|
||||||
* @see org.springframework.data.mongodb.core.aggregation.ObjectOperators
|
|
||||||
* @see org.springframework.data.mongodb.core.aggregation.SetOperators
|
|
||||||
* @see org.springframework.data.mongodb.core.aggregation.StringOperators
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface MongoExpression {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new {@link MongoExpression} from plain {@link String} (eg. {@code $toUpper : $name}). <br />
|
|
||||||
* The given expression will be wrapped with <code>{ ... }</code> to match an actual MongoDB {@link org.bson.Document}
|
|
||||||
* if necessary.
|
|
||||||
*
|
|
||||||
* @param expression must not be {@literal null}.
|
|
||||||
* @return new instance of {@link MongoExpression}.
|
|
||||||
*/
|
|
||||||
static MongoExpression create(String expression) {
|
|
||||||
return new BindableMongoExpression(expression, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new {@link MongoExpression} from plain {@link String} containing placeholders (eg. {@code $toUpper : ?0})
|
|
||||||
* that will be resolved on first call of {@link #toDocument()}. <br />
|
|
||||||
* The given expression will be wrapped with <code>{ ... }</code> to match an actual MongoDB {@link org.bson.Document}
|
|
||||||
* if necessary.
|
|
||||||
*
|
|
||||||
* @param expression must not be {@literal null}.
|
|
||||||
* @return new instance of {@link MongoExpression}.
|
|
||||||
*/
|
|
||||||
static MongoExpression create(String expression, Object... args) {
|
|
||||||
return new BindableMongoExpression(expression, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain the native {@link org.bson.Document} representation.
|
|
||||||
*
|
|
||||||
* @return never {@literal null}.
|
|
||||||
*/
|
|
||||||
org.bson.Document toDocument();
|
|
||||||
}
|
|
||||||
@@ -24,7 +24,7 @@ import com.mongodb.client.ClientSession;
|
|||||||
/**
|
/**
|
||||||
* MongoDB specific {@link ResourceHolderSupport resource holder}, wrapping a {@link ClientSession}.
|
* MongoDB specific {@link ResourceHolderSupport resource holder}, wrapping a {@link ClientSession}.
|
||||||
* {@link MongoTransactionManager} binds instances of this class to the thread.
|
* {@link MongoTransactionManager} binds instances of this class to the thread.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>Note:</strong> Intended for internal usage only.
|
* <strong>Note:</strong> Intended for internal usage only.
|
||||||
*
|
*
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
|
|||||||
@@ -37,18 +37,18 @@ import com.mongodb.client.ClientSession;
|
|||||||
/**
|
/**
|
||||||
* A {@link org.springframework.transaction.PlatformTransactionManager} implementation that manages
|
* A {@link org.springframework.transaction.PlatformTransactionManager} implementation that manages
|
||||||
* {@link ClientSession} based transactions for a single {@link MongoDatabaseFactory}.
|
* {@link ClientSession} based transactions for a single {@link MongoDatabaseFactory}.
|
||||||
* <br />
|
* <p />
|
||||||
* Binds a {@link ClientSession} from the specified {@link MongoDatabaseFactory} to the thread.
|
* Binds a {@link ClientSession} from the specified {@link MongoDatabaseFactory} to the thread.
|
||||||
* <br />
|
* <p />
|
||||||
* {@link TransactionDefinition#isReadOnly() Readonly} transactions operate on a {@link ClientSession} and enable causal
|
* {@link TransactionDefinition#isReadOnly() Readonly} transactions operate on a {@link ClientSession} and enable causal
|
||||||
* consistency, and also {@link ClientSession#startTransaction() start}, {@link ClientSession#commitTransaction()
|
* consistency, and also {@link ClientSession#startTransaction() start}, {@link ClientSession#commitTransaction()
|
||||||
* commit} or {@link ClientSession#abortTransaction() abort} a transaction.
|
* commit} or {@link ClientSession#abortTransaction() abort} a transaction.
|
||||||
* <br />
|
* <p />
|
||||||
* Application code is required to retrieve the {@link com.mongodb.client.MongoDatabase} via
|
* Application code is required to retrieve the {@link com.mongodb.client.MongoDatabase} via
|
||||||
* {@link MongoDatabaseUtils#getDatabase(MongoDatabaseFactory)} instead of a standard
|
* {@link MongoDatabaseUtils#getDatabase(MongoDatabaseFactory)} instead of a standard
|
||||||
* {@link MongoDatabaseFactory#getMongoDatabase()} call. Spring classes such as
|
* {@link MongoDatabaseFactory#getMongoDatabase()} call. Spring classes such as
|
||||||
* {@link org.springframework.data.mongodb.core.MongoTemplate} use this strategy implicitly.
|
* {@link org.springframework.data.mongodb.core.MongoTemplate} use this strategy implicitly.
|
||||||
* <br />
|
* <p />
|
||||||
* By default failure of a {@literal commit} operation raises a {@link TransactionSystemException}. One may override
|
* By default failure of a {@literal commit} operation raises a {@link TransactionSystemException}. One may override
|
||||||
* {@link #doCommit(MongoTransactionObject)} to implement the
|
* {@link #doCommit(MongoTransactionObject)} to implement the
|
||||||
* <a href="https://docs.mongodb.com/manual/core/transactions/#retry-commit-operation">Retry Commit Operation</a>
|
* <a href="https://docs.mongodb.com/manual/core/transactions/#retry-commit-operation">Retry Commit Operation</a>
|
||||||
@@ -69,11 +69,11 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link MongoTransactionManager} for bean-style usage.
|
* Create a new {@link MongoTransactionManager} for bean-style usage.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>Note:</strong>The {@link MongoDatabaseFactory db factory} has to be
|
* <strong>Note:</strong>The {@link MongoDatabaseFactory db factory} has to be
|
||||||
* {@link #setDbFactory(MongoDatabaseFactory) set} before using the instance. Use this constructor to prepare a
|
* {@link #setDbFactory(MongoDatabaseFactory) set} before using the instance. Use this constructor to prepare a
|
||||||
* {@link MongoTransactionManager} via a {@link org.springframework.beans.factory.BeanFactory}.
|
* {@link MongoTransactionManager} via a {@link org.springframework.beans.factory.BeanFactory}.
|
||||||
* <br />
|
* <p />
|
||||||
* Optionally it is possible to set default {@link TransactionOptions transaction options} defining
|
* Optionally it is possible to set default {@link TransactionOptions transaction options} defining
|
||||||
* {@link com.mongodb.ReadConcern} and {@link com.mongodb.WriteConcern}.
|
* {@link com.mongodb.ReadConcern} and {@link com.mongodb.WriteConcern}.
|
||||||
*
|
*
|
||||||
@@ -106,6 +106,10 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
this.options = options;
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* org.springframework.transaction.support.AbstractPlatformTransactionManager#doGetTransaction()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Object doGetTransaction() throws TransactionException {
|
protected Object doGetTransaction() throws TransactionException {
|
||||||
|
|
||||||
@@ -114,11 +118,19 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
return new MongoTransactionObject(resourceHolder);
|
return new MongoTransactionObject(resourceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* org.springframework.transaction.support.AbstractPlatformTransactionManager#isExistingTransaction(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean isExistingTransaction(Object transaction) throws TransactionException {
|
protected boolean isExistingTransaction(Object transaction) throws TransactionException {
|
||||||
return extractMongoTransaction(transaction).hasResourceHolder();
|
return extractMongoTransaction(transaction).hasResourceHolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* org.springframework.transaction.support.AbstractPlatformTransactionManager#doBegin(java.lang.Object, org.springframework.transaction.TransactionDefinition)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException {
|
protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException {
|
||||||
|
|
||||||
@@ -148,6 +160,10 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
TransactionSynchronizationManager.bindResource(getRequiredDbFactory(), resourceHolder);
|
TransactionSynchronizationManager.bindResource(getRequiredDbFactory(), resourceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* org.springframework.transaction.support.AbstractPlatformTransactionManager#doSuspend(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Object doSuspend(Object transaction) throws TransactionException {
|
protected Object doSuspend(Object transaction) throws TransactionException {
|
||||||
|
|
||||||
@@ -157,11 +173,19 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
return TransactionSynchronizationManager.unbindResource(getRequiredDbFactory());
|
return TransactionSynchronizationManager.unbindResource(getRequiredDbFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* org.springframework.transaction.support.AbstractPlatformTransactionManager#doResume(java.lang.Object, java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
|
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
|
||||||
TransactionSynchronizationManager.bindResource(getRequiredDbFactory(), suspendedResources);
|
TransactionSynchronizationManager.bindResource(getRequiredDbFactory(), suspendedResources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* org.springframework.transaction.support.AbstractPlatformTransactionManager#doCommit(org.springframework.transaction.support.DefaultTransactionStatus)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected final void doCommit(DefaultTransactionStatus status) throws TransactionException {
|
protected final void doCommit(DefaultTransactionStatus status) throws TransactionException {
|
||||||
|
|
||||||
@@ -188,8 +212,8 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
* By default those labels are ignored, nevertheless one might check for
|
* By default those labels are ignored, nevertheless one might check for
|
||||||
* {@link MongoException#UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL transient commit errors labels} and retry the the
|
* {@link MongoException#UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL transient commit errors labels} and retry the the
|
||||||
* commit. <br />
|
* commit. <br />
|
||||||
* <pre>
|
|
||||||
* <code>
|
* <code>
|
||||||
|
* <pre>
|
||||||
* int retries = 3;
|
* int retries = 3;
|
||||||
* do {
|
* do {
|
||||||
* try {
|
* try {
|
||||||
@@ -202,8 +226,8 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
* }
|
* }
|
||||||
* Thread.sleep(500);
|
* Thread.sleep(500);
|
||||||
* } while (--retries > 0);
|
* } while (--retries > 0);
|
||||||
* </code>
|
|
||||||
* </pre>
|
* </pre>
|
||||||
|
* </code>
|
||||||
*
|
*
|
||||||
* @param transactionObject never {@literal null}.
|
* @param transactionObject never {@literal null}.
|
||||||
* @throws Exception in case of transaction errors.
|
* @throws Exception in case of transaction errors.
|
||||||
@@ -212,6 +236,10 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
transactionObject.commitTransaction();
|
transactionObject.commitTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* org.springframework.transaction.support.AbstractPlatformTransactionManager#doRollback(org.springframework.transaction.support.DefaultTransactionStatus)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doRollback(DefaultTransactionStatus status) throws TransactionException {
|
protected void doRollback(DefaultTransactionStatus status) throws TransactionException {
|
||||||
|
|
||||||
@@ -231,6 +259,10 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* org.springframework.transaction.support.AbstractPlatformTransactionManager#doSetRollbackOnly(org.springframework.transaction.support.DefaultTransactionStatus)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException {
|
protected void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException {
|
||||||
|
|
||||||
@@ -238,6 +270,10 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
transactionObject.getRequiredResourceHolder().setRollbackOnly();
|
transactionObject.getRequiredResourceHolder().setRollbackOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* org.springframework.transaction.support.AbstractPlatformTransactionManager#doCleanupAfterCompletion(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doCleanupAfterCompletion(Object transaction) {
|
protected void doCleanupAfterCompletion(Object transaction) {
|
||||||
|
|
||||||
@@ -289,11 +325,19 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
return dbFactory;
|
return dbFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.support.ResourceTransactionManager#getResourceFactory()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MongoDatabaseFactory getResourceFactory() {
|
public MongoDatabaseFactory getResourceFactory() {
|
||||||
return getRequiredDbFactory();
|
return getRequiredDbFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
getRequiredDbFactory();
|
getRequiredDbFactory();
|
||||||
@@ -461,11 +505,19 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
|
|||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.support.SmartTransactionObject#isRollbackOnly()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isRollbackOnly() {
|
public boolean isRollbackOnly() {
|
||||||
return this.resourceHolder != null && this.resourceHolder.isRollbackOnly();
|
return this.resourceHolder != null && this.resourceHolder.isRollbackOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.support.SmartTransactionObject#flush()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
TransactionSynchronizationUtils.triggerFlush();
|
TransactionSynchronizationUtils.triggerFlush();
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import com.mongodb.reactivestreams.client.MongoDatabase;
|
|||||||
* Helper class for managing reactive {@link MongoDatabase} instances via {@link ReactiveMongoDatabaseFactory}. Used for
|
* Helper class for managing reactive {@link MongoDatabase} instances via {@link ReactiveMongoDatabaseFactory}. Used for
|
||||||
* obtaining {@link ClientSession session bound} resources, such as {@link MongoDatabase} and {@link MongoCollection}
|
* obtaining {@link ClientSession session bound} resources, such as {@link MongoDatabase} and {@link MongoCollection}
|
||||||
* suitable for transactional usage.
|
* suitable for transactional usage.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>Note:</strong> Intended for internal usage only.
|
* <strong>Note:</strong> Intended for internal usage only.
|
||||||
*
|
*
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
@@ -75,7 +75,7 @@ public class ReactiveMongoDatabaseUtils {
|
|||||||
/**
|
/**
|
||||||
* Obtain the default {@link MongoDatabase database} form the given {@link ReactiveMongoDatabaseFactory factory} using
|
* Obtain the default {@link MongoDatabase database} form the given {@link ReactiveMongoDatabaseFactory factory} using
|
||||||
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
|
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
|
||||||
* <br />
|
* <p />
|
||||||
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
|
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
|
||||||
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
||||||
*
|
*
|
||||||
@@ -88,7 +88,7 @@ public class ReactiveMongoDatabaseUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the default {@link MongoDatabase database} form the given {@link ReactiveMongoDatabaseFactory factory}.
|
* Obtain the default {@link MongoDatabase database} form the given {@link ReactiveMongoDatabaseFactory factory}.
|
||||||
* <br />
|
* <p />
|
||||||
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
|
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
|
||||||
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
||||||
*
|
*
|
||||||
@@ -104,7 +104,7 @@ public class ReactiveMongoDatabaseUtils {
|
|||||||
/**
|
/**
|
||||||
* Obtain the {@link MongoDatabase database} with given name form the given {@link ReactiveMongoDatabaseFactory
|
* Obtain the {@link MongoDatabase database} with given name form the given {@link ReactiveMongoDatabaseFactory
|
||||||
* factory} using {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
|
* factory} using {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
|
||||||
* <br />
|
* <p />
|
||||||
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
|
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
|
||||||
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
||||||
*
|
*
|
||||||
@@ -119,7 +119,7 @@ public class ReactiveMongoDatabaseUtils {
|
|||||||
/**
|
/**
|
||||||
* Obtain the {@link MongoDatabase database} with given name form the given {@link ReactiveMongoDatabaseFactory
|
* Obtain the {@link MongoDatabase database} with given name form the given {@link ReactiveMongoDatabaseFactory
|
||||||
* factory}.
|
* factory}.
|
||||||
* <br />
|
* <p />
|
||||||
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
|
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
|
||||||
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
|
||||||
*
|
*
|
||||||
@@ -138,10 +138,6 @@ public class ReactiveMongoDatabaseUtils {
|
|||||||
|
|
||||||
Assert.notNull(factory, "DatabaseFactory must not be null!");
|
Assert.notNull(factory, "DatabaseFactory must not be null!");
|
||||||
|
|
||||||
if (sessionSynchronization == SessionSynchronization.NEVER) {
|
|
||||||
return getMongoDatabaseOrDefault(dbName, factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TransactionSynchronizationManager.forCurrentTransaction()
|
return TransactionSynchronizationManager.forCurrentTransaction()
|
||||||
.filter(TransactionSynchronizationManager::isSynchronizationActive) //
|
.filter(TransactionSynchronizationManager::isSynchronizationActive) //
|
||||||
.flatMap(synchronizationManager -> {
|
.flatMap(synchronizationManager -> {
|
||||||
@@ -214,11 +210,19 @@ public class ReactiveMongoDatabaseUtils {
|
|||||||
this.resourceHolder = resourceHolder;
|
this.resourceHolder = resourceHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.ReactiveResourceSynchronization#shouldReleaseBeforeCompletion()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldReleaseBeforeCompletion() {
|
protected boolean shouldReleaseBeforeCompletion() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.ReactiveResourceSynchronization#processResourceAfterCommit(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Mono<Void> processResourceAfterCommit(ReactiveMongoResourceHolder resourceHolder) {
|
protected Mono<Void> processResourceAfterCommit(ReactiveMongoResourceHolder resourceHolder) {
|
||||||
|
|
||||||
@@ -229,6 +233,10 @@ public class ReactiveMongoDatabaseUtils {
|
|||||||
return Mono.empty();
|
return Mono.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.ReactiveResourceSynchronization#afterCompletion(int)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> afterCompletion(int status) {
|
public Mono<Void> afterCompletion(int status) {
|
||||||
|
|
||||||
@@ -244,6 +252,10 @@ public class ReactiveMongoDatabaseUtils {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.ReactiveResourceSynchronization#releaseResource(java.lang.Object, java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Mono<Void> releaseResource(ReactiveMongoResourceHolder resourceHolder, Object resourceKey) {
|
protected Mono<Void> releaseResource(ReactiveMongoResourceHolder resourceHolder, Object resourceKey) {
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import com.mongodb.reactivestreams.client.ClientSession;
|
|||||||
/**
|
/**
|
||||||
* MongoDB specific resource holder, wrapping a {@link ClientSession}. {@link ReactiveMongoTransactionManager} binds
|
* MongoDB specific resource holder, wrapping a {@link ClientSession}. {@link ReactiveMongoTransactionManager} binds
|
||||||
* instances of this class to the subscriber context.
|
* instances of this class to the subscriber context.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>Note:</strong> Intended for internal usage only.
|
* <strong>Note:</strong> Intended for internal usage only.
|
||||||
*
|
*
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
|
|||||||
@@ -38,21 +38,21 @@ import com.mongodb.reactivestreams.client.ClientSession;
|
|||||||
* A {@link org.springframework.transaction.ReactiveTransactionManager} implementation that manages
|
* A {@link org.springframework.transaction.ReactiveTransactionManager} implementation that manages
|
||||||
* {@link com.mongodb.reactivestreams.client.ClientSession} based transactions for a single
|
* {@link com.mongodb.reactivestreams.client.ClientSession} based transactions for a single
|
||||||
* {@link org.springframework.data.mongodb.ReactiveMongoDatabaseFactory}.
|
* {@link org.springframework.data.mongodb.ReactiveMongoDatabaseFactory}.
|
||||||
* <br />
|
* <p />
|
||||||
* Binds a {@link ClientSession} from the specified
|
* Binds a {@link ClientSession} from the specified
|
||||||
* {@link org.springframework.data.mongodb.ReactiveMongoDatabaseFactory} to the subscriber
|
* {@link org.springframework.data.mongodb.ReactiveMongoDatabaseFactory} to the subscriber
|
||||||
* {@link reactor.util.context.Context}.
|
* {@link reactor.util.context.Context}.
|
||||||
* <br />
|
* <p />
|
||||||
* {@link org.springframework.transaction.TransactionDefinition#isReadOnly() Readonly} transactions operate on a
|
* {@link org.springframework.transaction.TransactionDefinition#isReadOnly() Readonly} transactions operate on a
|
||||||
* {@link ClientSession} and enable causal consistency, and also {@link ClientSession#startTransaction() start},
|
* {@link ClientSession} and enable causal consistency, and also {@link ClientSession#startTransaction() start},
|
||||||
* {@link com.mongodb.reactivestreams.client.ClientSession#commitTransaction() commit} or
|
* {@link com.mongodb.reactivestreams.client.ClientSession#commitTransaction() commit} or
|
||||||
* {@link ClientSession#abortTransaction() abort} a transaction.
|
* {@link ClientSession#abortTransaction() abort} a transaction.
|
||||||
* <br />
|
* <p />
|
||||||
* Application code is required to retrieve the {@link com.mongodb.reactivestreams.client.MongoDatabase} via
|
* Application code is required to retrieve the {@link com.mongodb.reactivestreams.client.MongoDatabase} via
|
||||||
* {@link org.springframework.data.mongodb.ReactiveMongoDatabaseUtils#getDatabase(ReactiveMongoDatabaseFactory)} instead
|
* {@link org.springframework.data.mongodb.ReactiveMongoDatabaseUtils#getDatabase(ReactiveMongoDatabaseFactory)} instead
|
||||||
* of a standard {@link org.springframework.data.mongodb.ReactiveMongoDatabaseFactory#getMongoDatabase()} call. Spring
|
* of a standard {@link org.springframework.data.mongodb.ReactiveMongoDatabaseFactory#getMongoDatabase()} call. Spring
|
||||||
* classes such as {@link org.springframework.data.mongodb.core.ReactiveMongoTemplate} use this strategy implicitly.
|
* classes such as {@link org.springframework.data.mongodb.core.ReactiveMongoTemplate} use this strategy implicitly.
|
||||||
* <br />
|
* <p />
|
||||||
* By default failure of a {@literal commit} operation raises a {@link TransactionSystemException}. You can override
|
* By default failure of a {@literal commit} operation raises a {@link TransactionSystemException}. You can override
|
||||||
* {@link #doCommit(TransactionSynchronizationManager, ReactiveMongoTransactionObject)} to implement the
|
* {@link #doCommit(TransactionSynchronizationManager, ReactiveMongoTransactionObject)} to implement the
|
||||||
* <a href="https://docs.mongodb.com/manual/core/transactions/#retry-commit-operation">Retry Commit Operation</a>
|
* <a href="https://docs.mongodb.com/manual/core/transactions/#retry-commit-operation">Retry Commit Operation</a>
|
||||||
@@ -71,11 +71,11 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link ReactiveMongoTransactionManager} for bean-style usage.
|
* Create a new {@link ReactiveMongoTransactionManager} for bean-style usage.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>Note:</strong>The {@link org.springframework.data.mongodb.ReactiveMongoDatabaseFactory db factory} has to
|
* <strong>Note:</strong>The {@link org.springframework.data.mongodb.ReactiveMongoDatabaseFactory db factory} has to
|
||||||
* be {@link #setDatabaseFactory(ReactiveMongoDatabaseFactory)} set} before using the instance. Use this constructor
|
* be {@link #setDatabaseFactory(ReactiveMongoDatabaseFactory)} set} before using the instance. Use this constructor
|
||||||
* to prepare a {@link ReactiveMongoTransactionManager} via a {@link org.springframework.beans.factory.BeanFactory}.
|
* to prepare a {@link ReactiveMongoTransactionManager} via a {@link org.springframework.beans.factory.BeanFactory}.
|
||||||
* <br />
|
* <p />
|
||||||
* Optionally it is possible to set default {@link TransactionOptions transaction options} defining
|
* Optionally it is possible to set default {@link TransactionOptions transaction options} defining
|
||||||
* {@link com.mongodb.ReadConcern} and {@link com.mongodb.WriteConcern}.
|
* {@link com.mongodb.ReadConcern} and {@link com.mongodb.WriteConcern}.
|
||||||
*
|
*
|
||||||
@@ -110,6 +110,10 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
this.options = options;
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doGetTransaction(org.springframework.transaction.reactive.TransactionSynchronizationManager)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Object doGetTransaction(TransactionSynchronizationManager synchronizationManager)
|
protected Object doGetTransaction(TransactionSynchronizationManager synchronizationManager)
|
||||||
throws TransactionException {
|
throws TransactionException {
|
||||||
@@ -119,11 +123,19 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
return new ReactiveMongoTransactionObject(resourceHolder);
|
return new ReactiveMongoTransactionObject(resourceHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#isExistingTransaction(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean isExistingTransaction(Object transaction) throws TransactionException {
|
protected boolean isExistingTransaction(Object transaction) throws TransactionException {
|
||||||
return extractMongoTransaction(transaction).hasResourceHolder();
|
return extractMongoTransaction(transaction).hasResourceHolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doBegin(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object, org.springframework.transaction.TransactionDefinition)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Mono<Void> doBegin(TransactionSynchronizationManager synchronizationManager, Object transaction,
|
protected Mono<Void> doBegin(TransactionSynchronizationManager synchronizationManager, Object transaction,
|
||||||
TransactionDefinition definition) throws TransactionException {
|
TransactionDefinition definition) throws TransactionException {
|
||||||
@@ -163,6 +175,10 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doSuspend(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Mono<Object> doSuspend(TransactionSynchronizationManager synchronizationManager, Object transaction)
|
protected Mono<Object> doSuspend(TransactionSynchronizationManager synchronizationManager, Object transaction)
|
||||||
throws TransactionException {
|
throws TransactionException {
|
||||||
@@ -176,6 +192,10 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doResume(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object, java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Mono<Void> doResume(TransactionSynchronizationManager synchronizationManager, @Nullable Object transaction,
|
protected Mono<Void> doResume(TransactionSynchronizationManager synchronizationManager, @Nullable Object transaction,
|
||||||
Object suspendedResources) {
|
Object suspendedResources) {
|
||||||
@@ -183,6 +203,10 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
.fromRunnable(() -> synchronizationManager.bindResource(getRequiredDatabaseFactory(), suspendedResources));
|
.fromRunnable(() -> synchronizationManager.bindResource(getRequiredDatabaseFactory(), suspendedResources));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doCommit(org.springframework.transaction.reactive.TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected final Mono<Void> doCommit(TransactionSynchronizationManager synchronizationManager,
|
protected final Mono<Void> doCommit(TransactionSynchronizationManager synchronizationManager,
|
||||||
GenericReactiveTransaction status) throws TransactionException {
|
GenericReactiveTransaction status) throws TransactionException {
|
||||||
@@ -219,6 +243,10 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
return transactionObject.commitTransaction();
|
return transactionObject.commitTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doRollback(org.springframework.transaction.reactive.TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Mono<Void> doRollback(TransactionSynchronizationManager synchronizationManager,
|
protected Mono<Void> doRollback(TransactionSynchronizationManager synchronizationManager,
|
||||||
GenericReactiveTransaction status) {
|
GenericReactiveTransaction status) {
|
||||||
@@ -240,6 +268,10 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doSetRollbackOnly(org.springframework.transaction.reactive.TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Mono<Void> doSetRollbackOnly(TransactionSynchronizationManager synchronizationManager,
|
protected Mono<Void> doSetRollbackOnly(TransactionSynchronizationManager synchronizationManager,
|
||||||
GenericReactiveTransaction status) throws TransactionException {
|
GenericReactiveTransaction status) throws TransactionException {
|
||||||
@@ -250,6 +282,10 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.reactive.AbstractReactiveTransactionManager#doCleanupAfterCompletion(org.springframework.transaction.reactive.TransactionSynchronizationManager, java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Mono<Void> doCleanupAfterCompletion(TransactionSynchronizationManager synchronizationManager,
|
protected Mono<Void> doCleanupAfterCompletion(TransactionSynchronizationManager synchronizationManager,
|
||||||
Object transaction) {
|
Object transaction) {
|
||||||
@@ -304,6 +340,10 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
return databaseFactory;
|
return databaseFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
getRequiredDatabaseFactory();
|
getRequiredDatabaseFactory();
|
||||||
@@ -469,11 +509,19 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
|
|||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.support.SmartTransactionObject#isRollbackOnly()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isRollbackOnly() {
|
public boolean isRollbackOnly() {
|
||||||
return this.resourceHolder != null && this.resourceHolder.isRollbackOnly();
|
return this.resourceHolder != null && this.resourceHolder.isRollbackOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.transaction.support.SmartTransactionObject#flush()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
throw new UnsupportedOperationException("flush() not supported");
|
throw new UnsupportedOperationException("flush() not supported");
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import com.mongodb.session.ClientSession;
|
|||||||
/**
|
/**
|
||||||
* {@link MethodInterceptor} implementation looking up and invoking an alternative target method having
|
* {@link MethodInterceptor} implementation looking up and invoking an alternative target method having
|
||||||
* {@link ClientSession} as its first argument. This allows seamless integration with the existing code base.
|
* {@link ClientSession} as its first argument. This allows seamless integration with the existing code base.
|
||||||
* <br />
|
* <p />
|
||||||
* The {@link MethodInterceptor} is aware of methods on {@code MongoCollection} that my return new instances of itself
|
* The {@link MethodInterceptor} is aware of methods on {@code MongoCollection} that my return new instances of itself
|
||||||
* like (eg. {@link com.mongodb.reactivestreams.client.MongoCollection#withWriteConcern(WriteConcern)} and decorate them
|
* like (eg. {@link com.mongodb.reactivestreams.client.MongoCollection#withWriteConcern(WriteConcern)} and decorate them
|
||||||
* if not already proxied.
|
* if not already proxied.
|
||||||
@@ -95,6 +95,10 @@ public class SessionAwareMethodInterceptor<D, C> implements MethodInterceptor {
|
|||||||
this.sessionType = sessionType;
|
this.sessionType = sessionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.aopalliance.intercept.MethodInterceptor(org.aopalliance.intercept.MethodInvocation)
|
||||||
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
|
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
|
||||||
|
|||||||
@@ -15,20 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb;
|
package org.springframework.data.mongodb;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
|
||||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link SessionSynchronization} is used along with {@code MongoTemplate} to define in which type of transactions to
|
* {@link SessionSynchronization} is used along with {@link org.springframework.data.mongodb.core.MongoTemplate} to
|
||||||
* participate if any.
|
* define in which type of transactions to participate if any.
|
||||||
*
|
*
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
* @see MongoTemplate#setSessionSynchronization(SessionSynchronization)
|
|
||||||
* @see MongoDatabaseUtils#getDatabase(MongoDatabaseFactory, SessionSynchronization)
|
|
||||||
* @see ReactiveMongoTemplate#setSessionSynchronization(SessionSynchronization)
|
|
||||||
* @see ReactiveMongoDatabaseUtils#getDatabase(ReactiveMongoDatabaseFactory, SessionSynchronization)
|
|
||||||
*/
|
*/
|
||||||
public enum SessionSynchronization {
|
public enum SessionSynchronization {
|
||||||
|
|
||||||
@@ -41,12 +34,5 @@ public enum SessionSynchronization {
|
|||||||
/**
|
/**
|
||||||
* Synchronize with native MongoDB transactions initiated via {@link MongoTransactionManager}.
|
* Synchronize with native MongoDB transactions initiated via {@link MongoTransactionManager}.
|
||||||
*/
|
*/
|
||||||
ON_ACTUAL_TRANSACTION,
|
ON_ACTUAL_TRANSACTION;
|
||||||
|
|
||||||
/**
|
|
||||||
* Do not participate in ongoing transactions.
|
|
||||||
*
|
|
||||||
* @since 3.2.5
|
|
||||||
*/
|
|
||||||
NEVER;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb;
|
package org.springframework.data.mongodb;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.slf4j.Logger;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.data.util.Version;
|
import org.springframework.data.util.Version;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ import com.mongodb.MongoDriverInformation;
|
|||||||
*/
|
*/
|
||||||
public class SpringDataMongoDB {
|
public class SpringDataMongoDB {
|
||||||
|
|
||||||
private static final Log LOGGER = LogFactory.getLog(SpringDataMongoDB.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(SpringDataMongoDB.class);
|
||||||
|
|
||||||
private static final Version FALLBACK_VERSION = new Version(3);
|
private static final Version FALLBACK_VERSION = new Version(3);
|
||||||
private static final MongoDriverInformation DRIVER_INFORMATION = MongoDriverInformation
|
private static final MongoDriverInformation DRIVER_INFORMATION = MongoDriverInformation
|
||||||
@@ -48,7 +48,7 @@ public class SpringDataMongoDB {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the "Implementation-Version" manifest attribute from the jar file.
|
* Fetches the "Implementation-Version" manifest attribute from the jar file.
|
||||||
* <br />
|
* <p />
|
||||||
* Note that some ClassLoaders do not expose the package metadata, hence this class might not be able to determine the
|
* Note that some ClassLoaders do not expose the package metadata, hence this class might not be able to determine the
|
||||||
* version in all environments. In this case the current Major version is returned as a fallback.
|
* version in all environments. In this case the current Major version is returned as a fallback.
|
||||||
*
|
*
|
||||||
@@ -68,7 +68,7 @@ public class SpringDataMongoDB {
|
|||||||
try {
|
try {
|
||||||
return Version.parse(versionString);
|
return Version.parse(versionString);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.debug(String.format("Cannot read Spring Data MongoDB version '%s'.", versionString));
|
LOGGER.debug("Cannot read Spring Data MongoDB version '{}'.", versionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALLBACK_VERSION;
|
return FALLBACK_VERSION;
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ import com.mongodb.ConnectionString;
|
|||||||
*/
|
*/
|
||||||
public class ConnectionStringPropertyEditor extends PropertyEditorSupport {
|
public class ConnectionStringPropertyEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setAsText(@Nullable String connectionString) {
|
public void setAsText(@Nullable String connectionString) {
|
||||||
|
|
||||||
|
|||||||
@@ -61,8 +61,8 @@ public @interface EnableMongoAuditing {
|
|||||||
boolean modifyOnCreate() default true;
|
boolean modifyOnCreate() default true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures a {@link DateTimeProvider} bean name that allows customizing the timestamp to be used for setting
|
* Configures a {@link DateTimeProvider} bean name that allows customizing the {@link org.joda.time.DateTime} to be
|
||||||
* creation and modification dates.
|
* used for setting creation and modification dates.
|
||||||
*
|
*
|
||||||
* @return empty {@link String} by default.
|
* @return empty {@link String} by default.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020-2021 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.data.mongodb.config;
|
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Inherited;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
import org.springframework.data.auditing.DateTimeProvider;
|
|
||||||
import org.springframework.data.domain.ReactiveAuditorAware;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Annotation to enable auditing in MongoDB using reactive infrastructure via annotation configuration.
|
|
||||||
*
|
|
||||||
* @author Mark Paluch
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
@Inherited
|
|
||||||
@Documented
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Import(ReactiveMongoAuditingRegistrar.class)
|
|
||||||
public @interface EnableReactiveMongoAuditing {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures the {@link ReactiveAuditorAware} bean to be used to lookup the current principal.
|
|
||||||
*
|
|
||||||
* @return empty {@link String} by default.
|
|
||||||
*/
|
|
||||||
String auditorAwareRef() default "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures whether the creation and modification dates are set. Defaults to {@literal true}.
|
|
||||||
*
|
|
||||||
* @return {@literal true} by default.
|
|
||||||
*/
|
|
||||||
boolean setDates() default true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures whether the entity shall be marked as modified on creation. Defaults to {@literal true}.
|
|
||||||
*
|
|
||||||
* @return {@literal true} by default.
|
|
||||||
*/
|
|
||||||
boolean modifyOnCreate() default true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures a {@link DateTimeProvider} bean name that allows customizing the timestamp to be used for setting
|
|
||||||
* creation and modification dates.
|
|
||||||
*
|
|
||||||
* @return empty {@link String} by default.
|
|
||||||
*/
|
|
||||||
String dateTimeProviderRef() default "";
|
|
||||||
}
|
|
||||||
@@ -34,6 +34,10 @@ import org.w3c.dom.Element;
|
|||||||
*/
|
*/
|
||||||
class GridFsTemplateParser extends AbstractBeanDefinitionParser {
|
class GridFsTemplateParser extends AbstractBeanDefinitionParser {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||||
throws BeanDefinitionStoreException {
|
throws BeanDefinitionStoreException {
|
||||||
@@ -42,6 +46,10 @@ class GridFsTemplateParser extends AbstractBeanDefinitionParser {
|
|||||||
return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE_BEAN_NAME;
|
return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE_BEAN_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ import org.w3c.dom.Element;
|
|||||||
public class MappingMongoConverterParser implements BeanDefinitionParser {
|
public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||||
|
|
||||||
private static final String BASE_PACKAGE = "base-package";
|
private static final String BASE_PACKAGE = "base-package";
|
||||||
private static final boolean JSR_303_PRESENT = ClassUtils.isPresent("jakarta.validation.Validator",
|
private static final boolean JSR_303_PRESENT = ClassUtils.isPresent("javax.validation.Validator",
|
||||||
MappingMongoConverterParser.class.getClassLoader());
|
MappingMongoConverterParser.class.getClassLoader());
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -376,6 +376,10 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
|||||||
this.delegates = new HashSet<>(Arrays.asList(filters));
|
this.delegates = new HashSet<>(Arrays.asList(filters));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter#match(org.springframework.core.type.classreading.MetadataReader, org.springframework.core.type.classreading.MetadataReaderFactory)
|
||||||
|
*/
|
||||||
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
|
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
|
|||||||
@@ -47,16 +47,28 @@ public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinit
|
|||||||
private static boolean PROJECT_REACTOR_AVAILABLE = ClassUtils.isPresent("reactor.core.publisher.Mono",
|
private static boolean PROJECT_REACTOR_AVAILABLE = ClassUtils.isPresent("reactor.core.publisher.Mono",
|
||||||
MongoAuditingRegistrar.class.getClassLoader());
|
MongoAuditingRegistrar.class.getClassLoader());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Class<?> getBeanClass(Element element) {
|
protected Class<?> getBeanClass(Element element) {
|
||||||
return AuditingEntityCallback.class;
|
return AuditingEntityCallback.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#shouldGenerateId()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldGenerateId() {
|
protected boolean shouldGenerateId() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ package org.springframework.data.mongodb.config;
|
|||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
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.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
@@ -29,9 +29,13 @@ import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarS
|
|||||||
import org.springframework.data.auditing.config.AuditingConfiguration;
|
import org.springframework.data.auditing.config.AuditingConfiguration;
|
||||||
import org.springframework.data.config.ParsingUtils;
|
import org.springframework.data.config.ParsingUtils;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback;
|
import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableMongoAuditing} annotation.
|
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableMongoAuditing} annotation.
|
||||||
@@ -42,16 +46,31 @@ import org.springframework.util.Assert;
|
|||||||
*/
|
*/
|
||||||
class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
||||||
|
|
||||||
|
private static boolean PROJECT_REACTOR_AVAILABLE = ClassUtils.isPresent("reactor.core.publisher.Mono",
|
||||||
|
MongoAuditingRegistrar.class.getClassLoader());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Class<? extends Annotation> getAnnotation() {
|
protected Class<? extends Annotation> getAnnotation() {
|
||||||
return EnableMongoAuditing.class;
|
return EnableMongoAuditing.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String getAuditingHandlerBeanName() {
|
protected String getAuditingHandlerBeanName() {
|
||||||
return "mongoAuditingHandler";
|
return "mongoAuditingHandler";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
|
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
|
||||||
|
|
||||||
@@ -61,6 +80,10 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
|||||||
super.registerBeanDefinitions(annotationMetadata, registry);
|
super.registerBeanDefinitions(annotationMetadata, registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
|
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
|
||||||
|
|
||||||
@@ -68,13 +91,17 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
|||||||
|
|
||||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
|
||||||
|
|
||||||
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(org.springframework.data.repository.config.PersistentEntitiesFactoryBean.class);
|
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContextLookup.class);
|
||||||
definition.addConstructorArgValue(new RuntimeBeanReference(MappingContext.class));
|
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||||
|
|
||||||
builder.addConstructorArgValue(definition.getBeanDefinition());
|
builder.addConstructorArgValue(definition.getBeanDefinition());
|
||||||
return configureDefaultAuditHandlerAttributes(configuration, builder);
|
return configureDefaultAuditHandlerAttributes(configuration, builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListener(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
|
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
|
||||||
BeanDefinitionRegistry registry) {
|
BeanDefinitionRegistry registry) {
|
||||||
@@ -89,6 +116,68 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
|||||||
|
|
||||||
registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(),
|
registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(),
|
||||||
AuditingEntityCallback.class.getName(), registry);
|
AuditingEntityCallback.class.getName(), registry);
|
||||||
|
|
||||||
|
if (PROJECT_REACTOR_AVAILABLE) {
|
||||||
|
registerReactiveAuditingEntityCallback(registry, auditingHandlerDefinition.getSource());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerReactiveAuditingEntityCallback(BeanDefinitionRegistry registry, Object source) {
|
||||||
|
|
||||||
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class);
|
||||||
|
|
||||||
|
builder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
|
||||||
|
builder.getRawBeanDefinition().setSource(source);
|
||||||
|
|
||||||
|
registerInfrastructureBeanWithId(builder.getBeanDefinition(), ReactiveAuditingEntityCallback.class.getName(),
|
||||||
|
registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple helper to be able to wire the {@link MappingContext} from a {@link MappingMongoConverter} bean available in
|
||||||
|
* the application context.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
static class MongoMappingContextLookup
|
||||||
|
implements FactoryBean<MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty>> {
|
||||||
|
|
||||||
|
private final MappingMongoConverter converter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link MongoMappingContextLookup} for the given {@link MappingMongoConverter}.
|
||||||
|
*
|
||||||
|
* @param converter must not be {@literal null}.
|
||||||
|
*/
|
||||||
|
public MongoMappingContextLookup(MappingMongoConverter converter) {
|
||||||
|
this.converter = converter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getObject() throws Exception {
|
||||||
|
return converter.getMappingContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Class<?> getObjectType() {
|
||||||
|
return MappingContext.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isSingleton() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ import org.w3c.dom.Element;
|
|||||||
*/
|
*/
|
||||||
public class MongoClientParser implements BeanDefinitionParser {
|
public class MongoClientParser implements BeanDefinitionParser {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
Object source = parserContext.extractSource(element);
|
Object source = parserContext.extractSource(element);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||||
|
import org.springframework.data.annotation.Persistent;
|
||||||
import org.springframework.data.convert.CustomConversions;
|
import org.springframework.data.convert.CustomConversions;
|
||||||
import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy;
|
import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy;
|
||||||
import org.springframework.data.mapping.model.FieldNamingStrategy;
|
import org.springframework.data.mapping.model.FieldNamingStrategy;
|
||||||
@@ -139,7 +140,8 @@ public abstract class MongoConfigurationSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans the given base package for entities, i.e. MongoDB specific types annotated with {@link Document}.
|
* Scans the given base package for entities, i.e. MongoDB specific types annotated with {@link Document} and
|
||||||
|
* {@link Persistent}.
|
||||||
*
|
*
|
||||||
* @param basePackage must not be {@literal null}.
|
* @param basePackage must not be {@literal null}.
|
||||||
* @return
|
* @return
|
||||||
@@ -159,6 +161,7 @@ public abstract class MongoConfigurationSupport {
|
|||||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
|
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
|
||||||
false);
|
false);
|
||||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
|
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
|
||||||
|
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||||
|
|
||||||
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||||
|
|
||||||
@@ -172,7 +175,8 @@ public abstract class MongoConfigurationSupport {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures whether to abbreviate field names for domain objects by configuring a
|
* Configures whether to abbreviate field names for domain objects by configuring a
|
||||||
* {@link CamelCaseAbbreviatingFieldNamingStrategy} on the {@link MongoMappingContext} instance created.
|
* {@link CamelCaseAbbreviatingFieldNamingStrategy} on the {@link MongoMappingContext} instance created. For advanced
|
||||||
|
* customization needs, consider overriding {@link #mappingMongoConverter()}.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
|
|||||||
private static final String OPTIONS_DELIMITER = "?";
|
private static final String OPTIONS_DELIMITER = "?";
|
||||||
private static final String OPTION_VALUE_DELIMITER = "&";
|
private static final String OPTION_VALUE_DELIMITER = "&";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setAsText(@Nullable String text) throws IllegalArgumentException {
|
public void setAsText(@Nullable String text) throws IllegalArgumentException {
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
|
|||||||
MONGO_URI_ALLOWED_ADDITIONAL_ATTRIBUTES = Collections.unmodifiableSet(mongoUriAllowedAdditionalAttributes);
|
MONGO_URI_ALLOWED_ADDITIONAL_ATTRIBUTES = Collections.unmodifiableSet(mongoUriAllowedAdditionalAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||||
throws BeanDefinitionStoreException {
|
throws BeanDefinitionStoreException {
|
||||||
@@ -70,6 +74,10 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
|
|||||||
return StringUtils.hasText(id) ? id : BeanNames.DB_FACTORY_BEAN_NAME;
|
return StringUtils.hasText(id) ? id : BeanNames.DB_FACTORY_BEAN_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
|||||||
*/
|
*/
|
||||||
public class MongoNamespaceHandler extends NamespaceHandlerSupport {
|
public class MongoNamespaceHandler extends NamespaceHandlerSupport {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
||||||
|
*/
|
||||||
public void init() {
|
public void init() {
|
||||||
|
|
||||||
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
|
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
|
||||||
|
|||||||
@@ -22,12 +22,9 @@ import java.util.Map;
|
|||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.CustomEditorConfigurer;
|
import org.springframework.beans.factory.config.CustomEditorConfigurer;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionValidationException;
|
|
||||||
import org.springframework.beans.factory.support.ManagedMap;
|
import org.springframework.beans.factory.support.ManagedMap;
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
import org.springframework.data.mongodb.core.MongoClientSettingsFactoryBean;
|
import org.springframework.data.mongodb.core.MongoClientSettingsFactoryBean;
|
||||||
import org.springframework.data.mongodb.core.MongoServerApiFactoryBean;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.util.xml.DomUtils;
|
import org.springframework.util.xml.DomUtils;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
@@ -115,20 +112,6 @@ abstract class MongoParsingUtils {
|
|||||||
// Field level encryption
|
// Field level encryption
|
||||||
setPropertyReference(clientOptionsDefBuilder, settingsElement, "encryption-settings-ref", "autoEncryptionSettings");
|
setPropertyReference(clientOptionsDefBuilder, settingsElement, "encryption-settings-ref", "autoEncryptionSettings");
|
||||||
|
|
||||||
// ServerAPI
|
|
||||||
if (StringUtils.hasText(settingsElement.getAttribute("server-api-version"))) {
|
|
||||||
|
|
||||||
MongoServerApiFactoryBean serverApiFactoryBean = new MongoServerApiFactoryBean();
|
|
||||||
serverApiFactoryBean.setVersion(settingsElement.getAttribute("server-api-version"));
|
|
||||||
try {
|
|
||||||
clientOptionsDefBuilder.addPropertyValue("serverApi", serverApiFactoryBean.getObject());
|
|
||||||
} catch (Exception exception) {
|
|
||||||
throw new BeanDefinitionValidationException("Non parsable server-api.", exception);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setPropertyReference(clientOptionsDefBuilder, settingsElement, "server-api-ref", "serverApi");
|
|
||||||
}
|
|
||||||
|
|
||||||
// and the rest
|
// and the rest
|
||||||
|
|
||||||
mongoClientBuilder.addPropertyValue("mongoClientSettings", clientOptionsDefBuilder.getBeanDefinition());
|
mongoClientBuilder.addPropertyValue("mongoClientSettings", clientOptionsDefBuilder.getBeanDefinition());
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ import org.w3c.dom.Element;
|
|||||||
*/
|
*/
|
||||||
class MongoTemplateParser extends AbstractBeanDefinitionParser {
|
class MongoTemplateParser extends AbstractBeanDefinitionParser {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||||
throws BeanDefinitionStoreException {
|
throws BeanDefinitionStoreException {
|
||||||
@@ -47,6 +51,10 @@ class MongoTemplateParser extends AbstractBeanDefinitionParser {
|
|||||||
return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE_BEAN_NAME;
|
return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE_BEAN_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020-2021 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.data.mongodb.config;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
|
||||||
import org.springframework.data.mapping.context.PersistentEntities;
|
|
||||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple helper to be able to wire the {@link PersistentEntities} from a {@link MappingMongoConverter} bean available
|
|
||||||
* in the application context.
|
|
||||||
*
|
|
||||||
* @author Oliver Gierke
|
|
||||||
* @author Mark Paluch
|
|
||||||
* @author Christoph Strobl
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
public class PersistentEntitiesFactoryBean implements FactoryBean<PersistentEntities> {
|
|
||||||
|
|
||||||
private final MappingMongoConverter converter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link PersistentEntitiesFactoryBean} for the given {@link MappingMongoConverter}.
|
|
||||||
*
|
|
||||||
* @param converter must not be {@literal null}.
|
|
||||||
*/
|
|
||||||
public PersistentEntitiesFactoryBean(MappingMongoConverter converter) {
|
|
||||||
this.converter = converter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PersistentEntities getObject() {
|
|
||||||
return PersistentEntities.of(converter.getMappingContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> getObjectType() {
|
|
||||||
return PersistentEntities.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020-2021 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.data.mongodb.config;
|
|
||||||
|
|
||||||
import java.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;
|
|
||||||
import org.springframework.data.config.ParsingUtils;
|
|
||||||
import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableReactiveMongoAuditing} annotation.
|
|
||||||
*
|
|
||||||
* @author Mark Paluch
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
class ReactiveMongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class<? extends Annotation> getAnnotation() {
|
|
||||||
return EnableReactiveMongoAuditing.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getAuditingHandlerBeanName() {
|
|
||||||
return "reactiveMongoAuditingHandler";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
|
|
||||||
BeanDefinitionRegistry registry) {
|
|
||||||
|
|
||||||
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!");
|
|
||||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
|
|
||||||
|
|
||||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class);
|
|
||||||
|
|
||||||
builder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
|
|
||||||
builder.getRawBeanDefinition().setSource(auditingHandlerDefinition.getSource());
|
|
||||||
|
|
||||||
registerInfrastructureBeanWithId(builder.getBeanDefinition(), ReactiveAuditingEntityCallback.class.getName(),
|
|
||||||
registry);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -32,6 +32,10 @@ import com.mongodb.ReadConcernLevel;
|
|||||||
*/
|
*/
|
||||||
public class ReadConcernPropertyEditor extends PropertyEditorSupport {
|
public class ReadConcernPropertyEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setAsText(@Nullable String readConcernString) {
|
public void setAsText(@Nullable String readConcernString) {
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ import com.mongodb.ReadPreference;
|
|||||||
*/
|
*/
|
||||||
public class ReadPreferencePropertyEditor extends PropertyEditorSupport {
|
public class ReadPreferencePropertyEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setAsText(@Nullable String readPreferenceString) throws IllegalArgumentException {
|
public void setAsText(@Nullable String readPreferenceString) throws IllegalArgumentException {
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ import java.net.UnknownHostException;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.slf4j.Logger;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
@@ -43,9 +43,13 @@ 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 :.
|
* 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 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 {} '{}'. Check your replica set configuration!";
|
||||||
private static final Log LOG = LogFactory.getLog(ServerAddressPropertyEditor.class);
|
private static final Logger LOG = LoggerFactory.getLogger(ServerAddressPropertyEditor.class);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setAsText(@Nullable String replicaSetString) {
|
public void setAsText(@Nullable String replicaSetString) {
|
||||||
|
|
||||||
@@ -84,18 +88,14 @@ public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
|||||||
private ServerAddress parseServerAddress(String source) {
|
private ServerAddress parseServerAddress(String source) {
|
||||||
|
|
||||||
if (!StringUtils.hasText(source)) {
|
if (!StringUtils.hasText(source)) {
|
||||||
if(LOG.isWarnEnabled()) {
|
LOG.warn(COULD_NOT_PARSE_ADDRESS_MESSAGE, "source", source);
|
||||||
LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "source", source));
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] hostAndPort = extractHostAddressAndPort(source.trim());
|
String[] hostAndPort = extractHostAddressAndPort(source.trim());
|
||||||
|
|
||||||
if (hostAndPort.length > 2) {
|
if (hostAndPort.length > 2) {
|
||||||
if(LOG.isWarnEnabled()) {
|
LOG.warn(COULD_NOT_PARSE_ADDRESS_MESSAGE, "source", source);
|
||||||
LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "source", source));
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,13 +105,9 @@ public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
|||||||
|
|
||||||
return port == null ? new ServerAddress(hostAddress) : new ServerAddress(hostAddress, port);
|
return port == null ? new ServerAddress(hostAddress) : new ServerAddress(hostAddress, port);
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
if(LOG.isWarnEnabled()) {
|
LOG.warn(COULD_NOT_PARSE_ADDRESS_MESSAGE, "host", hostAndPort[0]);
|
||||||
LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "host", hostAndPort[0]));
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
if(LOG.isWarnEnabled()) {
|
LOG.warn(COULD_NOT_PARSE_ADDRESS_MESSAGE, "port", hostAndPort[1]);
|
||||||
LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "port", hostAndPort[1]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ import com.mongodb.WriteConcern;
|
|||||||
*/
|
*/
|
||||||
public class StringToWriteConcernConverter implements Converter<String, WriteConcern> {
|
public class StringToWriteConcernConverter implements Converter<String, WriteConcern> {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
|
||||||
|
*/
|
||||||
public WriteConcern convert(String source) {
|
public WriteConcern convert(String source) {
|
||||||
|
|
||||||
WriteConcern writeConcern = WriteConcern.valueOf(source);
|
WriteConcern writeConcern = WriteConcern.valueOf(source);
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ import org.springframework.util.StringUtils;
|
|||||||
*/
|
*/
|
||||||
public class UUidRepresentationPropertyEditor extends PropertyEditorSupport {
|
public class UUidRepresentationPropertyEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setAsText(@Nullable String value) {
|
public void setAsText(@Nullable String value) {
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -27,9 +29,7 @@ import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
|||||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
||||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
|
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
|
||||||
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
|
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.CountOperation;
|
||||||
import org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext;
|
|
||||||
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
|
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
|
||||||
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
||||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||||
@@ -37,7 +37,6 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
|||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
import org.springframework.data.util.Lazy;
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
@@ -50,52 +49,36 @@ import org.springframework.util.ObjectUtils;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
class AggregationUtil {
|
class AggregationUtil {
|
||||||
|
|
||||||
QueryMapper queryMapper;
|
QueryMapper queryMapper;
|
||||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||||
Lazy<AggregationOperationContext> untypedMappingContext;
|
|
||||||
|
|
||||||
AggregationUtil(QueryMapper queryMapper,
|
/**
|
||||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
* Prepare the {@link AggregationOperationContext} for a given aggregation by either returning the context itself it
|
||||||
|
* is not {@literal null}, create a {@link TypeBasedAggregationOperationContext} if the aggregation contains type
|
||||||
|
* information (is a {@link TypedAggregation}) or use the {@link Aggregation#DEFAULT_CONTEXT}.
|
||||||
|
*
|
||||||
|
* @param aggregation must not be {@literal null}.
|
||||||
|
* @param context can be {@literal null}.
|
||||||
|
* @return the root {@link AggregationOperationContext} to use.
|
||||||
|
*/
|
||||||
|
AggregationOperationContext prepareAggregationContext(Aggregation aggregation,
|
||||||
|
@Nullable AggregationOperationContext context) {
|
||||||
|
|
||||||
this.queryMapper = queryMapper;
|
if (context != null) {
|
||||||
this.mappingContext = mappingContext;
|
return context;
|
||||||
this.untypedMappingContext = Lazy
|
|
||||||
.of(() -> new RelaxedTypeBasedAggregationOperationContext(Object.class, mappingContext, queryMapper));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AggregationOperationContext createAggregationContext(Aggregation aggregation, @Nullable Class<?> inputType) {
|
if (aggregation instanceof TypedAggregation) {
|
||||||
|
return new TypeBasedAggregationOperationContext(((TypedAggregation) aggregation).getInputType(), mappingContext,
|
||||||
|
queryMapper);
|
||||||
|
}
|
||||||
|
|
||||||
DomainTypeMapping domainTypeMapping = aggregation.getOptions().getDomainTypeMapping();
|
|
||||||
|
|
||||||
if (domainTypeMapping == DomainTypeMapping.NONE) {
|
|
||||||
return Aggregation.DEFAULT_CONTEXT;
|
return Aggregation.DEFAULT_CONTEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(aggregation instanceof TypedAggregation)) {
|
|
||||||
|
|
||||||
if(inputType == null) {
|
|
||||||
return untypedMappingContext.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (domainTypeMapping == DomainTypeMapping.STRICT
|
|
||||||
&& !aggregation.getPipeline().containsUnionWith()) {
|
|
||||||
return new TypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RelaxedTypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
inputType = ((TypedAggregation<?>) aggregation).getInputType();
|
|
||||||
if (domainTypeMapping == DomainTypeMapping.STRICT
|
|
||||||
&& !aggregation.getPipeline().containsUnionWith()) {
|
|
||||||
return new TypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RelaxedTypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract and map the aggregation pipeline into a {@link List} of {@link Document}.
|
* Extract and map the aggregation pipeline into a {@link List} of {@link Document}.
|
||||||
*
|
*
|
||||||
@@ -105,7 +88,7 @@ class AggregationUtil {
|
|||||||
*/
|
*/
|
||||||
List<Document> createPipeline(Aggregation aggregation, AggregationOperationContext context) {
|
List<Document> createPipeline(Aggregation aggregation, AggregationOperationContext context) {
|
||||||
|
|
||||||
if (ObjectUtils.nullSafeEquals(context, Aggregation.DEFAULT_CONTEXT)) {
|
if (!ObjectUtils.nullSafeEquals(context, Aggregation.DEFAULT_CONTEXT)) {
|
||||||
return aggregation.toPipeline(context);
|
return aggregation.toPipeline(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +115,53 @@ class AggregationUtil {
|
|||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@code $count} aggregation for {@link Query} and optionally a {@link Class entity class}.
|
||||||
|
*
|
||||||
|
* @param query must not be {@literal null}.
|
||||||
|
* @param entityClass can be {@literal null} if the {@link Query} object is empty.
|
||||||
|
* @return the {@link Aggregation} pipeline definition to run a {@code $count} aggregation.
|
||||||
|
*/
|
||||||
|
Aggregation createCountAggregation(Query query, @Nullable Class<?> entityClass) {
|
||||||
|
|
||||||
|
List<AggregationOperation> pipeline = computeCountAggregationPipeline(query, entityClass);
|
||||||
|
|
||||||
|
Aggregation aggregation = entityClass != null ? Aggregation.newAggregation(entityClass, pipeline)
|
||||||
|
: Aggregation.newAggregation(pipeline);
|
||||||
|
aggregation.withOptions(AggregationOptions.builder().collation(query.getCollation().orElse(null)).build());
|
||||||
|
|
||||||
|
return aggregation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AggregationOperation> computeCountAggregationPipeline(Query query, @Nullable Class<?> entityType) {
|
||||||
|
|
||||||
|
CountOperation count = Aggregation.count().as("totalEntityCount");
|
||||||
|
if (query.getQueryObject().isEmpty()) {
|
||||||
|
return Collections.singletonList(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.notNull(entityType, "Entity type must not be null!");
|
||||||
|
|
||||||
|
Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(),
|
||||||
|
mappingContext.getPersistentEntity(entityType));
|
||||||
|
|
||||||
|
CriteriaDefinition criteria = new CriteriaDefinition() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Document getCriteriaObject() {
|
||||||
|
return mappedQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Arrays.asList(Aggregation.match(criteria), count);
|
||||||
|
}
|
||||||
|
|
||||||
private List<Document> mapAggregationPipeline(List<Document> pipeline) {
|
private List<Document> mapAggregationPipeline(List<Document> pipeline) {
|
||||||
|
|
||||||
return pipeline.stream().map(val -> queryMapper.getMappedObject(val, Optional.empty()))
|
return pipeline.stream().map(val -> queryMapper.getMappedObject(val, Optional.empty()))
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
|
|
||||||
@@ -25,7 +27,6 @@ import org.springframework.data.mongodb.core.convert.MongoConverter;
|
|||||||
import org.springframework.data.mongodb.core.messaging.Message;
|
import org.springframework.data.mongodb.core.messaging.Message;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
|
||||||
|
|
||||||
import com.mongodb.client.model.changestream.ChangeStreamDocument;
|
import com.mongodb.client.model.changestream.ChangeStreamDocument;
|
||||||
import com.mongodb.client.model.changestream.OperationType;
|
import com.mongodb.client.model.changestream.OperationType;
|
||||||
@@ -38,6 +39,7 @@ import com.mongodb.client.model.changestream.OperationType;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
|
@EqualsAndHashCode
|
||||||
public class ChangeStreamEvent<T> {
|
public class ChangeStreamEvent<T> {
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes") //
|
@SuppressWarnings("rawtypes") //
|
||||||
@@ -185,35 +187,16 @@ public class ChangeStreamEvent<T> {
|
|||||||
return CONVERTED_UPDATER.compareAndSet(this, null, result) ? result : CONVERTED_UPDATER.get(this);
|
return CONVERTED_UPDATER.compareAndSet(this, null, result) ? result : CONVERTED_UPDATER.get(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(String.format("No converter found capable of converting %s to %s",
|
||||||
String.format("No converter found capable of converting %s to %s", fullDocument.getClass(), targetType));
|
fullDocument.getClass(), targetType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ChangeStreamEvent {" + "raw=" + raw + ", targetType=" + targetType + '}';
|
return "ChangeStreamEvent {" + "raw=" + raw + ", targetType=" + targetType + '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (o == null || getClass() != o.getClass())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ChangeStreamEvent<?> that = (ChangeStreamEvent<?>) o;
|
|
||||||
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.raw, that.raw)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ObjectUtils.nullSafeEquals(this.targetType, that.targetType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = raw != null ? raw.hashCode() : 0;
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(targetType);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -23,6 +25,7 @@ import org.bson.BsonDocument;
|
|||||||
import org.bson.BsonTimestamp;
|
import org.bson.BsonTimestamp;
|
||||||
import org.bson.BsonValue;
|
import org.bson.BsonValue;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||||
import org.springframework.data.mongodb.core.query.Collation;
|
import org.springframework.data.mongodb.core.query.Collation;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
@@ -42,6 +45,7 @@ import com.mongodb.client.model.changestream.FullDocument;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
|
@EqualsAndHashCode
|
||||||
public class ChangeStreamOptions {
|
public class ChangeStreamOptions {
|
||||||
|
|
||||||
private @Nullable Object filter;
|
private @Nullable Object filter;
|
||||||
@@ -152,44 +156,6 @@ public class ChangeStreamOptions {
|
|||||||
+ ObjectUtils.nullSafeClassName(timestamp));
|
+ ObjectUtils.nullSafeClassName(timestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (o == null || getClass() != o.getClass())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ChangeStreamOptions that = (ChangeStreamOptions) o;
|
|
||||||
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.filter, that.filter)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.resumeToken, that.resumeToken)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.fullDocumentLookup, that.fullDocumentLookup)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.collation, that.collation)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.resumeTimestamp, that.resumeTimestamp)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return resume == that.resume;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = ObjectUtils.nullSafeHashCode(filter);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(resumeToken);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(fullDocumentLookup);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(collation);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(resumeTimestamp);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(resume);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.2
|
* @since 2.2
|
||||||
@@ -242,13 +208,13 @@ public class ChangeStreamOptions {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the filter to apply.
|
* Set the filter to apply.
|
||||||
* <br />
|
* <p/>
|
||||||
* Fields on aggregation expression root level are prefixed to map to fields contained in
|
* Fields on aggregation expression root level are prefixed to map to fields contained in
|
||||||
* {@link ChangeStreamDocument#getFullDocument() fullDocument}. However {@literal operationType}, {@literal ns},
|
* {@link ChangeStreamDocument#getFullDocument() fullDocument}. However {@literal operationType}, {@literal ns},
|
||||||
* {@literal documentKey} and {@literal fullDocument} are reserved words that will be omitted, and therefore taken
|
* {@literal documentKey} and {@literal fullDocument} are reserved words that will be omitted, and therefore taken
|
||||||
* as given, during the mapping procedure. You may want to have a look at the
|
* as given, during the mapping procedure. You may want to have a look at the
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/change-events/">structure of Change Events</a>.
|
* <a href="https://docs.mongodb.com/manual/reference/change-events/">structure of Change Events</a>.
|
||||||
* <br />
|
* <p/>
|
||||||
* Use {@link org.springframework.data.mongodb.core.aggregation.TypedAggregation} to ensure filter expressions are
|
* Use {@link org.springframework.data.mongodb.core.aggregation.TypedAggregation} to ensure filter expressions are
|
||||||
* mapped to domain type fields.
|
* mapped to domain type fields.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -15,13 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.mapping.Field;
|
|
||||||
import org.springframework.data.mongodb.core.query.Collation;
|
import org.springframework.data.mongodb.core.query.Collation;
|
||||||
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
|
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
|
||||||
import org.springframework.data.mongodb.core.timeseries.Granularity;
|
|
||||||
import org.springframework.data.mongodb.core.timeseries.GranularityDefinition;
|
|
||||||
import org.springframework.data.mongodb.core.validation.Validator;
|
import org.springframework.data.mongodb.core.validation.Validator;
|
||||||
import org.springframework.data.util.Optionals;
|
import org.springframework.data.util.Optionals;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
@@ -45,7 +44,6 @@ public class CollectionOptions {
|
|||||||
private @Nullable Boolean capped;
|
private @Nullable Boolean capped;
|
||||||
private @Nullable Collation collation;
|
private @Nullable Collation collation;
|
||||||
private ValidationOptions validationOptions;
|
private ValidationOptions validationOptions;
|
||||||
private @Nullable TimeSeriesOptions timeSeriesOptions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new <code>CollectionOptions</code> instance.
|
* Constructs a new <code>CollectionOptions</code> instance.
|
||||||
@@ -58,19 +56,17 @@ public class CollectionOptions {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped) {
|
public CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped) {
|
||||||
this(size, maxDocuments, capped, null, ValidationOptions.none(), null);
|
this(size, maxDocuments, capped, null, ValidationOptions.none());
|
||||||
}
|
}
|
||||||
|
|
||||||
private CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped,
|
private CollectionOptions(@Nullable Long size, @Nullable Long maxDocuments, @Nullable Boolean capped,
|
||||||
@Nullable Collation collation, ValidationOptions validationOptions,
|
@Nullable Collation collation, ValidationOptions validationOptions) {
|
||||||
@Nullable TimeSeriesOptions timeSeriesOptions) {
|
|
||||||
|
|
||||||
this.maxDocuments = maxDocuments;
|
this.maxDocuments = maxDocuments;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.capped = capped;
|
this.capped = capped;
|
||||||
this.collation = collation;
|
this.collation = collation;
|
||||||
this.validationOptions = validationOptions;
|
this.validationOptions = validationOptions;
|
||||||
this.timeSeriesOptions = timeSeriesOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +80,7 @@ public class CollectionOptions {
|
|||||||
|
|
||||||
Assert.notNull(collation, "Collation must not be null!");
|
Assert.notNull(collation, "Collation must not be null!");
|
||||||
|
|
||||||
return new CollectionOptions(null, null, null, collation, ValidationOptions.none(), null);
|
return new CollectionOptions(null, null, null, collation, ValidationOptions.none());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,21 +90,7 @@ public class CollectionOptions {
|
|||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public static CollectionOptions empty() {
|
public static CollectionOptions empty() {
|
||||||
return new CollectionOptions(null, null, null, null, ValidationOptions.none(), null);
|
return new CollectionOptions(null, null, null, null, ValidationOptions.none());
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Quick way to set up {@link CollectionOptions} for a Time Series collection. For more advanced settings use
|
|
||||||
* {@link #timeSeries(TimeSeriesOptions)}.
|
|
||||||
*
|
|
||||||
* @param timeField The name of the property which contains the date in each time series document. Must not be
|
|
||||||
* {@literal null}.
|
|
||||||
* @return new instance of {@link CollectionOptions}.
|
|
||||||
* @see #timeSeries(TimeSeriesOptions)
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
public static CollectionOptions timeSeries(String timeField) {
|
|
||||||
return empty().timeSeries(TimeSeriesOptions.timeSeries(timeField));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,7 +101,7 @@ public class CollectionOptions {
|
|||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public CollectionOptions capped() {
|
public CollectionOptions capped() {
|
||||||
return new CollectionOptions(size, maxDocuments, true, collation, validationOptions, null);
|
return new CollectionOptions(size, maxDocuments, true, collation, validationOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,7 +112,7 @@ public class CollectionOptions {
|
|||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public CollectionOptions maxDocuments(long maxDocuments) {
|
public CollectionOptions maxDocuments(long maxDocuments) {
|
||||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions);
|
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,7 +123,7 @@ public class CollectionOptions {
|
|||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public CollectionOptions size(long size) {
|
public CollectionOptions size(long size) {
|
||||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions);
|
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,7 +134,7 @@ public class CollectionOptions {
|
|||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public CollectionOptions collation(@Nullable Collation collation) {
|
public CollectionOptions collation(@Nullable Collation collation) {
|
||||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions);
|
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -272,20 +254,7 @@ public class CollectionOptions {
|
|||||||
public CollectionOptions validation(ValidationOptions validationOptions) {
|
public CollectionOptions validation(ValidationOptions validationOptions) {
|
||||||
|
|
||||||
Assert.notNull(validationOptions, "ValidationOptions must not be null!");
|
Assert.notNull(validationOptions, "ValidationOptions must not be null!");
|
||||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions);
|
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create new {@link CollectionOptions} with the given {@link TimeSeriesOptions}.
|
|
||||||
*
|
|
||||||
* @param timeSeriesOptions must not be {@literal null}.
|
|
||||||
* @return new instance of {@link CollectionOptions}.
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
public CollectionOptions timeSeries(TimeSeriesOptions timeSeriesOptions) {
|
|
||||||
|
|
||||||
Assert.notNull(timeSeriesOptions, "TimeSeriesOptions must not be null!");
|
|
||||||
return new CollectionOptions(size, maxDocuments, capped, collation, validationOptions, timeSeriesOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -336,16 +305,6 @@ public class CollectionOptions {
|
|||||||
return validationOptions.isEmpty() ? Optional.empty() : Optional.of(validationOptions);
|
return validationOptions.isEmpty() ? Optional.empty() : Optional.of(validationOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the {@link TimeSeriesOptions} if available.
|
|
||||||
*
|
|
||||||
* @return {@link Optional#empty()} if not specified.
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
public Optional<TimeSeriesOptions> getTimeSeriesOptions() {
|
|
||||||
return Optional.ofNullable(timeSeriesOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulation of ValidationOptions options.
|
* Encapsulation of ValidationOptions options.
|
||||||
*
|
*
|
||||||
@@ -353,6 +312,7 @@ public class CollectionOptions {
|
|||||||
* @author Andreas Zink
|
* @author Andreas Zink
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
public static class ValidationOptions {
|
public static class ValidationOptions {
|
||||||
|
|
||||||
private static final ValidationOptions NONE = new ValidationOptions(null, null, null);
|
private static final ValidationOptions NONE = new ValidationOptions(null, null, null);
|
||||||
@@ -361,13 +321,6 @@ public class CollectionOptions {
|
|||||||
private final @Nullable ValidationLevel validationLevel;
|
private final @Nullable ValidationLevel validationLevel;
|
||||||
private final @Nullable ValidationAction validationAction;
|
private final @Nullable ValidationAction validationAction;
|
||||||
|
|
||||||
public ValidationOptions(Validator validator, ValidationLevel validationLevel, ValidationAction validationAction) {
|
|
||||||
|
|
||||||
this.validator = validator;
|
|
||||||
this.validationLevel = validationLevel;
|
|
||||||
this.validationAction = validationAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an empty {@link ValidationOptions}.
|
* Create an empty {@link ValidationOptions}.
|
||||||
*
|
*
|
||||||
@@ -428,7 +381,7 @@ public class CollectionOptions {
|
|||||||
/**
|
/**
|
||||||
* Get the {@code validationAction} to perform.
|
* Get the {@code validationAction} to perform.
|
||||||
*
|
*
|
||||||
* @return {@link Optional#empty()} if not set.
|
* @return @return {@link Optional#empty()} if not set.
|
||||||
*/
|
*/
|
||||||
public Optional<ValidationAction> getValidationAction() {
|
public Optional<ValidationAction> getValidationAction() {
|
||||||
return Optional.ofNullable(validationAction);
|
return Optional.ofNullable(validationAction);
|
||||||
@@ -441,89 +394,4 @@ public class CollectionOptions {
|
|||||||
return !Optionals.isAnyPresent(getValidator(), getValidationAction(), getValidationLevel());
|
return !Optionals.isAnyPresent(getValidator(), getValidationAction(), getValidationLevel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Options applicable to Time Series collections.
|
|
||||||
*
|
|
||||||
* @author Christoph Strobl
|
|
||||||
* @since 3.3
|
|
||||||
* @see <a href=
|
|
||||||
* "https://docs.mongodb.com/manual/core/timeseries-collections">https://docs.mongodb.com/manual/core/timeseries-collections</a>
|
|
||||||
*/
|
|
||||||
public static class TimeSeriesOptions {
|
|
||||||
|
|
||||||
private final String timeField;
|
|
||||||
|
|
||||||
private @Nullable final String metaField;
|
|
||||||
|
|
||||||
private final GranularityDefinition granularity;
|
|
||||||
|
|
||||||
private TimeSeriesOptions(String timeField, @Nullable String metaField, GranularityDefinition granularity) {
|
|
||||||
|
|
||||||
Assert.hasText(timeField, "Time field must not be empty or null!");
|
|
||||||
|
|
||||||
this.timeField = timeField;
|
|
||||||
this.metaField = metaField;
|
|
||||||
this.granularity = granularity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance of {@link TimeSeriesOptions} using the given field as its {@literal timeField}. The one,
|
|
||||||
* that contains the date in each time series document. <br />
|
|
||||||
* {@link Field#name() Annotated fieldnames} will be considered during the mapping process.
|
|
||||||
*
|
|
||||||
* @param timeField must not be {@literal null}.
|
|
||||||
* @return new instance of {@link TimeSeriesOptions}.
|
|
||||||
*/
|
|
||||||
public static TimeSeriesOptions timeSeries(String timeField) {
|
|
||||||
return new TimeSeriesOptions(timeField, null, Granularity.DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the name of the field which contains metadata in each time series document. Should not be the {@literal id}
|
|
||||||
* nor {@link TimeSeriesOptions#timeSeries(String)} timeField} nor point to an {@literal array} or
|
|
||||||
* {@link java.util.Collection}. <br />
|
|
||||||
* {@link Field#name() Annotated fieldnames} will be considered during the mapping process.
|
|
||||||
*
|
|
||||||
* @param metaField must not be {@literal null}.
|
|
||||||
* @return new instance of {@link TimeSeriesOptions}.
|
|
||||||
*/
|
|
||||||
public TimeSeriesOptions metaField(String metaField) {
|
|
||||||
return new TimeSeriesOptions(timeField, metaField, granularity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select the {@link GranularityDefinition} parameter to define how data in the time series collection is organized.
|
|
||||||
* Select one that is closest to the time span between incoming measurements.
|
|
||||||
*
|
|
||||||
* @return new instance of {@link TimeSeriesOptions}.
|
|
||||||
* @see Granularity
|
|
||||||
*/
|
|
||||||
public TimeSeriesOptions granularity(GranularityDefinition granularity) {
|
|
||||||
return new TimeSeriesOptions(timeField, metaField, granularity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return never {@literal null}.
|
|
||||||
*/
|
|
||||||
public String getTimeField() {
|
|
||||||
return timeField;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return can be {@literal null}. Might be an {@literal empty} {@link String} as well, so maybe check via
|
|
||||||
* {@link org.springframework.util.StringUtils#hasText(String)}.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public String getMetaField() {
|
|
||||||
return metaField;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return never {@literal null}.
|
|
||||||
*/
|
|
||||||
public GranularityDefinition getGranularity() {
|
|
||||||
return granularity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -24,9 +27,8 @@ import java.util.stream.Collectors;
|
|||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.conversions.Bson;
|
import org.bson.conversions.Bson;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.dao.DataIntegrityViolationException;
|
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||||
import org.springframework.data.mapping.callback.EntityCallbacks;
|
import org.springframework.data.mapping.callback.EntityCallbacks;
|
||||||
import org.springframework.data.mongodb.BulkOperationException;
|
|
||||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||||
import org.springframework.data.mongodb.core.convert.UpdateMapper;
|
import org.springframework.data.mongodb.core.convert.UpdateMapper;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
@@ -45,9 +47,7 @@ import org.springframework.data.mongodb.core.query.UpdateDefinition.ArrayFilter;
|
|||||||
import org.springframework.data.util.Pair;
|
import org.springframework.data.util.Pair;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
|
||||||
|
|
||||||
import com.mongodb.MongoBulkWriteException;
|
|
||||||
import com.mongodb.WriteConcern;
|
import com.mongodb.WriteConcern;
|
||||||
import com.mongodb.bulk.BulkWriteResult;
|
import com.mongodb.bulk.BulkWriteResult;
|
||||||
import com.mongodb.client.MongoCollection;
|
import com.mongodb.client.MongoCollection;
|
||||||
@@ -64,7 +64,6 @@ import com.mongodb.client.model.*;
|
|||||||
* @author Jens Schauder
|
* @author Jens Schauder
|
||||||
* @author Michail Nikolaev
|
* @author Michail Nikolaev
|
||||||
* @author Roman Puchkovskiy
|
* @author Roman Puchkovskiy
|
||||||
* @author Jacob Botuck
|
|
||||||
* @since 1.9
|
* @since 1.9
|
||||||
*/
|
*/
|
||||||
class DefaultBulkOperations implements BulkOperations {
|
class DefaultBulkOperations implements BulkOperations {
|
||||||
@@ -74,6 +73,7 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
private final BulkOperationContext bulkOperationContext;
|
private final BulkOperationContext bulkOperationContext;
|
||||||
private final List<SourceAwareWriteModelHolder> models = new ArrayList<>();
|
private final List<SourceAwareWriteModelHolder> models = new ArrayList<>();
|
||||||
|
|
||||||
|
private PersistenceExceptionTranslator exceptionTranslator;
|
||||||
private @Nullable WriteConcern defaultWriteConcern;
|
private @Nullable WriteConcern defaultWriteConcern;
|
||||||
|
|
||||||
private BulkWriteOptions bulkOptions;
|
private BulkWriteOptions bulkOptions;
|
||||||
@@ -97,9 +97,19 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
this.mongoOperations = mongoOperations;
|
this.mongoOperations = mongoOperations;
|
||||||
this.collectionName = collectionName;
|
this.collectionName = collectionName;
|
||||||
this.bulkOperationContext = bulkOperationContext;
|
this.bulkOperationContext = bulkOperationContext;
|
||||||
|
this.exceptionTranslator = new MongoExceptionTranslator();
|
||||||
this.bulkOptions = getBulkWriteOptions(bulkOperationContext.getBulkMode());
|
this.bulkOptions = getBulkWriteOptions(bulkOperationContext.getBulkMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the {@link PersistenceExceptionTranslator} to be used. Defaults to {@link MongoExceptionTranslator}.
|
||||||
|
*
|
||||||
|
* @param exceptionTranslator can be {@literal null}.
|
||||||
|
*/
|
||||||
|
public void setExceptionTranslator(@Nullable PersistenceExceptionTranslator exceptionTranslator) {
|
||||||
|
this.exceptionTranslator = exceptionTranslator == null ? new MongoExceptionTranslator() : exceptionTranslator;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the default {@link WriteConcern} to be used. Defaults to {@literal null}.
|
* Configures the default {@link WriteConcern} to be used. Defaults to {@literal null}.
|
||||||
*
|
*
|
||||||
@@ -109,6 +119,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
this.defaultWriteConcern = defaultWriteConcern;
|
this.defaultWriteConcern = defaultWriteConcern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#insert(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BulkOperations insert(Object document) {
|
public BulkOperations insert(Object document) {
|
||||||
|
|
||||||
@@ -121,6 +135,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#insert(java.util.List)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BulkOperations insert(List<? extends Object> documents) {
|
public BulkOperations insert(List<? extends Object> documents) {
|
||||||
|
|
||||||
@@ -131,6 +149,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#updateOne(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.Update)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public BulkOperations updateOne(Query query, Update update) {
|
public BulkOperations updateOne(Query query, Update update) {
|
||||||
@@ -141,6 +163,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
return updateOne(Collections.singletonList(Pair.of(query, update)));
|
return updateOne(Collections.singletonList(Pair.of(query, update)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#updateOne(java.util.List)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BulkOperations updateOne(List<Pair<Query, Update>> updates) {
|
public BulkOperations updateOne(List<Pair<Query, Update>> updates) {
|
||||||
|
|
||||||
@@ -153,6 +179,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#updateMulti(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.Update)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public BulkOperations updateMulti(Query query, Update update) {
|
public BulkOperations updateMulti(Query query, Update update) {
|
||||||
@@ -163,6 +193,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
return updateMulti(Collections.singletonList(Pair.of(query, update)));
|
return updateMulti(Collections.singletonList(Pair.of(query, update)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#updateMulti(java.util.List)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BulkOperations updateMulti(List<Pair<Query, Update>> updates) {
|
public BulkOperations updateMulti(List<Pair<Query, Update>> updates) {
|
||||||
|
|
||||||
@@ -175,11 +209,19 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#upsert(org.springframework.data.mongodb.core.query.Query, org.springframework.data.mongodb.core.query.Update)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BulkOperations upsert(Query query, Update update) {
|
public BulkOperations upsert(Query query, Update update) {
|
||||||
return update(query, update, true, true);
|
return update(query, update, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#upsert(java.util.List)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BulkOperations upsert(List<Pair<Query, Update>> updates) {
|
public BulkOperations upsert(List<Pair<Query, Update>> updates) {
|
||||||
|
|
||||||
@@ -190,6 +232,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#remove(org.springframework.data.mongodb.core.query.Query)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BulkOperations remove(Query query) {
|
public BulkOperations remove(Query query) {
|
||||||
|
|
||||||
@@ -203,6 +249,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#remove(java.util.List)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BulkOperations remove(List<Query> removes) {
|
public BulkOperations remove(List<Query> removes) {
|
||||||
|
|
||||||
@@ -215,6 +265,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#replaceOne(org.springframework.data.mongodb.core.query.Query, java.lang.Object, org.springframework.data.mongodb.core.FindAndReplaceOptions)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BulkOperations replaceOne(Query query, Object replacement, FindAndReplaceOptions options) {
|
public BulkOperations replaceOne(Query query, Object replacement, FindAndReplaceOptions options) {
|
||||||
|
|
||||||
@@ -234,6 +288,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.BulkOperations#executeBulk()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public com.mongodb.bulk.BulkWriteResult execute() {
|
public com.mongodb.bulk.BulkWriteResult execute() {
|
||||||
|
|
||||||
@@ -258,26 +316,11 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
collection = collection.withWriteConcern(defaultWriteConcern);
|
collection = collection.withWriteConcern(defaultWriteConcern);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
return collection.bulkWrite( //
|
return collection.bulkWrite( //
|
||||||
models.stream() //
|
models.stream() //
|
||||||
.map(this::extractAndMapWriteModel) //
|
.map(this::extractAndMapWriteModel) //
|
||||||
.collect(Collectors.toList()), //
|
.collect(Collectors.toList()), //
|
||||||
bulkOptions);
|
bulkOptions);
|
||||||
} catch (RuntimeException ex) {
|
|
||||||
|
|
||||||
if (ex instanceof MongoBulkWriteException) {
|
|
||||||
|
|
||||||
MongoBulkWriteException mongoBulkWriteException = (MongoBulkWriteException) ex;
|
|
||||||
if (mongoBulkWriteException.getWriteConcernError() != null) {
|
|
||||||
throw new DataIntegrityViolationException(ex.getMessage(), ex);
|
|
||||||
}
|
|
||||||
throw new BulkOperationException(ex.getMessage(), mongoBulkWriteException);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private WriteModel<Document> extractAndMapWriteModel(SourceAwareWriteModelHolder it) {
|
private WriteModel<Document> extractAndMapWriteModel(SourceAwareWriteModelHolder it) {
|
||||||
@@ -504,93 +547,15 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
static final class BulkOperationContext {
|
@Value
|
||||||
|
static class BulkOperationContext {
|
||||||
|
|
||||||
private final BulkMode bulkMode;
|
@NonNull BulkMode bulkMode;
|
||||||
private final Optional<? extends MongoPersistentEntity<?>> entity;
|
@NonNull Optional<? extends MongoPersistentEntity<?>> entity;
|
||||||
private final QueryMapper queryMapper;
|
@NonNull QueryMapper queryMapper;
|
||||||
private final UpdateMapper updateMapper;
|
@NonNull UpdateMapper updateMapper;
|
||||||
private final ApplicationEventPublisher eventPublisher;
|
ApplicationEventPublisher eventPublisher;
|
||||||
private final EntityCallbacks entityCallbacks;
|
EntityCallbacks entityCallbacks;
|
||||||
|
|
||||||
BulkOperationContext(BulkOperations.BulkMode bulkMode, Optional<? extends MongoPersistentEntity<?>> entity,
|
|
||||||
QueryMapper queryMapper, UpdateMapper updateMapper, ApplicationEventPublisher eventPublisher,
|
|
||||||
EntityCallbacks entityCallbacks) {
|
|
||||||
|
|
||||||
this.bulkMode = bulkMode;
|
|
||||||
this.entity = entity;
|
|
||||||
this.queryMapper = queryMapper;
|
|
||||||
this.updateMapper = updateMapper;
|
|
||||||
this.eventPublisher = eventPublisher;
|
|
||||||
this.entityCallbacks = entityCallbacks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BulkMode getBulkMode() {
|
|
||||||
return this.bulkMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<? extends MongoPersistentEntity<?>> getEntity() {
|
|
||||||
return this.entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public QueryMapper getQueryMapper() {
|
|
||||||
return this.queryMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UpdateMapper getUpdateMapper() {
|
|
||||||
return this.updateMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApplicationEventPublisher getEventPublisher() {
|
|
||||||
return this.eventPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityCallbacks getEntityCallbacks() {
|
|
||||||
return this.entityCallbacks;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (o == null || getClass() != o.getClass())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
BulkOperationContext that = (BulkOperationContext) o;
|
|
||||||
|
|
||||||
if (bulkMode != that.bulkMode)
|
|
||||||
return false;
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.entity, that.entity)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.queryMapper, that.queryMapper)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.updateMapper, that.updateMapper)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.eventPublisher, that.eventPublisher)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ObjectUtils.nullSafeEquals(this.entityCallbacks, that.entityCallbacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = bulkMode != null ? bulkMode.hashCode() : 0;
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(entity);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(queryMapper);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(updateMapper);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(eventPublisher);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(entityCallbacks);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "DefaultBulkOperations.BulkOperationContext(bulkMode=" + this.getBulkMode() + ", entity="
|
|
||||||
+ this.getEntity() + ", queryMapper=" + this.getQueryMapper() + ", updateMapper=" + this.getUpdateMapper()
|
|
||||||
+ ", eventPublisher=" + this.getEventPublisher() + ", entityCallbacks=" + this.getEntityCallbacks() + ")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -599,50 +564,10 @@ class DefaultBulkOperations implements BulkOperations {
|
|||||||
* @since 2.2
|
* @since 2.2
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
*/
|
*/
|
||||||
private static final class SourceAwareWriteModelHolder {
|
@Value
|
||||||
|
private static class SourceAwareWriteModelHolder {
|
||||||
|
|
||||||
private final Object source;
|
Object source;
|
||||||
private final WriteModel<Document> model;
|
WriteModel<Document> model;
|
||||||
|
|
||||||
SourceAwareWriteModelHolder(Object source, WriteModel<Document> model) {
|
|
||||||
|
|
||||||
this.source = source;
|
|
||||||
this.model = model;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getSource() {
|
|
||||||
return this.source;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WriteModel<Document> getModel() {
|
|
||||||
return this.model;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (o == null || getClass() != o.getClass())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SourceAwareWriteModelHolder that = (SourceAwareWriteModelHolder) o;
|
|
||||||
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.source, that.source)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ObjectUtils.nullSafeEquals(this.model, that.model);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = ObjectUtils.nullSafeHashCode(model);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(source);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "DefaultBulkOperations.SourceAwareWriteModelHolder(source=" + this.getSource() + ", model="
|
|
||||||
+ this.getModel() + ")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,10 @@ public class DefaultIndexOperations implements IndexOperations {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.index.IndexOperations#ensureIndex(org.springframework.data.mongodb.core.index.IndexDefinition)
|
||||||
|
*/
|
||||||
public String ensureIndex(final IndexDefinition indexDefinition) {
|
public String ensureIndex(final IndexDefinition indexDefinition) {
|
||||||
|
|
||||||
return execute(collection -> {
|
return execute(collection -> {
|
||||||
@@ -146,6 +150,10 @@ public class DefaultIndexOperations implements IndexOperations {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.index.IndexOperations#dropIndex(java.lang.String)
|
||||||
|
*/
|
||||||
public void dropIndex(final String name) {
|
public void dropIndex(final String name) {
|
||||||
|
|
||||||
execute(collection -> {
|
execute(collection -> {
|
||||||
@@ -155,10 +163,18 @@ public class DefaultIndexOperations implements IndexOperations {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.index.IndexOperations#dropAllIndexes()
|
||||||
|
*/
|
||||||
public void dropAllIndexes() {
|
public void dropAllIndexes() {
|
||||||
dropIndex("*");
|
dropIndex("*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.index.IndexOperations#getIndexInfo()
|
||||||
|
*/
|
||||||
public List<IndexInfo> getIndexInfo() {
|
public List<IndexInfo> getIndexInfo() {
|
||||||
|
|
||||||
return execute(new CollectionCallback<List<IndexInfo>>() {
|
return execute(new CollectionCallback<List<IndexInfo>>() {
|
||||||
|
|||||||
@@ -42,8 +42,12 @@ class DefaultIndexOperationsProvider implements IndexOperationsProvider {
|
|||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.index.IndexOperationsProvider#reactiveIndexOps(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public IndexOperations indexOps(String collectionName, Class<?> type) {
|
public IndexOperations indexOps(String collectionName) {
|
||||||
return new DefaultIndexOperations(mongoDbFactory, collectionName, mapper, type);
|
return new DefaultIndexOperations(mongoDbFactory, collectionName, mapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,10 @@ public class DefaultReactiveIndexOperations implements ReactiveIndexOperations {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.index.ReactiveIndexOperations#ensureIndex(org.springframework.data.mongodb.core.index.IndexDefinition)
|
||||||
|
*/
|
||||||
public Mono<String> ensureIndex(final IndexDefinition indexDefinition) {
|
public Mono<String> ensureIndex(final IndexDefinition indexDefinition) {
|
||||||
|
|
||||||
return mongoOperations.execute(collectionName, collection -> {
|
return mongoOperations.execute(collectionName, collection -> {
|
||||||
@@ -115,14 +119,26 @@ public class DefaultReactiveIndexOperations implements ReactiveIndexOperations {
|
|||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.index.ReactiveIndexOperations#dropIndex(java.lang.String)
|
||||||
|
*/
|
||||||
public Mono<Void> dropIndex(final String name) {
|
public Mono<Void> dropIndex(final String name) {
|
||||||
return mongoOperations.execute(collectionName, collection -> collection.dropIndex(name)).then();
|
return mongoOperations.execute(collectionName, collection -> collection.dropIndex(name)).then();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.index.ReactiveIndexOperations#dropAllIndexes()
|
||||||
|
*/
|
||||||
public Mono<Void> dropAllIndexes() {
|
public Mono<Void> dropAllIndexes() {
|
||||||
return dropIndex("*");
|
return dropIndex("*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.index.ReactiveIndexOperations#getIndexInfo()
|
||||||
|
*/
|
||||||
public Flux<IndexInfo> getIndexInfo() {
|
public Flux<IndexInfo> getIndexInfo() {
|
||||||
|
|
||||||
return mongoOperations.execute(collectionName, collection -> collection.listIndexes(Document.class)) //
|
return mongoOperations.execute(collectionName, collection -> collection.listIndexes(Document.class)) //
|
||||||
|
|||||||
@@ -70,11 +70,19 @@ class DefaultScriptOperations implements ScriptOperations {
|
|||||||
this.mongoOperations = mongoOperations;
|
this.mongoOperations = mongoOperations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ScriptOperations#register(org.springframework.data.mongodb.core.script.ExecutableMongoScript)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public NamedMongoScript register(ExecutableMongoScript script) {
|
public NamedMongoScript register(ExecutableMongoScript script) {
|
||||||
return register(new NamedMongoScript(generateScriptName(), script));
|
return register(new NamedMongoScript(generateScriptName(), script));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ScriptOperations#register(org.springframework.data.mongodb.core.script.NamedMongoScript)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public NamedMongoScript register(NamedMongoScript script) {
|
public NamedMongoScript register(NamedMongoScript script) {
|
||||||
|
|
||||||
@@ -84,6 +92,10 @@ class DefaultScriptOperations implements ScriptOperations {
|
|||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ScriptOperations#execute(org.springframework.data.mongodb.core.script.ExecutableMongoScript, java.lang.Object[])
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object execute(final ExecutableMongoScript script, final Object... args) {
|
public Object execute(final ExecutableMongoScript script, final Object... args) {
|
||||||
|
|
||||||
@@ -103,6 +115,10 @@ class DefaultScriptOperations implements ScriptOperations {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ScriptOperations#call(java.lang.String, java.lang.Object[])
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object call(final String scriptName, final Object... args) {
|
public Object call(final String scriptName, final Object... args) {
|
||||||
|
|
||||||
@@ -119,6 +135,10 @@ class DefaultScriptOperations implements ScriptOperations {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ScriptOperations#exists(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean exists(String scriptName) {
|
public boolean exists(String scriptName) {
|
||||||
|
|
||||||
@@ -127,6 +147,10 @@ class DefaultScriptOperations implements ScriptOperations {
|
|||||||
return mongoOperations.exists(query(where("_id").is(scriptName)), NamedMongoScript.class, SCRIPT_COLLECTION_NAME);
|
return mongoOperations.exists(query(where("_id").is(scriptName)), NamedMongoScript.class, SCRIPT_COLLECTION_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ScriptOperations#getScriptNames()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getScriptNames() {
|
public Set<String> getScriptNames() {
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021 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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encryption algorithms supported by MongoDB Client Side Field Level Encryption.
|
|
||||||
*
|
|
||||||
* @author Christoph Strobl
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
public final class EncryptionAlgorithms {
|
|
||||||
|
|
||||||
public static final String AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic = "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic";
|
|
||||||
public static final String AEAD_AES_256_CBC_HMAC_SHA_512_Random = "AEAD_AES_256_CBC_HMAC_SHA_512-Random";
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -15,42 +15,35 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
import org.springframework.data.convert.CustomConversions;
|
|
||||||
import org.springframework.data.mapping.IdentifierAccessor;
|
import org.springframework.data.mapping.IdentifierAccessor;
|
||||||
import org.springframework.data.mapping.MappingException;
|
import org.springframework.data.mapping.MappingException;
|
||||||
import org.springframework.data.mapping.PersistentEntity;
|
import org.springframework.data.mapping.PersistentEntity;
|
||||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
|
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
|
||||||
import org.springframework.data.mongodb.core.CollectionOptions.TimeSeriesOptions;
|
|
||||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
|
||||||
import org.springframework.data.mongodb.core.convert.MongoWriter;
|
import org.springframework.data.mongodb.core.convert.MongoWriter;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
|
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
|
||||||
import org.springframework.data.mongodb.core.mapping.TimeSeries;
|
|
||||||
import org.springframework.data.mongodb.core.query.Collation;
|
import org.springframework.data.mongodb.core.query.Collation;
|
||||||
import org.springframework.data.mongodb.core.query.Criteria;
|
import org.springframework.data.mongodb.core.query.Criteria;
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
import org.springframework.data.mongodb.core.timeseries.Granularity;
|
|
||||||
import org.springframework.data.projection.EntityProjection;
|
|
||||||
import org.springframework.data.projection.EntityProjectionIntrospector;
|
|
||||||
import org.springframework.data.projection.ProjectionFactory;
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.util.ObjectUtils;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common operations performed on an entity in the context of it's mapping metadata.
|
* Common operations performed on an entity in the context of it's mapping metadata.
|
||||||
@@ -62,26 +55,12 @@ import org.springframework.util.StringUtils;
|
|||||||
* @see MongoTemplate
|
* @see MongoTemplate
|
||||||
* @see ReactiveMongoTemplate
|
* @see ReactiveMongoTemplate
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class EntityOperations {
|
class EntityOperations {
|
||||||
|
|
||||||
private static final String ID_FIELD = "_id";
|
private static final String ID_FIELD = "_id";
|
||||||
|
|
||||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context;
|
private final @NonNull MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context;
|
||||||
|
|
||||||
private final EntityProjectionIntrospector introspector;
|
|
||||||
|
|
||||||
EntityOperations(MongoConverter converter) {
|
|
||||||
this(converter.getMappingContext(), converter.getCustomConversions(), converter.getProjectionFactory());
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityOperations(MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context,
|
|
||||||
CustomConversions conversions, ProjectionFactory projectionFactory) {
|
|
||||||
this.context = context;
|
|
||||||
this.introspector = EntityProjectionIntrospector.create(projectionFactory,
|
|
||||||
EntityProjectionIntrospector.ProjectionPredicate.typeHierarchy()
|
|
||||||
.and(((target, underlyingType) -> !conversions.isSimpleType(target))),
|
|
||||||
context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link Entity} for the given bean.
|
* Creates a new {@link Entity} for the given bean.
|
||||||
@@ -90,7 +69,7 @@ class EntityOperations {
|
|||||||
* @return new instance of {@link Entity}.
|
* @return new instance of {@link Entity}.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
<T> Entity<T> forEntity(T entity) {
|
public <T> Entity<T> forEntity(T entity) {
|
||||||
|
|
||||||
Assert.notNull(entity, "Bean must not be null!");
|
Assert.notNull(entity, "Bean must not be null!");
|
||||||
|
|
||||||
@@ -113,7 +92,7 @@ class EntityOperations {
|
|||||||
* @return new instance of {@link AdaptibleEntity}.
|
* @return new instance of {@link AdaptibleEntity}.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
<T> AdaptibleEntity<T> forEntity(T entity, ConversionService conversionService) {
|
public <T> AdaptibleEntity<T> forEntity(T entity, ConversionService conversionService) {
|
||||||
|
|
||||||
Assert.notNull(entity, "Bean must not be null!");
|
Assert.notNull(entity, "Bean must not be null!");
|
||||||
Assert.notNull(conversionService, "ConversionService must not be null!");
|
Assert.notNull(conversionService, "ConversionService must not be null!");
|
||||||
@@ -129,20 +108,6 @@ class EntityOperations {
|
|||||||
return AdaptibleMappedEntity.of(entity, context, conversionService);
|
return AdaptibleMappedEntity.of(entity, context, conversionService);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param source can be {@literal null}.
|
|
||||||
* @return {@literal true} if the given value is an {@literal array}, {@link Collection} or {@link Iterator}.
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
static boolean isCollectionLike(@Nullable Object source) {
|
|
||||||
|
|
||||||
if (source == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ObjectUtils.isArray(source) || source instanceof Collection || source instanceof Iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param entityClass should not be null.
|
* @param entityClass should not be null.
|
||||||
* @return the {@link MongoPersistentEntity#getCollection() collection name}.
|
* @return the {@link MongoPersistentEntity#getCollection() collection name}.
|
||||||
@@ -245,20 +210,6 @@ class EntityOperations {
|
|||||||
return UntypedOperations.instance();
|
return UntypedOperations.instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Introspect the given {@link Class result type} in the context of the {@link Class entity type} whether the returned
|
|
||||||
* type is a projection and what property paths are participating in the projection.
|
|
||||||
*
|
|
||||||
* @param resultType the type to project on. Must not be {@literal null}.
|
|
||||||
* @param entityType the source domain type. Must not be {@literal null}.
|
|
||||||
* @return the introspection result.
|
|
||||||
* @since 3.4
|
|
||||||
* @see EntityProjectionIntrospector#introspect(Class, Class)
|
|
||||||
*/
|
|
||||||
public <M, D> EntityProjection<M, D> introspectProjection(Class<M> resultType, Class<D> entityType) {
|
|
||||||
return introspector.introspect(resultType, entityType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of information about an entity.
|
* A representation of information about an entity.
|
||||||
*
|
*
|
||||||
@@ -395,29 +346,42 @@ class EntityOperations {
|
|||||||
Number getVersion();
|
Number getVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
private static class UnmappedEntity<T extends Map<String, Object>> implements AdaptibleEntity<T> {
|
private static class UnmappedEntity<T extends Map<String, Object>> implements AdaptibleEntity<T> {
|
||||||
|
|
||||||
private final T map;
|
private final T map;
|
||||||
|
|
||||||
protected UnmappedEntity(T map) {
|
/*
|
||||||
this.map = map;
|
* (non-Javadoc)
|
||||||
}
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getIdPropertyName()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getIdFieldName() {
|
public String getIdFieldName() {
|
||||||
return ID_FIELD;
|
return ID_FIELD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getId()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object getId() {
|
public Object getId() {
|
||||||
return map.get(ID_FIELD);
|
return map.get(ID_FIELD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getByIdQuery()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Query getByIdQuery() {
|
public Query getByIdQuery() {
|
||||||
return Query.query(Criteria.where(ID_FIELD).is(map.get(ID_FIELD)));
|
return Query.query(Criteria.where(ID_FIELD).is(map.get(ID_FIELD)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.MutablePersistableSource#populateIdIfNecessary(java.lang.Object)
|
||||||
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public T populateIdIfNecessary(@Nullable Object id) {
|
public T populateIdIfNecessary(@Nullable Object id) {
|
||||||
@@ -427,11 +391,19 @@ class EntityOperations {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getQueryForVersion()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Query getQueryForVersion() {
|
public Query getQueryForVersion() {
|
||||||
throw new MappingException("Cannot query for version on plain Documents!");
|
throw new MappingException("Cannot query for version on plain Documents!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#toMappedDocument(org.springframework.data.mongodb.core.convert.MongoWriter)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MappedDocument toMappedDocument(MongoWriter<? super T> writer) {
|
public MappedDocument toMappedDocument(MongoWriter<? super T> writer) {
|
||||||
return MappedDocument.of(map instanceof Document //
|
return MappedDocument.of(map instanceof Document //
|
||||||
@@ -439,27 +411,47 @@ class EntityOperations {
|
|||||||
: new Document(map));
|
: new Document(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.MutablePersistableSource#initializeVersionProperty()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public T initializeVersionProperty() {
|
public T initializeVersionProperty() {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.MutablePersistableSource#getVersion()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Number getVersion() {
|
public Number getVersion() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.MutablePersistableSource#incrementVersion()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public T incrementVersion() {
|
public T incrementVersion() {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getBean()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public T getBean() {
|
public T getBean() {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.Entity#isNew()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isNew() {
|
public boolean isNew() {
|
||||||
return map.get(ID_FIELD) != null;
|
return map.get(ID_FIELD) != null;
|
||||||
@@ -468,10 +460,14 @@ class EntityOperations {
|
|||||||
|
|
||||||
private static class SimpleMappedEntity<T extends Map<String, Object>> extends UnmappedEntity<T> {
|
private static class SimpleMappedEntity<T extends Map<String, Object>> extends UnmappedEntity<T> {
|
||||||
|
|
||||||
protected SimpleMappedEntity(T map) {
|
SimpleMappedEntity(T map) {
|
||||||
super(map);
|
super(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#toMappedDocument(org.springframework.data.mongodb.core.convert.MongoWriter)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public MappedDocument toMappedDocument(MongoWriter<? super T> writer) {
|
public MappedDocument toMappedDocument(MongoWriter<? super T> writer) {
|
||||||
@@ -487,19 +483,12 @@ class EntityOperations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
private static class MappedEntity<T> implements Entity<T> {
|
private static class MappedEntity<T> implements Entity<T> {
|
||||||
|
|
||||||
private final MongoPersistentEntity<?> entity;
|
private final @NonNull MongoPersistentEntity<?> entity;
|
||||||
private final IdentifierAccessor idAccessor;
|
private final @NonNull IdentifierAccessor idAccessor;
|
||||||
private final PersistentPropertyAccessor<T> propertyAccessor;
|
private final @NonNull PersistentPropertyAccessor<T> propertyAccessor;
|
||||||
|
|
||||||
protected MappedEntity(MongoPersistentEntity<?> entity, IdentifierAccessor idAccessor,
|
|
||||||
PersistentPropertyAccessor<T> propertyAccessor) {
|
|
||||||
|
|
||||||
this.entity = entity;
|
|
||||||
this.idAccessor = idAccessor;
|
|
||||||
this.propertyAccessor = propertyAccessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> MappedEntity<T> of(T bean,
|
private static <T> MappedEntity<T> of(T bean,
|
||||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) {
|
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) {
|
||||||
@@ -511,16 +500,28 @@ class EntityOperations {
|
|||||||
return new MappedEntity<>(entity, identifierAccessor, propertyAccessor);
|
return new MappedEntity<>(entity, identifierAccessor, propertyAccessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getIdPropertyName()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getIdFieldName() {
|
public String getIdFieldName() {
|
||||||
return entity.getRequiredIdProperty().getFieldName();
|
return entity.getRequiredIdProperty().getFieldName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getId()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object getId() {
|
public Object getId() {
|
||||||
return idAccessor.getRequiredIdentifier();
|
return idAccessor.getRequiredIdentifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getByIdQuery()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Query getByIdQuery() {
|
public Query getByIdQuery() {
|
||||||
|
|
||||||
@@ -533,6 +534,10 @@ class EntityOperations {
|
|||||||
return Query.query(Criteria.where(idProperty.getName()).is(getId()));
|
return Query.query(Criteria.where(idProperty.getName()).is(getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getQueryForVersion(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Query getQueryForVersion() {
|
public Query getQueryForVersion() {
|
||||||
|
|
||||||
@@ -543,6 +548,10 @@ class EntityOperations {
|
|||||||
.and(versionProperty.getName()).is(getVersion()));
|
.and(versionProperty.getName()).is(getVersion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#toMappedDocument(org.springframework.data.mongodb.core.convert.MongoWriter)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MappedDocument toMappedDocument(MongoWriter<? super T> writer) {
|
public MappedDocument toMappedDocument(MongoWriter<? super T> writer) {
|
||||||
|
|
||||||
@@ -558,6 +567,10 @@ class EntityOperations {
|
|||||||
return MappedDocument.of(document);
|
return MappedDocument.of(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.Entity#assertUpdateableIdIfNotSet()
|
||||||
|
*/
|
||||||
public void assertUpdateableIdIfNotSet() {
|
public void assertUpdateableIdIfNotSet() {
|
||||||
|
|
||||||
if (!entity.hasIdProperty()) {
|
if (!entity.hasIdProperty()) {
|
||||||
@@ -578,22 +591,38 @@ class EntityOperations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#isVersionedEntity()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isVersionedEntity() {
|
public boolean isVersionedEntity() {
|
||||||
return entity.hasVersionProperty();
|
return entity.hasVersionProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getVersion()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Object getVersion() {
|
public Object getVersion() {
|
||||||
return propertyAccessor.getProperty(entity.getRequiredVersionProperty());
|
return propertyAccessor.getProperty(entity.getRequiredVersionProperty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#getBean()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public T getBean() {
|
public T getBean() {
|
||||||
return propertyAccessor.getBean();
|
return propertyAccessor.getBean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.Entity#isNew()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isNew() {
|
public boolean isNew() {
|
||||||
return entity.isNew(propertyAccessor.getBean());
|
return entity.isNew(propertyAccessor.getBean());
|
||||||
@@ -628,6 +657,10 @@ class EntityOperations {
|
|||||||
new ConvertingPropertyAccessor<>(propertyAccessor, conversionService));
|
new ConvertingPropertyAccessor<>(propertyAccessor, conversionService));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.AdaptibleEntity#populateIdIfNecessary(java.lang.Object)
|
||||||
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public T populateIdIfNecessary(@Nullable Object id) {
|
public T populateIdIfNecessary(@Nullable Object id) {
|
||||||
@@ -649,6 +682,10 @@ class EntityOperations {
|
|||||||
return propertyAccessor.getBean();
|
return propertyAccessor.getBean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.MappedEntity#getVersion()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Number getVersion() {
|
public Number getVersion() {
|
||||||
@@ -658,6 +695,10 @@ class EntityOperations {
|
|||||||
return propertyAccessor.getProperty(versionProperty, Number.class);
|
return propertyAccessor.getProperty(versionProperty, Number.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.AdaptibleEntity#initializeVersionProperty()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public T initializeVersionProperty() {
|
public T initializeVersionProperty() {
|
||||||
|
|
||||||
@@ -672,6 +713,10 @@ class EntityOperations {
|
|||||||
return propertyAccessor.getBean();
|
return propertyAccessor.getBean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.AdaptibleEntity#incrementVersion()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public T incrementVersion() {
|
public T incrementVersion() {
|
||||||
|
|
||||||
@@ -708,46 +753,35 @@ class EntityOperations {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Optional<Collation> getCollation(Query query);
|
Optional<Collation> getCollation(Query query);
|
||||||
|
|
||||||
/**
|
|
||||||
* Derive the applicable {@link CollectionOptions} for the given type.
|
|
||||||
*
|
|
||||||
* @return never {@literal null}.
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
CollectionOptions getCollectionOptions();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map the fields of a given {@link TimeSeriesOptions} against the target domain type to consider potentially
|
|
||||||
* annotated field names.
|
|
||||||
*
|
|
||||||
* @param options must not be {@literal null}.
|
|
||||||
* @return never {@literal null}.
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
TimeSeriesOptions mapTimeSeriesOptions(TimeSeriesOptions options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link TypedOperations} for generic entities that are not represented with {@link PersistentEntity} (e.g. custom
|
* {@link TypedOperations} for generic entities that are not represented with {@link PersistentEntity} (e.g. custom
|
||||||
* conversions).
|
* conversions).
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
enum UntypedOperations implements TypedOperations<Object> {
|
enum UntypedOperations implements TypedOperations<Object> {
|
||||||
|
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
|
||||||
UntypedOperations() {}
|
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
public static <T> TypedOperations<T> instance() {
|
public static <T> TypedOperations<T> instance() {
|
||||||
return (TypedOperations) INSTANCE;
|
return (TypedOperations) INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.TypedOperations#getCollation()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Optional<Collation> getCollation() {
|
public Optional<Collation> getCollation() {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.TypedOperations#getCollation(org.springframework.data.mongodb.core.query.Query)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Optional<Collation> getCollation(Query query) {
|
public Optional<Collation> getCollation(Query query) {
|
||||||
|
|
||||||
@@ -757,16 +791,6 @@ class EntityOperations {
|
|||||||
|
|
||||||
return query.getCollation();
|
return query.getCollation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CollectionOptions getCollectionOptions() {
|
|
||||||
return CollectionOptions.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesOptions mapTimeSeriesOptions(TimeSeriesOptions options) {
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -774,19 +798,24 @@ class EntityOperations {
|
|||||||
*
|
*
|
||||||
* @param <T>
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
static class TypedEntityOperations<T> implements TypedOperations<T> {
|
static class TypedEntityOperations<T> implements TypedOperations<T> {
|
||||||
|
|
||||||
private final MongoPersistentEntity<T> entity;
|
private final @NonNull MongoPersistentEntity<T> entity;
|
||||||
|
|
||||||
protected TypedEntityOperations(MongoPersistentEntity<T> entity) {
|
|
||||||
this.entity = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.TypedOperations#getCollation()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Optional<Collation> getCollation() {
|
public Optional<Collation> getCollation() {
|
||||||
return Optional.ofNullable(entity.getCollation());
|
return Optional.ofNullable(entity.getCollation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.EntityOperations.TypedOperations#getCollation(org.springframework.data.mongodb.core.query.Query)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Optional<Collation> getCollation(Query query) {
|
public Optional<Collation> getCollation(Query query) {
|
||||||
|
|
||||||
@@ -796,58 +825,6 @@ class EntityOperations {
|
|||||||
|
|
||||||
return Optional.ofNullable(entity.getCollation());
|
return Optional.ofNullable(entity.getCollation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CollectionOptions getCollectionOptions() {
|
|
||||||
|
|
||||||
CollectionOptions collectionOptions = CollectionOptions.empty();
|
|
||||||
if (entity.hasCollation()) {
|
|
||||||
collectionOptions = collectionOptions.collation(entity.getCollation());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity.isAnnotationPresent(TimeSeries.class)) {
|
|
||||||
|
|
||||||
TimeSeries timeSeries = entity.getRequiredAnnotation(TimeSeries.class);
|
|
||||||
|
|
||||||
if (entity.getPersistentProperty(timeSeries.timeField()) == null) {
|
|
||||||
throw new MappingException(String.format("Time series field '%s' does not exist in type %s",
|
|
||||||
timeSeries.timeField(), entity.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeSeriesOptions options = TimeSeriesOptions.timeSeries(timeSeries.timeField());
|
|
||||||
if (StringUtils.hasText(timeSeries.metaField())) {
|
|
||||||
|
|
||||||
if (entity.getPersistentProperty(timeSeries.metaField()) == null) {
|
|
||||||
throw new MappingException(
|
|
||||||
String.format("Meta field '%s' does not exist in type %s", timeSeries.metaField(), entity.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
options = options.metaField(timeSeries.metaField());
|
|
||||||
}
|
|
||||||
if (!Granularity.DEFAULT.equals(timeSeries.granularity())) {
|
|
||||||
options = options.granularity(timeSeries.granularity());
|
|
||||||
}
|
|
||||||
collectionOptions = collectionOptions.timeSeries(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return collectionOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeSeriesOptions mapTimeSeriesOptions(TimeSeriesOptions source) {
|
|
||||||
|
|
||||||
TimeSeriesOptions target = TimeSeriesOptions.timeSeries(mappedNameOrDefault(source.getTimeField()));
|
|
||||||
|
|
||||||
if (StringUtils.hasText(source.getMetaField())) {
|
|
||||||
target = target.metaField(mappedNameOrDefault(source.getMetaField()));
|
|
||||||
}
|
|
||||||
return target.granularity(source.getGranularity());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String mappedNameOrDefault(String name) {
|
|
||||||
MongoPersistentProperty persistentProperty = entity.getPersistentProperty(name);
|
|
||||||
return persistentProperty != null ? persistentProperty.getFieldName() : name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||||
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
|
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
|
||||||
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
||||||
import org.springframework.data.util.CloseableIterator;
|
import org.springframework.data.util.CloseableIterator;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@@ -29,14 +35,15 @@ import org.springframework.util.StringUtils;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class ExecutableAggregationOperationSupport implements ExecutableAggregationOperation {
|
class ExecutableAggregationOperationSupport implements ExecutableAggregationOperation {
|
||||||
|
|
||||||
private final MongoTemplate template;
|
private final @NonNull MongoTemplate template;
|
||||||
|
|
||||||
ExecutableAggregationOperationSupport(MongoTemplate template) {
|
|
||||||
this.template = template;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableAggregationOperation#aggregateAndReturn(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T> ExecutableAggregation<T> aggregateAndReturn(Class<T> domainType) {
|
public <T> ExecutableAggregation<T> aggregateAndReturn(Class<T> domainType) {
|
||||||
|
|
||||||
@@ -49,22 +56,20 @@ class ExecutableAggregationOperationSupport implements ExecutableAggregationOper
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||||
static class ExecutableAggregationSupport<T>
|
static class ExecutableAggregationSupport<T>
|
||||||
implements AggregationWithAggregation<T>, ExecutableAggregation<T>, TerminatingAggregation<T> {
|
implements AggregationWithAggregation<T>, ExecutableAggregation<T>, TerminatingAggregation<T> {
|
||||||
|
|
||||||
private final MongoTemplate template;
|
@NonNull MongoTemplate template;
|
||||||
private final Class<T> domainType;
|
@NonNull Class<T> domainType;
|
||||||
private final Aggregation aggregation;
|
@Nullable Aggregation aggregation;
|
||||||
private final String collection;
|
@Nullable String collection;
|
||||||
|
|
||||||
public ExecutableAggregationSupport(MongoTemplate template, Class<T> domainType, Aggregation aggregation,
|
|
||||||
String collection) {
|
|
||||||
this.template = template;
|
|
||||||
this.domainType = domainType;
|
|
||||||
this.aggregation = aggregation;
|
|
||||||
this.collection = collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableAggregationOperation.AggregationWithCollection#inCollection(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AggregationWithAggregation<T> inCollection(String collection) {
|
public AggregationWithAggregation<T> inCollection(String collection) {
|
||||||
|
|
||||||
@@ -73,6 +78,10 @@ class ExecutableAggregationOperationSupport implements ExecutableAggregationOper
|
|||||||
return new ExecutableAggregationSupport<>(template, domainType, aggregation, collection);
|
return new ExecutableAggregationSupport<>(template, domainType, aggregation, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableAggregationOperation.AggregationWithAggregation#by(org.springframework.data.mongodb.core.aggregation.Aggregation)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingAggregation<T> by(Aggregation aggregation) {
|
public TerminatingAggregation<T> by(Aggregation aggregation) {
|
||||||
|
|
||||||
@@ -81,11 +90,19 @@ class ExecutableAggregationOperationSupport implements ExecutableAggregationOper
|
|||||||
return new ExecutableAggregationSupport<>(template, domainType, aggregation, collection);
|
return new ExecutableAggregationSupport<>(template, domainType, aggregation, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableAggregationOperation.TerminatingAggregation#all()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AggregationResults<T> all() {
|
public AggregationResults<T> all() {
|
||||||
return template.aggregate(aggregation, getCollectionName(aggregation), domainType);
|
return template.aggregate(aggregation, getCollectionName(aggregation), domainType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableAggregationOperation.TerminatingAggregation#stream()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CloseableIterator<T> stream() {
|
public CloseableIterator<T> stream() {
|
||||||
return template.aggregateStream(aggregation, getCollectionName(aggregation), domainType);
|
return template.aggregateStream(aggregation, getCollectionName(aggregation), domainType);
|
||||||
|
|||||||
@@ -125,11 +125,6 @@ public interface ExecutableFindOperation {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of matching elements.
|
* Get the number of matching elements.
|
||||||
* <br />
|
|
||||||
* This method uses an {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) aggregation
|
|
||||||
* execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees shard,
|
|
||||||
* session and transaction compliance. In case an inaccurate count satisfies the applications needs use
|
|
||||||
* {@link MongoOperations#estimatedCount(String)} for empty queries instead.
|
|
||||||
*
|
*
|
||||||
* @return total number of matching elements.
|
* @return total number of matching elements.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,6 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import com.mongodb.ReadPreference;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -31,7 +37,6 @@ import org.springframework.util.Assert;
|
|||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import com.mongodb.ReadPreference;
|
|
||||||
import com.mongodb.client.FindIterable;
|
import com.mongodb.client.FindIterable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,16 +46,17 @@ import com.mongodb.client.FindIterable;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
||||||
|
|
||||||
private static final Query ALL_QUERY = new Query();
|
private static final Query ALL_QUERY = new Query();
|
||||||
|
|
||||||
private final MongoTemplate template;
|
private final @NonNull MongoTemplate template;
|
||||||
|
|
||||||
ExecutableFindOperationSupport(MongoTemplate template) {
|
|
||||||
this.template = template;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation#query(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T> ExecutableFind<T> query(Class<T> domainType) {
|
public <T> ExecutableFind<T> query(Class<T> domainType) {
|
||||||
|
|
||||||
@@ -64,24 +70,21 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||||
static class ExecutableFindSupport<T>
|
static class ExecutableFindSupport<T>
|
||||||
implements ExecutableFind<T>, FindWithCollection<T>, FindWithProjection<T>, FindWithQuery<T> {
|
implements ExecutableFind<T>, FindWithCollection<T>, FindWithProjection<T>, FindWithQuery<T> {
|
||||||
|
|
||||||
private final MongoTemplate template;
|
@NonNull MongoTemplate template;
|
||||||
private final Class<?> domainType;
|
@NonNull Class<?> domainType;
|
||||||
private final Class<T> returnType;
|
Class<T> returnType;
|
||||||
@Nullable private final String collection;
|
@Nullable String collection;
|
||||||
private final Query query;
|
Query query;
|
||||||
|
|
||||||
ExecutableFindSupport(MongoTemplate template, Class<?> domainType, Class<T> returnType,
|
|
||||||
String collection, Query query) {
|
|
||||||
this.template = template;
|
|
||||||
this.domainType = domainType;
|
|
||||||
this.returnType = returnType;
|
|
||||||
this.collection = collection;
|
|
||||||
this.query = query;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.FindWithCollection#inCollection(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public FindWithProjection<T> inCollection(String collection) {
|
public FindWithProjection<T> inCollection(String collection) {
|
||||||
|
|
||||||
@@ -90,6 +93,10 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
|||||||
return new ExecutableFindSupport<>(template, domainType, returnType, collection, query);
|
return new ExecutableFindSupport<>(template, domainType, returnType, collection, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.FindWithProjection#as(Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T1> FindWithQuery<T1> as(Class<T1> returnType) {
|
public <T1> FindWithQuery<T1> as(Class<T1> returnType) {
|
||||||
|
|
||||||
@@ -98,6 +105,10 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
|||||||
return new ExecutableFindSupport<>(template, domainType, returnType, collection, query);
|
return new ExecutableFindSupport<>(template, domainType, returnType, collection, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.FindWithQuery#matching(org.springframework.data.mongodb.core.query.Query)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingFind<T> matching(Query query) {
|
public TerminatingFind<T> matching(Query query) {
|
||||||
|
|
||||||
@@ -106,6 +117,10 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
|||||||
return new ExecutableFindSupport<>(template, domainType, returnType, collection, query);
|
return new ExecutableFindSupport<>(template, domainType, returnType, collection, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.TerminatingFind#oneValue()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public T oneValue() {
|
public T oneValue() {
|
||||||
|
|
||||||
@@ -122,6 +137,10 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
|||||||
return result.iterator().next();
|
return result.iterator().next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.TerminatingFind#firstValue()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public T firstValue() {
|
public T firstValue() {
|
||||||
|
|
||||||
@@ -130,31 +149,55 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
|||||||
return ObjectUtils.isEmpty(result) ? null : result.iterator().next();
|
return ObjectUtils.isEmpty(result) ? null : result.iterator().next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.TerminatingFind#all()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<T> all() {
|
public List<T> all() {
|
||||||
return doFind(null);
|
return doFind(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.TerminatingFind#stream()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Stream<T> stream() {
|
public Stream<T> stream() {
|
||||||
return StreamUtils.createStreamFromIterator(doStream());
|
return StreamUtils.createStreamFromIterator(doStream());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.FindWithQuery#near(org.springframework.data.mongodb.core.query.NearQuery)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingFindNear<T> near(NearQuery nearQuery) {
|
public TerminatingFindNear<T> near(NearQuery nearQuery) {
|
||||||
return () -> template.geoNear(nearQuery, domainType, getCollectionName(), returnType);
|
return () -> template.geoNear(nearQuery, domainType, getCollectionName(), returnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.TerminatingFind#count()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public long count() {
|
public long count() {
|
||||||
return template.count(query, domainType, getCollectionName());
|
return template.count(query, domainType, getCollectionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.TerminatingFind#exists()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean exists() {
|
public boolean exists() {
|
||||||
return template.exists(query, domainType, getCollectionName());
|
return template.exists(query, domainType, getCollectionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.FindDistinct#distinct(java.lang.String)
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public TerminatingDistinct<Object> distinct(String field) {
|
public TerminatingDistinct<Object> distinct(String field) {
|
||||||
@@ -209,6 +252,10 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
|||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.CursorPreparer#prepare(com.mongodb.clientFindIterable)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public FindIterable<Document> prepare(FindIterable<Document> iterable) {
|
public FindIterable<Document> prepare(FindIterable<Document> iterable) {
|
||||||
|
|
||||||
@@ -243,6 +290,10 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
|||||||
this.field = field;
|
this.field = field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.DistinctWithProjection#as(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <R> TerminatingDistinct<R> as(Class<R> resultType) {
|
public <R> TerminatingDistinct<R> as(Class<R> resultType) {
|
||||||
@@ -252,6 +303,10 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
|||||||
return new DistinctOperationSupport<>((ExecutableFindSupport) delegate.as(resultType), field);
|
return new DistinctOperationSupport<>((ExecutableFindSupport) delegate.as(resultType), field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.DistinctWithQuery#matching(org.springframework.data.mongodb.core.query.Query)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingDistinct<T> matching(Query query) {
|
public TerminatingDistinct<T> matching(Query query) {
|
||||||
|
|
||||||
@@ -260,6 +315,10 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
|||||||
return new DistinctOperationSupport<>((ExecutableFindSupport<T>) delegate.matching(query), field);
|
return new DistinctOperationSupport<>((ExecutableFindSupport<T>) delegate.matching(query), field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.TerminatingDistinct#all()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<T> all() {
|
public List<T> all() {
|
||||||
return delegate.doFindDistinct(field);
|
return delegate.doFindDistinct(field);
|
||||||
|
|||||||
@@ -15,6 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@@ -32,14 +37,15 @@ import com.mongodb.bulk.BulkWriteResult;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
||||||
|
|
||||||
private final MongoTemplate template;
|
private final @NonNull MongoTemplate template;
|
||||||
|
|
||||||
ExecutableInsertOperationSupport(MongoTemplate template) {
|
|
||||||
this.template = template;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.coreExecutableInsertOperation#insert(java.lan.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T> ExecutableInsert<T> insert(Class<T> domainType) {
|
public <T> ExecutableInsert<T> insert(Class<T> domainType) {
|
||||||
|
|
||||||
@@ -52,21 +58,19 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||||
static class ExecutableInsertSupport<T> implements ExecutableInsert<T> {
|
static class ExecutableInsertSupport<T> implements ExecutableInsert<T> {
|
||||||
|
|
||||||
private final MongoTemplate template;
|
@NonNull MongoTemplate template;
|
||||||
private final Class<T> domainType;
|
@NonNull Class<T> domainType;
|
||||||
@Nullable private final String collection;
|
@Nullable String collection;
|
||||||
@Nullable private final BulkMode bulkMode;
|
@Nullable BulkMode bulkMode;
|
||||||
|
|
||||||
ExecutableInsertSupport(MongoTemplate template, Class<T> domainType, String collection, BulkMode bulkMode) {
|
|
||||||
|
|
||||||
this.template = template;
|
|
||||||
this.domainType = domainType;
|
|
||||||
this.collection = collection;
|
|
||||||
this.bulkMode = bulkMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation.TerminatingInsert#insert(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public T one(T object) {
|
public T one(T object) {
|
||||||
|
|
||||||
@@ -75,6 +79,10 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
|||||||
return template.insert(object, getCollectionName());
|
return template.insert(object, getCollectionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation.TerminatingInsert#all(java.util.Collection)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Collection<T> all(Collection<? extends T> objects) {
|
public Collection<T> all(Collection<? extends T> objects) {
|
||||||
|
|
||||||
@@ -83,6 +91,10 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
|||||||
return template.insert(objects, getCollectionName());
|
return template.insert(objects, getCollectionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation.TerminatingBulkInsert#bulk(java.util.Collection)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public BulkWriteResult bulk(Collection<? extends T> objects) {
|
public BulkWriteResult bulk(Collection<? extends T> objects) {
|
||||||
|
|
||||||
@@ -92,6 +104,10 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
|||||||
.insert(new ArrayList<>(objects)).execute();
|
.insert(new ArrayList<>(objects)).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation.InsertWithCollection#inCollection(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public InsertWithBulkMode<T> inCollection(String collection) {
|
public InsertWithBulkMode<T> inCollection(String collection) {
|
||||||
|
|
||||||
@@ -100,6 +116,10 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
|
|||||||
return new ExecutableInsertSupport<>(template, domainType, collection, bulkMode);
|
return new ExecutableInsertSupport<>(template, domainType, collection, bulkMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation.InsertWithBulkMode#withBulkMode(org.springframework.data.mongodb.core.BulkMode)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingBulkInsert<T> withBulkMode(BulkMode bulkMode) {
|
public TerminatingBulkInsert<T> withBulkMode(BulkMode bulkMode) {
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
|
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
|
||||||
@@ -29,17 +32,12 @@ import org.springframework.util.StringUtils;
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperation {
|
class ExecutableMapReduceOperationSupport implements ExecutableMapReduceOperation {
|
||||||
|
|
||||||
private static final Query ALL_QUERY = new Query();
|
private static final Query ALL_QUERY = new Query();
|
||||||
|
|
||||||
private final MongoTemplate template;
|
private final @NonNull MongoTemplate template;
|
||||||
|
|
||||||
ExecutableMapReduceOperationSupport(MongoTemplate template) {
|
|
||||||
|
|
||||||
Assert.notNull(template, "Template must not be null!");
|
|
||||||
this.template = template;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javascript)
|
* (non-Javascript)
|
||||||
|
|||||||
@@ -15,6 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
@@ -31,16 +36,17 @@ import com.mongodb.client.result.DeleteResult;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation {
|
class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation {
|
||||||
|
|
||||||
private static final Query ALL_QUERY = new Query();
|
private static final Query ALL_QUERY = new Query();
|
||||||
|
|
||||||
private final MongoTemplate tempate;
|
private final @NonNull MongoTemplate tempate;
|
||||||
|
|
||||||
public ExecutableRemoveOperationSupport(MongoTemplate tempate) {
|
|
||||||
this.tempate = tempate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableRemoveOperation#remove(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T> ExecutableRemove<T> remove(Class<T> domainType) {
|
public <T> ExecutableRemove<T> remove(Class<T> domainType) {
|
||||||
|
|
||||||
@@ -53,20 +59,19 @@ class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation {
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||||
static class ExecutableRemoveSupport<T> implements ExecutableRemove<T>, RemoveWithCollection<T> {
|
static class ExecutableRemoveSupport<T> implements ExecutableRemove<T>, RemoveWithCollection<T> {
|
||||||
|
|
||||||
private final MongoTemplate template;
|
@NonNull MongoTemplate template;
|
||||||
private final Class<T> domainType;
|
@NonNull Class<T> domainType;
|
||||||
private final Query query;
|
Query query;
|
||||||
@Nullable private final String collection;
|
@Nullable String collection;
|
||||||
|
|
||||||
public ExecutableRemoveSupport(MongoTemplate template, Class<T> domainType, Query query, String collection) {
|
|
||||||
this.template = template;
|
|
||||||
this.domainType = domainType;
|
|
||||||
this.query = query;
|
|
||||||
this.collection = collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableRemoveOperation.RemoveWithCollection#inCollection(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public RemoveWithQuery<T> inCollection(String collection) {
|
public RemoveWithQuery<T> inCollection(String collection) {
|
||||||
|
|
||||||
@@ -75,6 +80,10 @@ class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation {
|
|||||||
return new ExecutableRemoveSupport<>(template, domainType, query, collection);
|
return new ExecutableRemoveSupport<>(template, domainType, query, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableRemoveOperation.RemoveWithQuery#matching(org.springframework.data.mongodb.core.query.Query)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingRemove<T> matching(Query query) {
|
public TerminatingRemove<T> matching(Query query) {
|
||||||
|
|
||||||
@@ -83,16 +92,28 @@ class ExecutableRemoveOperationSupport implements ExecutableRemoveOperation {
|
|||||||
return new ExecutableRemoveSupport<>(template, domainType, query, collection);
|
return new ExecutableRemoveSupport<>(template, domainType, query, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableRemoveOperation.TerminatingRemove#all()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DeleteResult all() {
|
public DeleteResult all() {
|
||||||
return template.doRemove(getCollectionName(), query, domainType, true);
|
return template.doRemove(getCollectionName(), query, domainType, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableRemoveOperation.TerminatingRemove#one()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DeleteResult one() {
|
public DeleteResult one() {
|
||||||
return template.doRemove(getCollectionName(), query, domainType, false);
|
return template.doRemove(getCollectionName(), query, domainType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableRemoveOperation.TerminatingRemove#findAndRemove()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<T> findAndRemove() {
|
public List<T> findAndRemove() {
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public interface ExecutableUpdateOperation {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger
|
* Trigger
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* execution by calling one of the terminating methods.
|
* execution by calling one of the terminating methods.
|
||||||
*
|
*
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
|
|||||||
@@ -15,6 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
@@ -30,16 +35,17 @@ import com.mongodb.client.result.UpdateResult;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
||||||
|
|
||||||
private static final Query ALL_QUERY = new Query();
|
private static final Query ALL_QUERY = new Query();
|
||||||
|
|
||||||
private final MongoTemplate template;
|
private final @NonNull MongoTemplate template;
|
||||||
|
|
||||||
ExecutableUpdateOperationSupport(MongoTemplate template) {
|
|
||||||
this.template = template;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation#update(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T> ExecutableUpdate<T> update(Class<T> domainType) {
|
public <T> ExecutableUpdate<T> update(Class<T> domainType) {
|
||||||
|
|
||||||
@@ -52,35 +58,26 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||||
static class ExecutableUpdateSupport<T>
|
static class ExecutableUpdateSupport<T>
|
||||||
implements ExecutableUpdate<T>, UpdateWithCollection<T>, UpdateWithQuery<T>, TerminatingUpdate<T>,
|
implements ExecutableUpdate<T>, UpdateWithCollection<T>, UpdateWithQuery<T>, TerminatingUpdate<T>,
|
||||||
FindAndReplaceWithOptions<T>, TerminatingFindAndReplace<T>, FindAndReplaceWithProjection<T> {
|
FindAndReplaceWithOptions<T>, TerminatingFindAndReplace<T>, FindAndReplaceWithProjection<T> {
|
||||||
|
|
||||||
private final MongoTemplate template;
|
@NonNull MongoTemplate template;
|
||||||
private final Class domainType;
|
@NonNull Class domainType;
|
||||||
private final Query query;
|
Query query;
|
||||||
@Nullable private final UpdateDefinition update;
|
@Nullable UpdateDefinition update;
|
||||||
@Nullable private final String collection;
|
@Nullable String collection;
|
||||||
@Nullable private final FindAndModifyOptions findAndModifyOptions;
|
@Nullable FindAndModifyOptions findAndModifyOptions;
|
||||||
@Nullable private final FindAndReplaceOptions findAndReplaceOptions;
|
@Nullable FindAndReplaceOptions findAndReplaceOptions;
|
||||||
@Nullable private final Object replacement;
|
@Nullable Object replacement;
|
||||||
private final Class<T> targetType;
|
@NonNull Class<T> targetType;
|
||||||
|
|
||||||
ExecutableUpdateSupport(MongoTemplate template, Class domainType, Query query, UpdateDefinition update,
|
|
||||||
String collection, FindAndModifyOptions findAndModifyOptions, FindAndReplaceOptions findAndReplaceOptions,
|
|
||||||
Object replacement, Class<T> targetType) {
|
|
||||||
|
|
||||||
this.template = template;
|
|
||||||
this.domainType = domainType;
|
|
||||||
this.query = query;
|
|
||||||
this.update = update;
|
|
||||||
this.collection = collection;
|
|
||||||
this.findAndModifyOptions = findAndModifyOptions;
|
|
||||||
this.findAndReplaceOptions = findAndReplaceOptions;
|
|
||||||
this.replacement = replacement;
|
|
||||||
this.targetType = targetType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.UpdateWithUpdate#apply(org.springframework.data.mongodb.core.query.UpdateDefinition)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingUpdate<T> apply(UpdateDefinition update) {
|
public TerminatingUpdate<T> apply(UpdateDefinition update) {
|
||||||
|
|
||||||
@@ -90,6 +87,10 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
|||||||
findAndReplaceOptions, replacement, targetType);
|
findAndReplaceOptions, replacement, targetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.UpdateWithCollection#inCollection(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public UpdateWithQuery<T> inCollection(String collection) {
|
public UpdateWithQuery<T> inCollection(String collection) {
|
||||||
|
|
||||||
@@ -99,6 +100,10 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
|||||||
findAndReplaceOptions, replacement, targetType);
|
findAndReplaceOptions, replacement, targetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.FindAndModifyWithOptions#withOptions(org.springframework.data.mongodb.core.FindAndModifyOptions)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingFindAndModify<T> withOptions(FindAndModifyOptions options) {
|
public TerminatingFindAndModify<T> withOptions(FindAndModifyOptions options) {
|
||||||
|
|
||||||
@@ -108,6 +113,10 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
|||||||
findAndReplaceOptions, replacement, targetType);
|
findAndReplaceOptions, replacement, targetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.UpdateWithUpdate#replaceWith(Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public FindAndReplaceWithProjection<T> replaceWith(T replacement) {
|
public FindAndReplaceWithProjection<T> replaceWith(T replacement) {
|
||||||
|
|
||||||
@@ -117,6 +126,10 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
|||||||
findAndReplaceOptions, replacement, targetType);
|
findAndReplaceOptions, replacement, targetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.FindAndReplaceWithOptions#withOptions(org.springframework.data.mongodb.core.FindAndReplaceOptions)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public FindAndReplaceWithProjection<T> withOptions(FindAndReplaceOptions options) {
|
public FindAndReplaceWithProjection<T> withOptions(FindAndReplaceOptions options) {
|
||||||
|
|
||||||
@@ -126,6 +139,10 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
|||||||
options, replacement, targetType);
|
options, replacement, targetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveUpdateOperation.UpdateWithQuery#matching(org.springframework.data.mongodb.core.query.Query)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public UpdateWithUpdate<T> matching(Query query) {
|
public UpdateWithUpdate<T> matching(Query query) {
|
||||||
|
|
||||||
@@ -135,6 +152,10 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
|||||||
findAndReplaceOptions, replacement, targetType);
|
findAndReplaceOptions, replacement, targetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveUpdateOperation.FindAndReplaceWithProjection#as(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <R> FindAndReplaceWithOptions<R> as(Class<R> resultType) {
|
public <R> FindAndReplaceWithOptions<R> as(Class<R> resultType) {
|
||||||
|
|
||||||
@@ -144,21 +165,37 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
|||||||
findAndReplaceOptions, replacement, resultType);
|
findAndReplaceOptions, replacement, resultType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.TerminatingUpdate#all()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public UpdateResult all() {
|
public UpdateResult all() {
|
||||||
return doUpdate(true, false);
|
return doUpdate(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.TerminatingUpdate#first()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public UpdateResult first() {
|
public UpdateResult first() {
|
||||||
return doUpdate(false, false);
|
return doUpdate(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.TerminatingUpdate#upsert()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public UpdateResult upsert() {
|
public UpdateResult upsert() {
|
||||||
return doUpdate(true, true);
|
return doUpdate(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.TerminatingFindAndModify#findAndModifyValue()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public @Nullable T findAndModifyValue() {
|
public @Nullable T findAndModifyValue() {
|
||||||
|
|
||||||
@@ -167,6 +204,10 @@ class ExecutableUpdateOperationSupport implements ExecutableUpdateOperation {
|
|||||||
getCollectionName());
|
getCollectionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ExecutableUpdateOperation.TerminatingFindAndReplace#findAndReplaceValue()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public @Nullable T findAndReplaceValue() {
|
public @Nullable T findAndReplaceValue() {
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ package org.springframework.data.mongodb.core;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Options for
|
* Options for
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>.
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>.
|
||||||
* <br />
|
* <br />
|
||||||
* Defaults to
|
* Defaults to
|
||||||
* <dl>
|
* <dl>
|
||||||
|
|||||||
@@ -115,10 +115,6 @@ abstract class IndexConverters {
|
|||||||
ops = ops.collation(fromDocument(indexOptions.get("collation", Document.class)));
|
ops = ops.collation(fromDocument(indexOptions.get("collation", Document.class)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indexOptions.containsKey("wildcardProjection")) {
|
|
||||||
ops.wildcardProjection(indexOptions.get("wildcardProjection", Document.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ops;
|
return ops;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -24,6 +27,8 @@ import org.springframework.data.mongodb.core.query.Update;
|
|||||||
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
||||||
import org.springframework.data.util.StreamUtils;
|
import org.springframework.data.util.StreamUtils;
|
||||||
|
|
||||||
|
import com.mongodb.client.model.Filters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A MongoDB document in its mapped state. I.e. after a source document has been mapped using mapping information of the
|
* A MongoDB document in its mapped state. I.e. after a source document has been mapped using mapping information of the
|
||||||
* entity the source document was supposed to represent.
|
* entity the source document was supposed to represent.
|
||||||
@@ -31,20 +36,13 @@ import org.springframework.data.util.StreamUtils;
|
|||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor(staticName = "of")
|
||||||
public class MappedDocument {
|
public class MappedDocument {
|
||||||
|
|
||||||
private static final String ID_FIELD = "_id";
|
private static final String ID_FIELD = "_id";
|
||||||
private static final Document ID_ONLY_PROJECTION = new Document(ID_FIELD, 1);
|
private static final Document ID_ONLY_PROJECTION = new Document(ID_FIELD, 1);
|
||||||
|
|
||||||
private final Document document;
|
private final @Getter Document document;
|
||||||
|
|
||||||
private MappedDocument(Document document) {
|
|
||||||
this.document = document;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MappedDocument of(Document document) {
|
|
||||||
return new MappedDocument(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Document getIdOnlyProjection() {
|
public static Document getIdOnlyProjection() {
|
||||||
return ID_ONLY_PROJECTION;
|
return ID_ONLY_PROJECTION;
|
||||||
@@ -93,10 +91,6 @@ public class MappedDocument {
|
|||||||
return new MappedUpdate(Update.fromDocument(document, ID_FIELD));
|
return new MappedUpdate(Update.fromDocument(document, ID_FIELD));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Document getDocument() {
|
|
||||||
return this.document;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link UpdateDefinition} that indicates that the {@link #getUpdateObject() update object} has already been
|
* An {@link UpdateDefinition} that indicates that the {@link #getUpdateObject() update object} has already been
|
||||||
* mapped to the specific domain type.
|
* mapped to the specific domain type.
|
||||||
@@ -112,34 +106,49 @@ public class MappedDocument {
|
|||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#getUpdateObject()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Document getUpdateObject() {
|
public Document getUpdateObject() {
|
||||||
return delegate.getUpdateObject();
|
return delegate.getUpdateObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#modifies(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean modifies(String key) {
|
public boolean modifies(String key) {
|
||||||
return delegate.modifies(key);
|
return delegate.modifies(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#inc(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void inc(String version) {
|
public void inc(String version) {
|
||||||
delegate.inc(version);
|
delegate.inc(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#isIsolated()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean isIsolated() {
|
public Boolean isIsolated() {
|
||||||
return delegate.isIsolated();
|
return delegate.isIsolated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#getArrayFilters()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<ArrayFilter> getArrayFilters() {
|
public List<ArrayFilter> getArrayFilters() {
|
||||||
return delegate.getArrayFilters();
|
return delegate.getArrayFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasArrayFilters() {
|
|
||||||
return delegate.hasArrayFilters();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,20 +20,13 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import org.springframework.data.mapping.PersistentProperty;
|
import org.springframework.data.mapping.PersistentProperty;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||||
import org.springframework.data.mongodb.core.mapping.Encrypted;
|
|
||||||
import org.springframework.data.mongodb.core.mapping.Field;
|
import org.springframework.data.mongodb.core.mapping.Field;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ArrayJsonSchemaProperty;
|
|
||||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty;
|
|
||||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ObjectJsonSchemaProperty;
|
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ObjectJsonSchemaProperty;
|
||||||
import org.springframework.data.mongodb.core.schema.JsonSchemaObject;
|
import org.springframework.data.mongodb.core.schema.JsonSchemaObject;
|
||||||
import org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type;
|
import org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type;
|
||||||
@@ -41,12 +34,10 @@ import org.springframework.data.mongodb.core.schema.JsonSchemaProperty;
|
|||||||
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
|
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
|
||||||
import org.springframework.data.mongodb.core.schema.MongoJsonSchema.MongoJsonSchemaBuilder;
|
import org.springframework.data.mongodb.core.schema.MongoJsonSchema.MongoJsonSchemaBuilder;
|
||||||
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject;
|
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject;
|
||||||
import org.springframework.data.util.ClassTypeInformation;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link MongoJsonSchemaCreator} implementation using both {@link MongoConverter} and {@link MappingContext} to obtain
|
* {@link MongoJsonSchemaCreator} implementation using both {@link MongoConverter} and {@link MappingContext} to obtain
|
||||||
@@ -61,7 +52,6 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
|||||||
|
|
||||||
private final MongoConverter converter;
|
private final MongoConverter converter;
|
||||||
private final MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
private final MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||||
private final Predicate<JsonSchemaPropertyContext> filter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of {@link MappingMongoJsonSchemaCreator}.
|
* Create a new instance of {@link MappingMongoJsonSchemaCreator}.
|
||||||
@@ -71,55 +61,27 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
MappingMongoJsonSchemaCreator(MongoConverter converter) {
|
MappingMongoJsonSchemaCreator(MongoConverter converter) {
|
||||||
|
|
||||||
this(converter, (MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty>) converter.getMappingContext(),
|
|
||||||
(property) -> true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
MappingMongoJsonSchemaCreator(MongoConverter converter,
|
|
||||||
MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext,
|
|
||||||
Predicate<JsonSchemaPropertyContext> filter) {
|
|
||||||
|
|
||||||
Assert.notNull(converter, "Converter must not be null!");
|
Assert.notNull(converter, "Converter must not be null!");
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
this.mappingContext = mappingContext;
|
this.mappingContext = (MappingContext<MongoPersistentEntity<?>, MongoPersistentProperty>) converter
|
||||||
this.filter = filter;
|
.getMappingContext();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MongoJsonSchemaCreator filter(Predicate<JsonSchemaPropertyContext> filter) {
|
|
||||||
return new MappingMongoJsonSchemaCreator(converter, mappingContext, filter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* org.springframework.data.mongodb.core.MongoJsonSchemaCreator#createSchemaFor(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MongoJsonSchema createSchemaFor(Class<?> type) {
|
public MongoJsonSchema createSchemaFor(Class<?> type) {
|
||||||
|
|
||||||
MongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(type);
|
MongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(type);
|
||||||
MongoJsonSchemaBuilder schemaBuilder = MongoJsonSchema.builder();
|
MongoJsonSchemaBuilder schemaBuilder = MongoJsonSchema.builder();
|
||||||
|
|
||||||
{
|
|
||||||
Encrypted encrypted = entity.findAnnotation(Encrypted.class);
|
|
||||||
if (encrypted != null) {
|
|
||||||
|
|
||||||
Document encryptionMetadata = new Document();
|
|
||||||
|
|
||||||
Collection<Object> encryptionKeyIds = entity.getEncryptionKeyIds();
|
|
||||||
if (!CollectionUtils.isEmpty(encryptionKeyIds)) {
|
|
||||||
encryptionMetadata.append("keyId", encryptionKeyIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.hasText(encrypted.algorithm())) {
|
|
||||||
encryptionMetadata.append("algorithm", encrypted.algorithm());
|
|
||||||
}
|
|
||||||
|
|
||||||
schemaBuilder.encryptionMetadata(encryptionMetadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<JsonSchemaProperty> schemaProperties = computePropertiesForEntity(Collections.emptyList(), entity);
|
List<JsonSchemaProperty> schemaProperties = computePropertiesForEntity(Collections.emptyList(), entity);
|
||||||
schemaBuilder.properties(schemaProperties.toArray(new JsonSchemaProperty[0]));
|
schemaBuilder.properties(schemaProperties.toArray(new JsonSchemaProperty[0]));
|
||||||
|
|
||||||
return schemaBuilder.build();
|
return schemaBuilder.build();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<JsonSchemaProperty> computePropertiesForEntity(List<MongoPersistentProperty> path,
|
private List<JsonSchemaProperty> computePropertiesForEntity(List<MongoPersistentProperty> path,
|
||||||
@@ -131,11 +93,6 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
|||||||
|
|
||||||
List<MongoPersistentProperty> currentPath = new ArrayList<>(path);
|
List<MongoPersistentProperty> currentPath = new ArrayList<>(path);
|
||||||
|
|
||||||
if (!filter.test(new PropertyContext(
|
|
||||||
currentPath.stream().map(PersistentProperty::getName).collect(Collectors.joining(".")), nested))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.contains(nested)) { // cycle guard
|
if (path.contains(nested)) { // cycle guard
|
||||||
schemaProperties.add(createSchemaProperty(computePropertyFieldName(CollectionUtils.lastElement(currentPath)),
|
schemaProperties.add(createSchemaProperty(computePropertyFieldName(CollectionUtils.lastElement(currentPath)),
|
||||||
Object.class, false));
|
Object.class, false));
|
||||||
@@ -157,88 +114,21 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
|||||||
Class<?> rawTargetType = computeTargetType(property); // target type before conversion
|
Class<?> rawTargetType = computeTargetType(property); // target type before conversion
|
||||||
Class<?> targetType = converter.getTypeMapper().getWriteTargetTypeFor(rawTargetType); // conversion target type
|
Class<?> targetType = converter.getTypeMapper().getWriteTargetTypeFor(rawTargetType); // conversion target type
|
||||||
|
|
||||||
if (!isCollection(property) && property.isEntity() && ObjectUtils.nullSafeEquals(rawTargetType, targetType)) {
|
if (property.isEntity() && ObjectUtils.nullSafeEquals(rawTargetType, targetType)) {
|
||||||
return createObjectSchemaPropertyForEntity(path, property, required);
|
return createObjectSchemaPropertyForEntity(path, property, required);
|
||||||
}
|
}
|
||||||
|
|
||||||
String fieldName = computePropertyFieldName(property);
|
String fieldName = computePropertyFieldName(property);
|
||||||
|
|
||||||
JsonSchemaProperty schemaProperty;
|
if (property.isCollectionLike()) {
|
||||||
if (isCollection(property)) {
|
return createSchemaProperty(fieldName, targetType, required);
|
||||||
schemaProperty = createArraySchemaProperty(fieldName, property, required);
|
|
||||||
} else if (property.isMap()) {
|
} else if (property.isMap()) {
|
||||||
schemaProperty = createSchemaProperty(fieldName, Type.objectType(), required);
|
return createSchemaProperty(fieldName, Type.objectType(), required);
|
||||||
} else if (ClassUtils.isAssignable(Enum.class, targetType)) {
|
} else if (ClassUtils.isAssignable(Enum.class, targetType)) {
|
||||||
schemaProperty = createEnumSchemaProperty(fieldName, targetType, required);
|
return createEnumSchemaProperty(fieldName, targetType, required);
|
||||||
} else {
|
|
||||||
schemaProperty = createSchemaProperty(fieldName, targetType, required);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return applyEncryptionDataIfNecessary(property, schemaProperty);
|
return createSchemaProperty(fieldName, targetType, required);
|
||||||
}
|
|
||||||
|
|
||||||
private JsonSchemaProperty createArraySchemaProperty(String fieldName, MongoPersistentProperty property,
|
|
||||||
boolean required) {
|
|
||||||
|
|
||||||
ArrayJsonSchemaProperty schemaProperty = JsonSchemaProperty.array(fieldName);
|
|
||||||
|
|
||||||
if (isSpecificType(property)) {
|
|
||||||
schemaProperty = potentiallyEnhanceArraySchemaProperty(property, schemaProperty);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createPotentiallyRequiredSchemaProperty(schemaProperty, required);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
|
||||||
private ArrayJsonSchemaProperty potentiallyEnhanceArraySchemaProperty(MongoPersistentProperty property,
|
|
||||||
ArrayJsonSchemaProperty schemaProperty) {
|
|
||||||
|
|
||||||
MongoPersistentEntity<?> persistentEntity = mappingContext
|
|
||||||
.getPersistentEntity(property.getTypeInformation().getRequiredComponentType());
|
|
||||||
|
|
||||||
if (persistentEntity != null) {
|
|
||||||
|
|
||||||
List<JsonSchemaProperty> nestedProperties = computePropertiesForEntity(Collections.emptyList(), persistentEntity);
|
|
||||||
|
|
||||||
if (nestedProperties.isEmpty()) {
|
|
||||||
return schemaProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
return schemaProperty
|
|
||||||
.items(JsonSchemaObject.object().properties(nestedProperties.toArray(new JsonSchemaProperty[0])));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ClassUtils.isAssignable(Enum.class, property.getActualType())) {
|
|
||||||
|
|
||||||
List<Object> possibleValues = getPossibleEnumValues((Class<Enum>) property.getActualType());
|
|
||||||
|
|
||||||
return schemaProperty
|
|
||||||
.items(createSchemaObject(computeTargetType(property.getActualType(), possibleValues), possibleValues));
|
|
||||||
}
|
|
||||||
|
|
||||||
return schemaProperty.items(JsonSchemaObject.of(property.getActualType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSpecificType(MongoPersistentProperty property) {
|
|
||||||
return !ClassTypeInformation.OBJECT.equals(property.getTypeInformation().getActualType());
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsonSchemaProperty applyEncryptionDataIfNecessary(MongoPersistentProperty property,
|
|
||||||
JsonSchemaProperty schemaProperty) {
|
|
||||||
|
|
||||||
Encrypted encrypted = property.findAnnotation(Encrypted.class);
|
|
||||||
if (encrypted == null) {
|
|
||||||
return schemaProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
EncryptedJsonSchemaProperty enc = new EncryptedJsonSchemaProperty(schemaProperty);
|
|
||||||
if (StringUtils.hasText(encrypted.algorithm())) {
|
|
||||||
enc = enc.algorithm(encrypted.algorithm());
|
|
||||||
}
|
|
||||||
if (!ObjectUtils.isEmpty(encrypted.keyId())) {
|
|
||||||
enc = enc.keys(property.getEncryptionKeyIds());
|
|
||||||
}
|
|
||||||
return enc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonSchemaProperty createObjectSchemaPropertyForEntity(List<MongoPersistentProperty> path,
|
private JsonSchemaProperty createObjectSchemaPropertyForEntity(List<MongoPersistentProperty> path,
|
||||||
@@ -252,12 +142,15 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
|||||||
target.properties(nestedProperties.toArray(new JsonSchemaProperty[0])), required);
|
target.properties(nestedProperties.toArray(new JsonSchemaProperty[0])), required);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
|
||||||
private JsonSchemaProperty createEnumSchemaProperty(String fieldName, Class<?> targetType, boolean required) {
|
private JsonSchemaProperty createEnumSchemaProperty(String fieldName, Class<?> targetType, boolean required) {
|
||||||
|
|
||||||
List<Object> possibleValues = getPossibleEnumValues((Class<Enum>) targetType);
|
List<Object> possibleValues = new ArrayList<>();
|
||||||
|
|
||||||
targetType = computeTargetType(targetType, possibleValues);
|
for (Object enumValue : EnumSet.allOf((Class) targetType)) {
|
||||||
|
possibleValues.add(converter.convertToMongoType(enumValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
targetType = possibleValues.isEmpty() ? targetType : possibleValues.iterator().next().getClass();
|
||||||
return createSchemaProperty(fieldName, targetType, required, possibleValues);
|
return createSchemaProperty(fieldName, targetType, required, possibleValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,20 +161,14 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
|||||||
JsonSchemaProperty createSchemaProperty(String fieldName, Object type, boolean required,
|
JsonSchemaProperty createSchemaProperty(String fieldName, Object type, boolean required,
|
||||||
Collection<?> possibleValues) {
|
Collection<?> possibleValues) {
|
||||||
|
|
||||||
TypedJsonSchemaObject schemaObject = createSchemaObject(type, possibleValues);
|
|
||||||
|
|
||||||
return createPotentiallyRequiredSchemaProperty(JsonSchemaProperty.named(fieldName).with(schemaObject), required);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TypedJsonSchemaObject createSchemaObject(Object type, Collection<?> possibleValues) {
|
|
||||||
|
|
||||||
TypedJsonSchemaObject schemaObject = type instanceof Type ? JsonSchemaObject.of(Type.class.cast(type))
|
TypedJsonSchemaObject schemaObject = type instanceof Type ? JsonSchemaObject.of(Type.class.cast(type))
|
||||||
: JsonSchemaObject.of(Class.class.cast(type));
|
: JsonSchemaObject.of(Class.class.cast(type));
|
||||||
|
|
||||||
if (!CollectionUtils.isEmpty(possibleValues)) {
|
if (!CollectionUtils.isEmpty(possibleValues)) {
|
||||||
schemaObject = schemaObject.possibleValues(possibleValues);
|
schemaObject = schemaObject.possibleValues(possibleValues);
|
||||||
}
|
}
|
||||||
return schemaObject;
|
|
||||||
|
return createPotentiallyRequiredSchemaProperty(JsonSchemaProperty.named(fieldName).with(schemaObject), required);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String computePropertyFieldName(PersistentProperty property) {
|
private String computePropertyFieldName(PersistentProperty property) {
|
||||||
@@ -312,53 +199,12 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
|||||||
return mongoProperty.getFieldType() != mongoProperty.getActualType() ? Object.class : mongoProperty.getFieldType();
|
return mongoProperty.getFieldType() != mongoProperty.getActualType() ? Object.class : mongoProperty.getFieldType();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Class<?> computeTargetType(Class<?> fallback, List<Object> possibleValues) {
|
|
||||||
return possibleValues.isEmpty() ? fallback : possibleValues.iterator().next().getClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
private <E extends Enum<E>> List<Object> getPossibleEnumValues(Class<E> targetType) {
|
|
||||||
|
|
||||||
EnumSet<E> enumSet = EnumSet.allOf(targetType);
|
|
||||||
List<Object> possibleValues = new ArrayList<>(enumSet.size());
|
|
||||||
|
|
||||||
for (Object enumValue : enumSet) {
|
|
||||||
possibleValues.add(converter.convertToMongoType(enumValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
return possibleValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isCollection(MongoPersistentProperty property) {
|
|
||||||
return property.isCollectionLike() && !property.getType().equals(byte[].class);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JsonSchemaProperty createPotentiallyRequiredSchemaProperty(JsonSchemaProperty property, boolean required) {
|
static JsonSchemaProperty createPotentiallyRequiredSchemaProperty(JsonSchemaProperty property, boolean required) {
|
||||||
return required ? JsonSchemaProperty.required(property) : property;
|
|
||||||
}
|
|
||||||
|
|
||||||
class PropertyContext implements JsonSchemaPropertyContext {
|
if (!required) {
|
||||||
|
|
||||||
private final String path;
|
|
||||||
private final MongoPersistentProperty property;
|
|
||||||
|
|
||||||
public PropertyContext(String path, MongoPersistentProperty property) {
|
|
||||||
this.path = path;
|
|
||||||
this.property = property;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPath() {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MongoPersistentProperty getProperty() {
|
|
||||||
return property;
|
return property;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
return JsonSchemaProperty.required(property);
|
||||||
public <T> MongoPersistentEntity<T> resolveEntity(MongoPersistentProperty property) {
|
|
||||||
return (MongoPersistentEntity<T>) mappingContext.getPersistentEntity(property);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,16 +46,25 @@ public class MongoAdmin implements MongoAdminOperations {
|
|||||||
this.mongoClient = client;
|
this.mongoClient = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.core.MongoAdminOperations#dropDatabase(java.lang.String)
|
||||||
|
*/
|
||||||
@ManagedOperation
|
@ManagedOperation
|
||||||
public void dropDatabase(String databaseName) {
|
public void dropDatabase(String databaseName) {
|
||||||
getDB(databaseName).drop();
|
getDB(databaseName).drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.core.MongoAdminOperations#createDatabase(java.lang.String)
|
||||||
|
*/
|
||||||
@ManagedOperation
|
@ManagedOperation
|
||||||
public void createDatabase(String databaseName) {
|
public void createDatabase(String databaseName) {
|
||||||
getDB(databaseName);
|
getDB(databaseName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.core.MongoAdminOperations#getDatabaseStats(java.lang.String)
|
||||||
|
*/
|
||||||
@ManagedOperation
|
@ManagedOperation
|
||||||
public String getDatabaseStats(String databaseName) {
|
public String getDatabaseStats(String databaseName) {
|
||||||
return getDB(databaseName).runCommand(new Document("dbStats", 1).append("scale", 1024)).toJson();
|
return getDB(databaseName).runCommand(new Document("dbStats", 1).append("scale", 1024)).toJson();
|
||||||
|
|||||||
@@ -119,15 +119,27 @@ public class MongoClientFactoryBean extends AbstractFactoryBean<MongoClient> imp
|
|||||||
this.exceptionTranslator = exceptionTranslator == null ? DEFAULT_EXCEPTION_TRANSLATOR : exceptionTranslator;
|
this.exceptionTranslator = exceptionTranslator == null ? DEFAULT_EXCEPTION_TRANSLATOR : exceptionTranslator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
|
||||||
|
*/
|
||||||
public Class<? extends MongoClient> getObjectType() {
|
public Class<? extends MongoClient> getObjectType() {
|
||||||
return MongoClient.class;
|
return MongoClient.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
|
||||||
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||||
return exceptionTranslator.translateExceptionIfPossible(ex);
|
return exceptionTranslator.translateExceptionIfPossible(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected MongoClient createInstance() throws Exception {
|
protected MongoClient createInstance() throws Exception {
|
||||||
return createMongoClient(computeClientSetting());
|
return createMongoClient(computeClientSetting());
|
||||||
@@ -324,6 +336,10 @@ public class MongoClientFactoryBean extends AbstractFactoryBean<MongoClient> imp
|
|||||||
return !fromConnectionStringIsDefault ? fromConnectionString : defaultValue;
|
return !fromConnectionStringIsDefault ? fromConnectionString : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.config.AbstractFactoryBean#destroyInstance(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void destroyInstance(@Nullable MongoClient instance) throws Exception {
|
protected void destroyInstance(@Nullable MongoClient instance) throws Exception {
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import com.mongodb.MongoClientSettings.Builder;
|
|||||||
import com.mongodb.ReadConcern;
|
import com.mongodb.ReadConcern;
|
||||||
import com.mongodb.ReadPreference;
|
import com.mongodb.ReadPreference;
|
||||||
import com.mongodb.ServerAddress;
|
import com.mongodb.ServerAddress;
|
||||||
import com.mongodb.ServerApi;
|
|
||||||
import com.mongodb.WriteConcern;
|
import com.mongodb.WriteConcern;
|
||||||
import com.mongodb.connection.ClusterConnectionMode;
|
import com.mongodb.connection.ClusterConnectionMode;
|
||||||
import com.mongodb.connection.ClusterType;
|
import com.mongodb.connection.ClusterType;
|
||||||
@@ -114,7 +113,6 @@ public class MongoClientSettingsFactoryBean extends AbstractFactoryBean<MongoCli
|
|||||||
// encryption and retry
|
// encryption and retry
|
||||||
|
|
||||||
private @Nullable AutoEncryptionSettings autoEncryptionSettings;
|
private @Nullable AutoEncryptionSettings autoEncryptionSettings;
|
||||||
private @Nullable ServerApi serverApi;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param socketConnectTimeoutMS in msec
|
* @param socketConnectTimeoutMS in msec
|
||||||
@@ -397,15 +395,6 @@ public class MongoClientSettingsFactoryBean extends AbstractFactoryBean<MongoCli
|
|||||||
this.autoEncryptionSettings = autoEncryptionSettings;
|
this.autoEncryptionSettings = autoEncryptionSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param serverApi can be {@literal null}.
|
|
||||||
* @see MongoClientSettings.Builder#serverApi(ServerApi)
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
public void setServerApi(@Nullable ServerApi serverApi) {
|
|
||||||
this.serverApi = serverApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getObjectType() {
|
public Class<?> getObjectType() {
|
||||||
return MongoClientSettings.class;
|
return MongoClientSettings.class;
|
||||||
@@ -487,11 +476,9 @@ public class MongoClientSettingsFactoryBean extends AbstractFactoryBean<MongoCli
|
|||||||
if (retryWrites != null) {
|
if (retryWrites != null) {
|
||||||
builder = builder.retryWrites(retryWrites);
|
builder = builder.retryWrites(retryWrites);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uUidRepresentation != null) {
|
if (uUidRepresentation != null) {
|
||||||
builder = builder.uuidRepresentation(uUidRepresentation);
|
builder.uuidRepresentation(uUidRepresentation);
|
||||||
}
|
|
||||||
if (serverApi != null) {
|
|
||||||
builder = builder.serverApi(serverApi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
import org.springframework.aop.framework.ProxyFactory;
|
import org.springframework.aop.framework.ProxyFactory;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||||
@@ -22,7 +24,6 @@ import org.springframework.data.mongodb.MongoDatabaseFactory;
|
|||||||
import org.springframework.data.mongodb.SessionAwareMethodInterceptor;
|
import org.springframework.data.mongodb.SessionAwareMethodInterceptor;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
|
||||||
|
|
||||||
import com.mongodb.ClientSessionOptions;
|
import com.mongodb.ClientSessionOptions;
|
||||||
import com.mongodb.WriteConcern;
|
import com.mongodb.WriteConcern;
|
||||||
@@ -33,7 +34,7 @@ import com.mongodb.client.MongoDatabase;
|
|||||||
/**
|
/**
|
||||||
* Common base class for usage with both {@link com.mongodb.client.MongoClients} defining common properties such as
|
* Common base class for usage with both {@link com.mongodb.client.MongoClients} defining common properties such as
|
||||||
* database name and exception translator.
|
* database name and exception translator.
|
||||||
* <br />
|
* <p/>
|
||||||
* Not intended to be used directly.
|
* Not intended to be used directly.
|
||||||
*
|
*
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
@@ -84,10 +85,18 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
|
|||||||
this.writeConcern = writeConcern;
|
this.writeConcern = writeConcern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.MongoDbFactory#getMongoDatabase()
|
||||||
|
*/
|
||||||
public MongoDatabase getMongoDatabase() throws DataAccessException {
|
public MongoDatabase getMongoDatabase() throws DataAccessException {
|
||||||
return getMongoDatabase(getDefaultDatabaseName());
|
return getMongoDatabase(getDefaultDatabaseName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.MongoDbFactory#getMongoDatabase(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MongoDatabase getMongoDatabase(String dbName) throws DataAccessException {
|
public MongoDatabase getMongoDatabase(String dbName) throws DataAccessException {
|
||||||
|
|
||||||
@@ -110,16 +119,28 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
|
|||||||
*/
|
*/
|
||||||
protected abstract MongoDatabase doGetMongoDatabase(String dbName);
|
protected abstract MongoDatabase doGetMongoDatabase(String dbName);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||||
|
*/
|
||||||
public void destroy() throws Exception {
|
public void destroy() throws Exception {
|
||||||
if (mongoInstanceCreated) {
|
if (mongoInstanceCreated) {
|
||||||
closeClient();
|
closeClient();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.MongoDbFactory#getExceptionTranslator()
|
||||||
|
*/
|
||||||
public PersistenceExceptionTranslator getExceptionTranslator() {
|
public PersistenceExceptionTranslator getExceptionTranslator() {
|
||||||
return this.exceptionTranslator;
|
return this.exceptionTranslator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.MongoDbFactory#withSession(com.mongodb.session.Session)
|
||||||
|
*/
|
||||||
public MongoDatabaseFactory withSession(ClientSession session) {
|
public MongoDatabaseFactory withSession(ClientSession session) {
|
||||||
return new MongoDatabaseFactorySupport.ClientSessionBoundMongoDbFactory(session, this);
|
return new MongoDatabaseFactorySupport.ClientSessionBoundMongoDbFactory(session, this);
|
||||||
}
|
}
|
||||||
@@ -150,41 +171,61 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
static final class ClientSessionBoundMongoDbFactory implements MongoDatabaseFactory {
|
@Value
|
||||||
|
static class ClientSessionBoundMongoDbFactory implements MongoDatabaseFactory {
|
||||||
|
|
||||||
private final ClientSession session;
|
ClientSession session;
|
||||||
private final MongoDatabaseFactory delegate;
|
MongoDatabaseFactory delegate;
|
||||||
|
|
||||||
public ClientSessionBoundMongoDbFactory(ClientSession session, MongoDatabaseFactory delegate) {
|
|
||||||
this.session = session;
|
|
||||||
this.delegate = delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.MongoDbFactory#getMongoDatabase()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MongoDatabase getMongoDatabase() throws DataAccessException {
|
public MongoDatabase getMongoDatabase() throws DataAccessException {
|
||||||
return proxyMongoDatabase(delegate.getMongoDatabase());
|
return proxyMongoDatabase(delegate.getMongoDatabase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.MongoDbFactory#getMongoDatabase(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MongoDatabase getMongoDatabase(String dbName) throws DataAccessException {
|
public MongoDatabase getMongoDatabase(String dbName) throws DataAccessException {
|
||||||
return proxyMongoDatabase(delegate.getMongoDatabase(dbName));
|
return proxyMongoDatabase(delegate.getMongoDatabase(dbName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.MongoDbFactory#getExceptionTranslator()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public PersistenceExceptionTranslator getExceptionTranslator() {
|
public PersistenceExceptionTranslator getExceptionTranslator() {
|
||||||
return delegate.getExceptionTranslator();
|
return delegate.getExceptionTranslator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.MongoDbFactory#getSession(com.mongodb.ClientSessionOptions)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ClientSession getSession(ClientSessionOptions options) {
|
public ClientSession getSession(ClientSessionOptions options) {
|
||||||
return delegate.getSession(options);
|
return delegate.getSession(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.MongoDbFactory#withSession(com.mongodb.session.ClientSession)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MongoDatabaseFactory withSession(ClientSession session) {
|
public MongoDatabaseFactory withSession(ClientSession session) {
|
||||||
return delegate.withSession(session);
|
return delegate.withSession(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.MongoDbFactory#isTransactionActive()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isTransactionActive() {
|
public boolean isTransactionActive() {
|
||||||
return session != null && session.hasActiveTransaction();
|
return session != null && session.hasActiveTransaction();
|
||||||
@@ -215,40 +256,5 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
|
|||||||
|
|
||||||
return targetType.cast(factory.getProxy(target.getClass().getClassLoader()));
|
return targetType.cast(factory.getProxy(target.getClass().getClassLoader()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientSession getSession() {
|
|
||||||
return this.session;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoDatabaseFactory getDelegate() {
|
|
||||||
return this.delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (o == null || getClass() != o.getClass())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ClientSessionBoundMongoDbFactory that = (ClientSessionBoundMongoDbFactory) o;
|
|
||||||
|
|
||||||
if (!ObjectUtils.nullSafeEquals(this.session, that.session)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ObjectUtils.nullSafeEquals(this.delegate, that.delegate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = ObjectUtils.nullSafeHashCode(this.session);
|
|
||||||
result = 31 * result + ObjectUtils.nullSafeHashCode(this.delegate);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "MongoDatabaseFactorySupport.ClientSessionBoundMongoDbFactory(session=" + this.getSession() + ", delegate="
|
|
||||||
+ this.getDelegate() + ")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import org.springframework.dao.support.PersistenceExceptionTranslator;
|
|||||||
/**
|
/**
|
||||||
* Common base class for usage with both {@link com.mongodb.client.MongoClients} defining common properties such as
|
* Common base class for usage with both {@link com.mongodb.client.MongoClients} defining common properties such as
|
||||||
* database name and exception translator.
|
* database name and exception translator.
|
||||||
* <br />
|
* <p/>
|
||||||
* Not intended to be used directly.
|
* Not intended to be used directly.
|
||||||
*
|
*
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
|
|||||||
@@ -88,6 +88,10 @@ public class MongoEncryptionSettingsFactoryBean implements FactoryBean<AutoEncry
|
|||||||
this.schemaMap = schemaMap;
|
this.schemaMap = schemaMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AutoEncryptionSettings getObject() {
|
public AutoEncryptionSettings getObject() {
|
||||||
|
|
||||||
@@ -105,6 +109,10 @@ public class MongoEncryptionSettingsFactoryBean implements FactoryBean<AutoEncry
|
|||||||
return source != null ? source : Collections.emptyMap();
|
return source != null ? source : Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getObjectType() {
|
public Class<?> getObjectType() {
|
||||||
return AutoEncryptionSettings.class;
|
return AutoEncryptionSettings.class;
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
|
|||||||
private static final Set<String> DATA_INTEGRITY_EXCEPTIONS = new HashSet<>(
|
private static final Set<String> DATA_INTEGRITY_EXCEPTIONS = new HashSet<>(
|
||||||
Arrays.asList("WriteConcernException", "MongoWriteException", "MongoBulkWriteException"));
|
Arrays.asList("WriteConcernException", "MongoWriteException", "MongoBulkWriteException"));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
|
||||||
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||||
|
|
||||||
|
|||||||
@@ -15,23 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.springframework.data.mapping.PersistentProperty;
|
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
|
||||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
|
||||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
|
|
||||||
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
|
|
||||||
import org.springframework.data.mongodb.core.mapping.Encrypted;
|
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
|
|
||||||
import org.springframework.data.mongodb.core.mapping.Unwrapped.Nullable;
|
|
||||||
import org.springframework.data.mongodb.core.schema.JsonSchemaProperty;
|
|
||||||
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
|
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@@ -40,7 +24,6 @@ import org.springframework.util.Assert;
|
|||||||
* following mapping rules.
|
* following mapping rules.
|
||||||
* <p>
|
* <p>
|
||||||
* <strong>Required Properties</strong>
|
* <strong>Required Properties</strong>
|
||||||
* </p>
|
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Properties of primitive type</li>
|
* <li>Properties of primitive type</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
@@ -62,8 +45,7 @@ import org.springframework.util.Assert;
|
|||||||
* {@link org.springframework.data.annotation.Id _id} properties using types that can be converted into
|
* {@link org.springframework.data.annotation.Id _id} properties using types that can be converted into
|
||||||
* {@link org.bson.types.ObjectId} like {@link String} will be mapped to {@code type : 'object'} unless there is more
|
* {@link org.bson.types.ObjectId} like {@link String} will be mapped to {@code type : 'object'} unless there is more
|
||||||
* specific information available via the {@link org.springframework.data.mongodb.core.mapping.MongoId} annotation.
|
* specific information available via the {@link org.springframework.data.mongodb.core.mapping.MongoId} annotation.
|
||||||
|
* </p>
|
||||||
* {@link Encrypted} properties will contain {@literal encrypt} information.
|
|
||||||
*
|
*
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.2
|
* @since 2.2
|
||||||
@@ -78,88 +60,6 @@ public interface MongoJsonSchemaCreator {
|
|||||||
*/
|
*/
|
||||||
MongoJsonSchema createSchemaFor(Class<?> type);
|
MongoJsonSchema createSchemaFor(Class<?> type);
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter matching {@link JsonSchemaProperty properties}.
|
|
||||||
*
|
|
||||||
* @param filter the {@link Predicate} to evaluate for inclusion. Must not be {@literal null}.
|
|
||||||
* @return new instance of {@link MongoJsonSchemaCreator}.
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
MongoJsonSchemaCreator filter(Predicate<JsonSchemaPropertyContext> filter);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The context in which a specific {@link #getProperty()} is encountered during schema creation.
|
|
||||||
*
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
interface JsonSchemaPropertyContext {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The path to a given field/property in dot notation.
|
|
||||||
*
|
|
||||||
* @return never {@literal null}.
|
|
||||||
*/
|
|
||||||
String getPath();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current property.
|
|
||||||
*
|
|
||||||
* @return never {@literal null}.
|
|
||||||
*/
|
|
||||||
MongoPersistentProperty getProperty();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain the {@link MongoPersistentEntity} for a given property.
|
|
||||||
*
|
|
||||||
* @param property must not be {@literal null}.
|
|
||||||
* @param <T>
|
|
||||||
* @return {@literal null} if the property is not an entity. It is nevertheless recommend to check
|
|
||||||
* {@link PersistentProperty#isEntity()} first.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
<T> MongoPersistentEntity<T> resolveEntity(MongoPersistentProperty property);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A filter {@link Predicate} that matches {@link Encrypted encrypted properties} and those having nested ones.
|
|
||||||
*
|
|
||||||
* @return new instance of {@link Predicate}.
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
static Predicate<JsonSchemaPropertyContext> encryptedOnly() {
|
|
||||||
|
|
||||||
return new Predicate<JsonSchemaPropertyContext>() {
|
|
||||||
|
|
||||||
// cycle guard
|
|
||||||
private final Set<MongoPersistentProperty> seen = new HashSet<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean test(JsonSchemaPropertyContext context) {
|
|
||||||
return extracted(context.getProperty(), context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean extracted(MongoPersistentProperty property, JsonSchemaPropertyContext context) {
|
|
||||||
if (property.isAnnotationPresent(Encrypted.class)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!property.isEntity() || seen.contains(property)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
seen.add(property);
|
|
||||||
|
|
||||||
for (MongoPersistentProperty nested : context.resolveEntity(property)) {
|
|
||||||
if (extracted(nested, context)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link MongoJsonSchemaCreator} that is aware of conversions applied by the given
|
* Creates a new {@link MongoJsonSchemaCreator} that is aware of conversions applied by the given
|
||||||
* {@link MongoConverter}.
|
* {@link MongoConverter}.
|
||||||
@@ -172,41 +72,4 @@ public interface MongoJsonSchemaCreator {
|
|||||||
Assert.notNull(mongoConverter, "MongoConverter must not be null!");
|
Assert.notNull(mongoConverter, "MongoConverter must not be null!");
|
||||||
return new MappingMongoJsonSchemaCreator(mongoConverter);
|
return new MappingMongoJsonSchemaCreator(mongoConverter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link MongoJsonSchemaCreator} that is aware of type mappings and potential
|
|
||||||
* {@link org.springframework.data.spel.spi.EvaluationContextExtension extensions}.
|
|
||||||
*
|
|
||||||
* @param mappingContext must not be {@literal null}.
|
|
||||||
* @return new instance of {@link MongoJsonSchemaCreator}.
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
static MongoJsonSchemaCreator create(MappingContext mappingContext) {
|
|
||||||
|
|
||||||
MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
|
|
||||||
converter.setCustomConversions(MongoCustomConversions.create(config -> {}));
|
|
||||||
converter.afterPropertiesSet();
|
|
||||||
|
|
||||||
return create(converter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link MongoJsonSchemaCreator} that does not consider potential extensions - suitable for testing. We
|
|
||||||
* recommend to use {@link #create(MappingContext)}.
|
|
||||||
*
|
|
||||||
* @return new instance of {@link MongoJsonSchemaCreator}.
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
static MongoJsonSchemaCreator create() {
|
|
||||||
|
|
||||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
|
||||||
mappingContext.setSimpleTypeHolder(MongoSimpleTypes.HOLDER);
|
|
||||||
mappingContext.afterPropertiesSet();
|
|
||||||
|
|
||||||
MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
|
|
||||||
converter.setCustomConversions(MongoCustomConversions.create(config -> {}));
|
|
||||||
converter.afterPropertiesSet();
|
|
||||||
|
|
||||||
return create(converter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ import com.mongodb.client.result.UpdateResult;
|
|||||||
* Interface that specifies a basic set of MongoDB operations. Implemented by {@link MongoTemplate}. Not often used but
|
* Interface that specifies a basic set of MongoDB operations. Implemented by {@link MongoTemplate}. Not often used but
|
||||||
* a useful option for extensibility and testability (as it can be easily mocked, stubbed, or be the target of a JDK
|
* a useful option for extensibility and testability (as it can be easily mocked, stubbed, or be the target of a JDK
|
||||||
* proxy).
|
* proxy).
|
||||||
* <br />
|
* <p/>
|
||||||
* <strong>NOTE:</strong> Some operations cannot be executed within a MongoDB transaction. Please refer to the MongoDB
|
* <strong>NOTE:</strong> Some operations cannot be executed within a MongoDB transaction. Please refer to the MongoDB
|
||||||
* specific documentation to learn more about <a href="https://docs.mongodb.com/manual/core/transactions/">Multi
|
* specific documentation to learn more about <a href="https://docs.mongodb.com/manual/core/transactions/">Multi
|
||||||
* Document Transactions</a>.
|
* Document Transactions</a>.
|
||||||
@@ -125,7 +125,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a {@link DbCallback} translating any exceptions as necessary.
|
* Executes a {@link DbCallback} translating any exceptions as necessary.
|
||||||
* <br />
|
* <p/>
|
||||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||||
*
|
*
|
||||||
* @param action callback object that specifies the MongoDB actions to perform on the passed in DB instance. Must not
|
* @param action callback object that specifies the MongoDB actions to perform on the passed in DB instance. Must not
|
||||||
@@ -138,7 +138,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the given {@link CollectionCallback} on the entity collection of the specified class.
|
* Executes the given {@link CollectionCallback} on the entity collection of the specified class.
|
||||||
* <br />
|
* <p/>
|
||||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||||
*
|
*
|
||||||
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
|
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
|
||||||
@@ -151,7 +151,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the given {@link CollectionCallback} on the collection of the given name.
|
* Executes the given {@link CollectionCallback} on the collection of the given name.
|
||||||
* <br />
|
* <p/>
|
||||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||||
*
|
*
|
||||||
* @param collectionName the name of the collection that specifies which {@link MongoCollection} instance will be
|
* @param collectionName the name of the collection that specifies which {@link MongoCollection} instance will be
|
||||||
@@ -176,7 +176,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Obtain a {@link ClientSession session} bound instance of {@link SessionScoped} binding the {@link ClientSession}
|
* Obtain a {@link ClientSession session} bound instance of {@link SessionScoped} binding the {@link ClientSession}
|
||||||
* provided by the given {@link Supplier} to each and every command issued against MongoDB.
|
* provided by the given {@link Supplier} to each and every command issued against MongoDB.
|
||||||
* <br />
|
* <p/>
|
||||||
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle. Use the
|
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle. Use the
|
||||||
* {@link SessionScoped#execute(SessionCallback, Consumer)} hook to potentially close the {@link ClientSession}.
|
* {@link SessionScoped#execute(SessionCallback, Consumer)} hook to potentially close the {@link ClientSession}.
|
||||||
*
|
*
|
||||||
@@ -212,7 +212,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain a {@link ClientSession} bound instance of {@link MongoOperations}.
|
* Obtain a {@link ClientSession} bound instance of {@link MongoOperations}.
|
||||||
* <br />
|
* <p/>
|
||||||
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle.
|
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle.
|
||||||
*
|
*
|
||||||
* @param session must not be {@literal null}.
|
* @param session must not be {@literal null}.
|
||||||
@@ -300,7 +300,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
* is created on first interaction with the server. Collections can be explicitly created via
|
* is created on first interaction with the server. Collections can be explicitly created via
|
||||||
* {@link #createCollection(Class)}. Please make sure to check if the collection {@link #collectionExists(Class)
|
* {@link #createCollection(Class)}. Please make sure to check if the collection {@link #collectionExists(Class)
|
||||||
* exists} first.
|
* exists} first.
|
||||||
* <br />
|
* <p/>
|
||||||
* Translate any exceptions as necessary.
|
* Translate any exceptions as necessary.
|
||||||
*
|
*
|
||||||
* @param collectionName name of the collection. Must not be {@literal null}.
|
* @param collectionName name of the collection. Must not be {@literal null}.
|
||||||
@@ -310,7 +310,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if a collection with a name indicated by the entity class exists.
|
* Check to see if a collection with a name indicated by the entity class exists.
|
||||||
* <br />
|
* <p/>
|
||||||
* Translate any exceptions as necessary.
|
* Translate any exceptions as necessary.
|
||||||
*
|
*
|
||||||
* @param entityClass class that determines the name of the collection. Must not be {@literal null}.
|
* @param entityClass class that determines the name of the collection. Must not be {@literal null}.
|
||||||
@@ -320,7 +320,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if a collection with a given name exists.
|
* Check to see if a collection with a given name exists.
|
||||||
* <br />
|
* <p/>
|
||||||
* Translate any exceptions as necessary.
|
* Translate any exceptions as necessary.
|
||||||
*
|
*
|
||||||
* @param collectionName name of the collection. Must not be {@literal null}.
|
* @param collectionName name of the collection. Must not be {@literal null}.
|
||||||
@@ -330,7 +330,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop the collection with the name indicated by the entity class.
|
* Drop the collection with the name indicated by the entity class.
|
||||||
* <br />
|
* <p/>
|
||||||
* Translate any exceptions as necessary.
|
* Translate any exceptions as necessary.
|
||||||
*
|
*
|
||||||
* @param entityClass class that determines the collection to drop/delete. Must not be {@literal null}.
|
* @param entityClass class that determines the collection to drop/delete. Must not be {@literal null}.
|
||||||
@@ -339,7 +339,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop the collection with the given name.
|
* Drop the collection with the given name.
|
||||||
* <br />
|
* <p/>
|
||||||
* Translate any exceptions as necessary.
|
* Translate any exceptions as necessary.
|
||||||
*
|
*
|
||||||
* @param collectionName name of the collection to drop/delete.
|
* @param collectionName name of the collection to drop/delete.
|
||||||
@@ -403,10 +403,10 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Query for a list of objects of type T from the collection used by the entity class.
|
* Query for a list of objects of type T from the collection used by the entity class.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
||||||
* to map objects since the test for class type is done in the client and not on the server.
|
* to map objects since the test for class type is done in the client and not on the server.
|
||||||
*
|
*
|
||||||
@@ -417,10 +417,10 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Query for a list of objects of type T from the specified collection.
|
* Query for a list of objects of type T from the specified collection.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
||||||
* to map objects since the test for class type is done in the client and not on the server.
|
* to map objects since the test for class type is done in the client and not on the server.
|
||||||
*
|
*
|
||||||
@@ -539,11 +539,11 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute an aggregation operation backed by a Mongo DB {@link com.mongodb.client.AggregateIterable}.
|
* Execute an aggregation operation backed by a Mongo DB {@link com.mongodb.client.AggregateIterable}.
|
||||||
* <br />
|
* <p/>
|
||||||
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link com.mongodb.client.AggregateIterable} that
|
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link com.mongodb.client.AggregateIterable} that
|
||||||
* needs to be closed. The raw results will be mapped to the given entity class and are returned as stream. The name
|
* needs to be closed. The raw results will be mapped to the given entity class and are returned as stream. The name
|
||||||
* of the inputCollection is derived from the inputType of the aggregation.
|
* of the inputCollection is derived from the inputType of the aggregation.
|
||||||
* <br />
|
* <p/>
|
||||||
* Aggregation streaming can't be used with {@link AggregationOptions#isExplain() aggregation explain}. Enabling
|
* Aggregation streaming can't be used with {@link AggregationOptions#isExplain() aggregation explain}. Enabling
|
||||||
* explanation mode will throw an {@link IllegalArgumentException}.
|
* explanation mode will throw an {@link IllegalArgumentException}.
|
||||||
*
|
*
|
||||||
@@ -557,10 +557,10 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute an aggregation operation backed by a Mongo DB {@link com.mongodb.client.AggregateIterable}.
|
* Execute an aggregation operation backed by a Mongo DB {@link com.mongodb.client.AggregateIterable}.
|
||||||
* <br />
|
* <p/>
|
||||||
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link com.mongodb.client.AggregateIterable} that
|
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link com.mongodb.client.AggregateIterable} that
|
||||||
* needs to be closed. The raw results will be mapped to the given entity class.
|
* needs to be closed. The raw results will be mapped to the given entity class.
|
||||||
* <br />
|
* <p/>
|
||||||
* Aggregation streaming can't be used with {@link AggregationOptions#isExplain() aggregation explain}. Enabling
|
* Aggregation streaming can't be used with {@link AggregationOptions#isExplain() aggregation explain}. Enabling
|
||||||
* explanation mode will throw an {@link IllegalArgumentException}.
|
* explanation mode will throw an {@link IllegalArgumentException}.
|
||||||
*
|
*
|
||||||
@@ -576,10 +576,10 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute an aggregation operation backed by a Mongo DB {@link com.mongodb.client.AggregateIterable}.
|
* Execute an aggregation operation backed by a Mongo DB {@link com.mongodb.client.AggregateIterable}.
|
||||||
* <br />
|
* <p/>
|
||||||
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link com.mongodb.client.AggregateIterable} that
|
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link com.mongodb.client.AggregateIterable} that
|
||||||
* needs to be closed. The raw results will be mapped to the given entity class.
|
* needs to be closed. The raw results will be mapped to the given entity class.
|
||||||
* <br />
|
* <p/>
|
||||||
* Aggregation streaming can't be used with {@link AggregationOptions#isExplain() aggregation explain}. Enabling
|
* Aggregation streaming can't be used with {@link AggregationOptions#isExplain() aggregation explain}. Enabling
|
||||||
* explanation mode will throw an {@link IllegalArgumentException}.
|
* explanation mode will throw an {@link IllegalArgumentException}.
|
||||||
*
|
*
|
||||||
@@ -702,10 +702,10 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Map the results of an ad-hoc query on the collection for the entity class to a single instance of an object of the
|
* Map the results of an ad-hoc query on the collection for the entity class to a single instance of an object of the
|
||||||
* specified type.
|
* specified type.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -720,10 +720,10 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified
|
* Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified
|
||||||
* type.
|
* type.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -768,10 +768,10 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Map the results of an ad-hoc query on the collection for the entity class to a List of the specified type.
|
* Map the results of an ad-hoc query on the collection for the entity class to a List of the specified type.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -784,10 +784,10 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Map the results of an ad-hoc query on the specified collection to a List of the specified type.
|
* Map the results of an ad-hoc query on the specified collection to a List of the specified type.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -881,7 +881,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify </a>
|
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify <a/>
|
||||||
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
|
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
|
||||||
*
|
*
|
||||||
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
|
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
|
||||||
@@ -897,7 +897,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
<T> T findAndModify(Query query, UpdateDefinition update, Class<T> entityClass);
|
<T> T findAndModify(Query query, UpdateDefinition update, Class<T> entityClass);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify </a>
|
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify <a/>
|
||||||
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
|
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
|
||||||
*
|
*
|
||||||
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
|
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
|
||||||
@@ -914,7 +914,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
<T> T findAndModify(Query query, UpdateDefinition update, Class<T> entityClass, String collectionName);
|
<T> T findAndModify(Query query, UpdateDefinition update, Class<T> entityClass, String collectionName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify </a>
|
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify <a/>
|
||||||
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
|
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
|
||||||
* {@link FindAndModifyOptions} into account.
|
* {@link FindAndModifyOptions} into account.
|
||||||
*
|
*
|
||||||
@@ -934,7 +934,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
<T> T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class<T> entityClass);
|
<T> T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class<T> entityClass);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify </a>
|
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify <a/>
|
||||||
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
|
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
|
||||||
* {@link FindAndModifyOptions} into account.
|
* {@link FindAndModifyOptions} into account.
|
||||||
*
|
*
|
||||||
@@ -957,7 +957,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement}
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement}
|
||||||
* document. <br />
|
* document. <br />
|
||||||
* The collection name is derived from the {@literal replacement} type. <br />
|
* The collection name is derived from the {@literal replacement} type. <br />
|
||||||
@@ -977,7 +977,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement}
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement}
|
||||||
* document.<br />
|
* document.<br />
|
||||||
* Options are defaulted to {@link FindAndReplaceOptions#empty()}. <br />
|
* Options are defaulted to {@link FindAndReplaceOptions#empty()}. <br />
|
||||||
@@ -997,7 +997,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
||||||
* taking {@link FindAndReplaceOptions} into account.<br />
|
* taking {@link FindAndReplaceOptions} into account.<br />
|
||||||
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
||||||
@@ -1018,7 +1018,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
||||||
* taking {@link FindAndReplaceOptions} into account.<br />
|
* taking {@link FindAndReplaceOptions} into account.<br />
|
||||||
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
||||||
@@ -1041,7 +1041,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
||||||
* taking {@link FindAndReplaceOptions} into account.<br />
|
* taking {@link FindAndReplaceOptions} into account.<br />
|
||||||
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
||||||
@@ -1066,7 +1066,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
||||||
* taking {@link FindAndReplaceOptions} into account.<br />
|
* taking {@link FindAndReplaceOptions} into account.<br />
|
||||||
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
||||||
@@ -1094,7 +1094,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
||||||
* taking {@link FindAndReplaceOptions} into account.<br />
|
* taking {@link FindAndReplaceOptions} into account.<br />
|
||||||
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
||||||
@@ -1120,9 +1120,9 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
* Map the results of an ad-hoc query on the collection for the entity type to a single instance of an object of the
|
* Map the results of an ad-hoc query on the collection for the entity type to a single instance of an object of the
|
||||||
* specified type. The first document that matches the query is returned and also removed from the collection in the
|
* specified type. The first document that matches the query is returned and also removed from the collection in the
|
||||||
* database.
|
* database.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}.
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -1137,10 +1137,10 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified
|
* Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified
|
||||||
* type. The first document that matches the query is returned and also removed from the collection in the database.
|
* type. The first document that matches the query is returned and also removed from the collection in the database.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -1160,12 +1160,6 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
||||||
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
||||||
* count all matches.
|
* count all matches.
|
||||||
* <br />
|
|
||||||
* This method uses an
|
|
||||||
* {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
|
|
||||||
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
|
|
||||||
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
|
|
||||||
* {@link #estimatedCount(Class)} for empty queries instead.
|
|
||||||
*
|
*
|
||||||
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
|
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
|
||||||
* {@literal null}.
|
* {@literal null}.
|
||||||
@@ -1182,12 +1176,6 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
||||||
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
||||||
* count all matches.
|
* count all matches.
|
||||||
* <br />
|
|
||||||
* This method uses an
|
|
||||||
* {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
|
|
||||||
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
|
|
||||||
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
|
|
||||||
* {@link #estimatedCount(String)} for empty queries instead.
|
|
||||||
*
|
*
|
||||||
* @param query the {@link Query} class that specifies the criteria used to find documents.
|
* @param query the {@link Query} class that specifies the criteria used to find documents.
|
||||||
* @param collectionName must not be {@literal null} or empty.
|
* @param collectionName must not be {@literal null} or empty.
|
||||||
@@ -1196,35 +1184,6 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
*/
|
*/
|
||||||
long count(Query query, String collectionName);
|
long count(Query query, String collectionName);
|
||||||
|
|
||||||
/**
|
|
||||||
* Estimate the number of documents, in the collection {@link #getCollectionName(Class) identified by the given type},
|
|
||||||
* based on collection statistics.
|
|
||||||
* <br />
|
|
||||||
* Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside
|
|
||||||
* transactions.
|
|
||||||
*
|
|
||||||
* @param entityClass must not be {@literal null}.
|
|
||||||
* @return the estimated number of documents.
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
default long estimatedCount(Class<?> entityClass) {
|
|
||||||
|
|
||||||
Assert.notNull(entityClass, "Entity class must not be null!");
|
|
||||||
return estimatedCount(getCollectionName(entityClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Estimate the number of documents in the given collection based on collection statistics.
|
|
||||||
* <br />
|
|
||||||
* Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside
|
|
||||||
* transactions.
|
|
||||||
*
|
|
||||||
* @param collectionName must not be {@literal null}.
|
|
||||||
* @return the estimated number of documents.
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
long estimatedCount(String collectionName);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of documents for the given {@link Query} by querying the given collection using the given entity
|
* Returns the number of documents for the given {@link Query} by querying the given collection using the given entity
|
||||||
* class to map the given {@link Query}. <br />
|
* class to map the given {@link Query}. <br />
|
||||||
@@ -1232,12 +1191,6 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
||||||
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
||||||
* count all matches.
|
* count all matches.
|
||||||
* <br />
|
|
||||||
* This method uses an
|
|
||||||
* {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
|
|
||||||
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
|
|
||||||
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
|
|
||||||
* {@link #estimatedCount(String)} for empty queries instead.
|
|
||||||
*
|
*
|
||||||
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
|
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
|
||||||
* {@literal null}.
|
* {@literal null}.
|
||||||
@@ -1249,39 +1202,34 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert the object into the collection for the entity type of the object to save.
|
* Insert the object into the collection for the entity type of the object to save.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}.
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
* 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
|
* 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
|
* 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
|
* <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation" > Spring's
|
||||||
* Type Conversion"</a> for more details.
|
* Type Conversion"</a> for more details.
|
||||||
* <br />
|
* <p/>
|
||||||
|
* <p/>
|
||||||
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
||||||
* <br />
|
|
||||||
* The {@code objectToSave} must not be collection-like.
|
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
* @return the inserted object.
|
* @return the inserted object.
|
||||||
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
|
|
||||||
*/
|
*/
|
||||||
<T> T insert(T objectToSave);
|
<T> T insert(T objectToSave);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert the object into the specified collection.
|
* Insert the object into the specified collection.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
||||||
* <br />
|
|
||||||
* The {@code objectToSave} must not be collection-like.
|
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
|
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
|
||||||
* @return the inserted object.
|
* @return the inserted object.
|
||||||
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
|
|
||||||
*/
|
*/
|
||||||
<T> T insert(T objectToSave, String collectionName);
|
<T> T insert(T objectToSave, String collectionName);
|
||||||
|
|
||||||
@@ -1315,42 +1263,37 @@ public interface MongoOperations extends FluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Save the object to the collection for the entity type of the object to save. This will perform an insert if the
|
* Save the object to the collection for the entity type of the object to save. This will perform an insert if the
|
||||||
* object is not already present, that is an 'upsert'.
|
* object is not already present, that is an 'upsert'.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
* 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
|
* 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
|
* 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
|
* <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation" > Spring's
|
||||||
* Type Conversion"</a> for more details.
|
* Type Conversion"</a> for more details.
|
||||||
* <br />
|
|
||||||
* The {@code objectToSave} must not be collection-like.
|
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
* @return the saved object.
|
* @return the saved object.
|
||||||
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
|
|
||||||
*/
|
*/
|
||||||
<T> T save(T objectToSave);
|
<T> T save(T objectToSave);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the object to the specified collection. This will perform an insert if the object is not already present, that
|
* Save the object to the specified collection. This will perform an insert if the object is not already present, that
|
||||||
* is an 'upsert'.
|
* is an 'upsert'.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
* 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
|
* 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.
|
* property type will be handled by Spring's BeanWrapper class that leverages Type Conversion API. See <a
|
||||||
* See <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation">Spring's Type Conversion</a> for more details.
|
* https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation">Spring's Type
|
||||||
* <br />
|
* Conversion"</a> for more details.
|
||||||
* The {@code objectToSave} must not be collection-like.
|
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
|
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
|
||||||
* @return the saved object.
|
* @return the saved object.
|
||||||
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
|
|
||||||
*/
|
*/
|
||||||
<T> T save(T objectToSave, String collectionName);
|
<T> T save(T objectToSave, String collectionName);
|
||||||
|
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021 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.beans.factory.FactoryBean;
|
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import org.springframework.util.ObjectUtils;
|
|
||||||
|
|
||||||
import com.mongodb.ServerApi;
|
|
||||||
import com.mongodb.ServerApi.Builder;
|
|
||||||
import com.mongodb.ServerApiVersion;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link FactoryBean} for creating {@link ServerApi} using the {@link ServerApi.Builder}.
|
|
||||||
*
|
|
||||||
* @author Christoph Strobl
|
|
||||||
* @since 3.3
|
|
||||||
*/
|
|
||||||
public class MongoServerApiFactoryBean implements FactoryBean<ServerApi> {
|
|
||||||
|
|
||||||
private String version;
|
|
||||||
private @Nullable Boolean deprecationErrors;
|
|
||||||
private @Nullable Boolean strict;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param version the version string either as the enum name or the server version value.
|
|
||||||
* @see ServerApiVersion
|
|
||||||
*/
|
|
||||||
public void setVersion(String version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param deprecationErrors
|
|
||||||
* @see ServerApi.Builder#deprecationErrors(boolean)
|
|
||||||
*/
|
|
||||||
public void setDeprecationErrors(@Nullable Boolean deprecationErrors) {
|
|
||||||
this.deprecationErrors = deprecationErrors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param strict
|
|
||||||
* @see ServerApi.Builder#strict(boolean)
|
|
||||||
*/
|
|
||||||
public void setStrict(@Nullable Boolean strict) {
|
|
||||||
this.strict = strict;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public ServerApi getObject() throws Exception {
|
|
||||||
|
|
||||||
Builder builder = ServerApi.builder().version(version());
|
|
||||||
|
|
||||||
if (deprecationErrors != null) {
|
|
||||||
builder = builder.deprecationErrors(deprecationErrors);
|
|
||||||
}
|
|
||||||
if (strict != null) {
|
|
||||||
builder = builder.strict(strict);
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Class<?> getObjectType() {
|
|
||||||
return ServerApi.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ServerApiVersion version() {
|
|
||||||
try {
|
|
||||||
// lookup by name eg. 'V1'
|
|
||||||
return ObjectUtils.caseInsensitiveValueOf(ServerApiVersion.values(), version);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// or just the version number, eg. just '1'
|
|
||||||
return ServerApiVersion.findByValue(version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -15,63 +15,62 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
import org.bson.Document;
|
import lombok.AccessLevel;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import org.bson.Document;
|
||||||
|
import org.springframework.data.mapping.SimplePropertyHandler;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
import org.springframework.data.mongodb.core.mapping.PersistentPropertyTranslator;
|
import org.springframework.data.projection.ProjectionFactory;
|
||||||
import org.springframework.data.projection.EntityProjection;
|
import org.springframework.data.projection.ProjectionInformation;
|
||||||
import org.springframework.data.util.Predicates;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common operations performed on properties of an entity like extracting fields information for projection creation.
|
* Common operations performed on properties of an entity like extracting fields information for projection creation.
|
||||||
*
|
*
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Mark Paluch
|
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||||
class PropertyOperations {
|
class PropertyOperations {
|
||||||
|
|
||||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||||
|
|
||||||
PropertyOperations(MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
|
||||||
this.mappingContext = mappingContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For cases where {@code fields} is {@link Document#isEmpty() empty} include only fields that are required for
|
* For cases where {@code fields} is {@link Document#isEmpty() empty} include only fields that are required for
|
||||||
* creating the projection (target) type if the {@code EntityProjection} is a {@literal DTO projection} or a
|
* creating the projection (target) type if the {@code targetType} is a {@literal DTO projection} or a
|
||||||
* {@literal closed interface projection}.
|
* {@literal closed interface projection}.
|
||||||
*
|
*
|
||||||
* @param projection must not be {@literal null}.
|
* @param projectionFactory must not be {@literal null}.
|
||||||
* @param fields must not be {@literal null}.
|
* @param fields must not be {@literal null}.
|
||||||
|
* @param domainType must not be {@literal null}.
|
||||||
|
* @param targetType must not be {@literal null}.
|
||||||
* @return {@link Document} with fields to be included.
|
* @return {@link Document} with fields to be included.
|
||||||
*/
|
*/
|
||||||
Document computeMappedFieldsForProjection(EntityProjection<?, ?> projection,
|
Document computeFieldsForProjection(ProjectionFactory projectionFactory, Document fields, Class<?> domainType,
|
||||||
Document fields) {
|
Class<?> targetType) {
|
||||||
|
|
||||||
if (!projection.isClosedProjection()) {
|
if (!fields.isEmpty() || ClassUtils.isAssignable(domainType, targetType)) {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
Document projectedFields = new Document();
|
Document projectedFields = new Document();
|
||||||
|
|
||||||
if (projection.getMappedType().getType().isInterface()) {
|
if (targetType.isInterface()) {
|
||||||
projection.forEach(it -> {
|
|
||||||
projectedFields.put(it.getPropertyPath().getSegment(), 1);
|
ProjectionInformation projectionInformation = projectionFactory.getProjectionInformation(targetType);
|
||||||
});
|
|
||||||
|
if (projectionInformation.isClosed()) {
|
||||||
|
projectionInformation.getInputProperties().forEach(it -> projectedFields.append(it.getName(), 1));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// DTO projections use merged metadata between domain type and result type
|
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(targetType);
|
||||||
PersistentPropertyTranslator translator = PersistentPropertyTranslator.create(
|
if (entity != null) {
|
||||||
mappingContext.getRequiredPersistentEntity(projection.getDomainType()),
|
entity.doWithProperties(
|
||||||
Predicates.negate(MongoPersistentProperty::hasExplicitFieldName));
|
(SimplePropertyHandler) persistentProperty -> projectedFields.append(persistentProperty.getName(), 1));
|
||||||
|
|
||||||
MongoPersistentEntity<?> persistentEntity = mappingContext
|
|
||||||
.getRequiredPersistentEntity(projection.getMappedType());
|
|
||||||
for (MongoPersistentProperty property : persistentEntity) {
|
|
||||||
projectedFields.put(translator.translate(property).getFieldName(), 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ package org.springframework.data.mongodb.core;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -28,22 +27,15 @@ import java.util.stream.Collectors;
|
|||||||
import org.bson.BsonValue;
|
import org.bson.BsonValue;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.codecs.Codec;
|
import org.bson.codecs.Codec;
|
||||||
|
|
||||||
import org.springframework.data.mapping.PropertyPath;
|
import org.springframework.data.mapping.PropertyPath;
|
||||||
import org.springframework.data.mapping.PropertyReferenceException;
|
import org.springframework.data.mapping.PropertyReferenceException;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.mongodb.CodecRegistryProvider;
|
import org.springframework.data.mongodb.CodecRegistryProvider;
|
||||||
import org.springframework.data.mongodb.MongoExpression;
|
|
||||||
import org.springframework.data.mongodb.core.MappedDocument.MappedUpdate;
|
import org.springframework.data.mongodb.core.MappedDocument.MappedUpdate;
|
||||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||||
import org.springframework.data.mongodb.core.aggregation.AggregationExpression;
|
|
||||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
|
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.AggregationUpdate;
|
import org.springframework.data.mongodb.core.aggregation.AggregationUpdate;
|
||||||
import org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext;
|
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.convert.QueryMapper;
|
||||||
import org.springframework.data.mongodb.core.convert.UpdateMapper;
|
import org.springframework.data.mongodb.core.convert.UpdateMapper;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
@@ -55,10 +47,10 @@ import org.springframework.data.mongodb.core.query.Query;
|
|||||||
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
||||||
import org.springframework.data.mongodb.core.query.UpdateDefinition.ArrayFilter;
|
import org.springframework.data.mongodb.core.query.UpdateDefinition.ArrayFilter;
|
||||||
import org.springframework.data.mongodb.util.BsonUtils;
|
import org.springframework.data.mongodb.util.BsonUtils;
|
||||||
import org.springframework.data.projection.EntityProjection;
|
import org.springframework.data.projection.ProjectionFactory;
|
||||||
import org.springframework.data.util.Lazy;
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import com.mongodb.client.model.CountOptions;
|
import com.mongodb.client.model.CountOptions;
|
||||||
@@ -202,34 +194,9 @@ class QueryOperations {
|
|||||||
return new DeleteContext(query, false);
|
return new DeleteContext(query, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new {@link AggregationDefinition} for the given {@link Aggregation}.
|
|
||||||
*
|
|
||||||
* @param aggregation must not be {@literal null}.
|
|
||||||
* @param inputType fallback mapping type in case of untyped aggregation. Can be {@literal null}.
|
|
||||||
* @return new instance of {@link AggregationDefinition}.
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
AggregationDefinition createAggregation(Aggregation aggregation, @Nullable Class<?> inputType) {
|
|
||||||
return new AggregationDefinition(aggregation, inputType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new {@link AggregationDefinition} for the given {@link Aggregation}.
|
|
||||||
*
|
|
||||||
* @param aggregation must not be {@literal null}.
|
|
||||||
* @param aggregationOperationContext the {@link AggregationOperationContext} to use. Can be {@literal null}.
|
|
||||||
* @return new instance of {@link AggregationDefinition}.
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
AggregationDefinition createAggregation(Aggregation aggregation,
|
|
||||||
@Nullable AggregationOperationContext aggregationOperationContext) {
|
|
||||||
return new AggregationDefinition(aggregation, aggregationOperationContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link QueryContext} encapsulates common tasks required to convert a {@link Query} into its MongoDB document
|
* {@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}.
|
* representation, mapping fieldnames, as well as determinging and applying {@link Collation collations}.
|
||||||
*
|
*
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
*/
|
*/
|
||||||
@@ -238,7 +205,7 @@ class QueryOperations {
|
|||||||
private final Query query;
|
private final Query query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new a {@link QueryContext} instance from the given {@literal query} (can be either a {@link Query} or a
|
* Create new a {@link QueryContext} instance from the given {@literal query} (can be eihter a {@link Query} or a
|
||||||
* plain {@link Document}.
|
* plain {@link Document}.
|
||||||
*
|
*
|
||||||
* @param query can be {@literal null}.
|
* @param query can be {@literal null}.
|
||||||
@@ -288,59 +255,31 @@ class QueryOperations {
|
|||||||
return queryMapper.getMappedObject(getQueryObject(), entity);
|
return queryMapper.getMappedObject(getQueryObject(), entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
Document getMappedFields(@Nullable MongoPersistentEntity<?> entity,
|
Document getMappedFields(@Nullable MongoPersistentEntity<?> entity, Class<?> targetType,
|
||||||
EntityProjection<?, ?> projection) {
|
ProjectionFactory projectionFactory) {
|
||||||
|
|
||||||
Document fields = evaluateFields(entity);
|
Document fields = query.getFieldsObject();
|
||||||
|
Document mappedFields = fields;
|
||||||
|
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
return fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
Document mappedFields;
|
|
||||||
if (!fields.isEmpty()) {
|
|
||||||
mappedFields = queryMapper.getMappedFields(fields, entity);
|
|
||||||
} else {
|
|
||||||
mappedFields = propertyOperations.computeMappedFieldsForProjection(projection, fields);
|
|
||||||
mappedFields = queryMapper.addMetaAttributes(mappedFields, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity.hasTextScoreProperty() && mappedFields.containsKey(entity.getTextScoreProperty().getFieldName())
|
|
||||||
&& !query.getQueryObject().containsKey("$text")) {
|
|
||||||
mappedFields.remove(entity.getTextScoreProperty().getFieldName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mappedFields.isEmpty()) {
|
|
||||||
return BsonUtils.EMPTY_DOCUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mappedFields;
|
return mappedFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Document evaluateFields(@Nullable MongoPersistentEntity<?> entity) {
|
Document projectedFields = propertyOperations.computeFieldsForProjection(projectionFactory, fields,
|
||||||
|
entity.getType(), targetType);
|
||||||
|
|
||||||
Document fields = query.getFieldsObject();
|
if (ObjectUtils.nullSafeEquals(fields, projectedFields)) {
|
||||||
|
mappedFields = queryMapper.getMappedFields(projectedFields, entity);
|
||||||
if (fields.isEmpty()) {
|
|
||||||
return BsonUtils.EMPTY_DOCUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
Document evaluated = new Document();
|
|
||||||
|
|
||||||
for (Entry<String, Object> entry : fields.entrySet()) {
|
|
||||||
|
|
||||||
if (entry.getValue() instanceof MongoExpression) {
|
|
||||||
|
|
||||||
AggregationOperationContext ctx = entity == null ? Aggregation.DEFAULT_CONTEXT
|
|
||||||
: new RelaxedTypeBasedAggregationOperationContext(entity.getType(), mappingContext, queryMapper);
|
|
||||||
|
|
||||||
evaluated.put(entry.getKey(), AggregationExpression.from((MongoExpression) entry.getValue()).toDocument(ctx));
|
|
||||||
} else {
|
} else {
|
||||||
evaluated.put(entry.getKey(), entry.getValue());
|
mappedFields = queryMapper.getMappedFields(projectedFields,
|
||||||
}
|
mappingContext.getRequiredPersistentEntity(targetType));
|
||||||
}
|
}
|
||||||
|
|
||||||
return evaluated;
|
if (entity != null && entity.hasTextScoreProperty() && !query.getQueryObject().containsKey("$text")) {
|
||||||
|
mappedFields.remove(entity.getTextScoreProperty().getFieldName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return mappedFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -402,8 +341,7 @@ class QueryOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Document getMappedFields(@Nullable MongoPersistentEntity<?> entity,
|
Document getMappedFields(@Nullable MongoPersistentEntity<?> entity, Class<?> targetType, ProjectionFactory projectionFactory) {
|
||||||
EntityProjection<?, ?> projection) {
|
|
||||||
return getMappedFields(entity);
|
return getMappedFields(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,7 +565,7 @@ class QueryOperations {
|
|||||||
|
|
||||||
UpdateContext(MappedDocument update, boolean upsert) {
|
UpdateContext(MappedDocument update, boolean upsert) {
|
||||||
|
|
||||||
super(new BasicQuery(BsonUtils.asDocument(update.getIdFilter())));
|
super(new BasicQuery(new Document(BsonUtils.asMap(update.getIdFilter()))));
|
||||||
this.multi = false;
|
this.multi = false;
|
||||||
this.upsert = upsert;
|
this.upsert = upsert;
|
||||||
this.mappedDocument = update;
|
this.mappedDocument = update;
|
||||||
@@ -770,10 +708,10 @@ class QueryOperations {
|
|||||||
*/
|
*/
|
||||||
List<Document> getUpdatePipeline(@Nullable Class<?> domainType) {
|
List<Document> getUpdatePipeline(@Nullable Class<?> domainType) {
|
||||||
|
|
||||||
Class<?> type = domainType != null ? domainType : Object.class;
|
AggregationOperationContext context = domainType != null
|
||||||
|
? new RelaxedTypeBasedAggregationOperationContext(domainType, mappingContext, queryMapper)
|
||||||
|
: Aggregation.DEFAULT_CONTEXT;
|
||||||
|
|
||||||
AggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(type, mappingContext,
|
|
||||||
queryMapper);
|
|
||||||
return aggregationUtil.createPipeline((AggregationUpdate) update, context);
|
return aggregationUtil.createPipeline((AggregationUpdate) update, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -823,105 +761,4 @@ class QueryOperations {
|
|||||||
return multi;
|
return multi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A value object that encapsulates common tasks required when running {@literal aggregations}.
|
|
||||||
*
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
class AggregationDefinition {
|
|
||||||
|
|
||||||
private final Aggregation aggregation;
|
|
||||||
private final Lazy<AggregationOperationContext> aggregationOperationContext;
|
|
||||||
private final Lazy<List<Document>> pipeline;
|
|
||||||
private final @Nullable Class<?> inputType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates new instance of {@link AggregationDefinition} extracting the input type from either the
|
|
||||||
* {@link org.springframework.data.mongodb.core.aggregation.Aggregation} in case of a {@link TypedAggregation} or
|
|
||||||
* the given {@literal aggregationOperationContext} if present. <br />
|
|
||||||
* Creates a new {@link AggregationOperationContext} if none given, based on the {@link Aggregation} input type and
|
|
||||||
* the desired {@link AggregationOptions#getDomainTypeMapping() domain type mapping}. <br />
|
|
||||||
* Pipelines are mapped on first access of {@link #getAggregationPipeline()} and cached for reuse.
|
|
||||||
*
|
|
||||||
* @param aggregation the source aggregation.
|
|
||||||
* @param aggregationOperationContext can be {@literal null}.
|
|
||||||
*/
|
|
||||||
AggregationDefinition(Aggregation aggregation, @Nullable AggregationOperationContext aggregationOperationContext) {
|
|
||||||
|
|
||||||
this.aggregation = aggregation;
|
|
||||||
|
|
||||||
if (aggregation instanceof TypedAggregation) {
|
|
||||||
this.inputType = ((TypedAggregation<?>) aggregation).getInputType();
|
|
||||||
} else if (aggregationOperationContext instanceof TypeBasedAggregationOperationContext) {
|
|
||||||
this.inputType = ((TypeBasedAggregationOperationContext) aggregationOperationContext).getType();
|
|
||||||
} else {
|
|
||||||
this.inputType = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.aggregationOperationContext = Lazy.of(() -> aggregationOperationContext != null ? aggregationOperationContext
|
|
||||||
: aggregationUtil.createAggregationContext(aggregation, getInputType()));
|
|
||||||
this.pipeline = Lazy.of(() -> aggregationUtil.createPipeline(this.aggregation, getAggregationOperationContext()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates new instance of {@link AggregationDefinition} extracting the input type from either the
|
|
||||||
* {@link org.springframework.data.mongodb.core.aggregation.Aggregation} in case of a {@link TypedAggregation} or
|
|
||||||
* the given {@literal aggregationOperationContext} if present. <br />
|
|
||||||
* Creates a new {@link AggregationOperationContext} based on the {@link Aggregation} input type and the desired
|
|
||||||
* {@link AggregationOptions#getDomainTypeMapping() domain type mapping}. <br />
|
|
||||||
* Pipelines are mapped on first access of {@link #getAggregationPipeline()} and cached for reuse.
|
|
||||||
*
|
|
||||||
* @param aggregation the source aggregation.
|
|
||||||
* @param inputType can be {@literal null}.
|
|
||||||
*/
|
|
||||||
AggregationDefinition(Aggregation aggregation, @Nullable Class<?> inputType) {
|
|
||||||
|
|
||||||
this.aggregation = aggregation;
|
|
||||||
|
|
||||||
if (aggregation instanceof TypedAggregation) {
|
|
||||||
this.inputType = ((TypedAggregation<?>) aggregation).getInputType();
|
|
||||||
} else {
|
|
||||||
this.inputType = inputType;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.aggregationOperationContext = Lazy
|
|
||||||
.of(() -> aggregationUtil.createAggregationContext(aggregation, getInputType()));
|
|
||||||
this.pipeline = Lazy.of(() -> aggregationUtil.createPipeline(this.aggregation, getAggregationOperationContext()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain the already mapped pipeline.
|
|
||||||
*
|
|
||||||
* @return never {@literal null}.
|
|
||||||
*/
|
|
||||||
List<Document> getAggregationPipeline() {
|
|
||||||
return pipeline.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@literal true} if the last aggregation stage is either {@literal $out} or {@literal $merge}.
|
|
||||||
* @see AggregationPipeline#isOutOrMerge()
|
|
||||||
*/
|
|
||||||
boolean isOutOrMerge() {
|
|
||||||
return aggregation.getPipeline().isOutOrMerge();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain the {@link AggregationOperationContext} used for mapping the pipeline.
|
|
||||||
*
|
|
||||||
* @return never {@literal null}.
|
|
||||||
*/
|
|
||||||
AggregationOperationContext getAggregationOperationContext() {
|
|
||||||
return aggregationOperationContext.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the input type to map the pipeline against. Can be {@literal null}.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
Class<?> getInputType() {
|
|
||||||
return inputType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||||
@@ -46,6 +50,10 @@ class ReactiveAggregationOperationSupport implements ReactiveAggregationOperatio
|
|||||||
this.template = template;
|
this.template = template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveAggregationOperation#aggregateAndReturn(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T> ReactiveAggregation<T> aggregateAndReturn(Class<T> domainType) {
|
public <T> ReactiveAggregation<T> aggregateAndReturn(Class<T> domainType) {
|
||||||
|
|
||||||
@@ -54,23 +62,20 @@ class ReactiveAggregationOperationSupport implements ReactiveAggregationOperatio
|
|||||||
return new ReactiveAggregationSupport<>(template, domainType, null, null);
|
return new ReactiveAggregationSupport<>(template, domainType, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||||
static class ReactiveAggregationSupport<T>
|
static class ReactiveAggregationSupport<T>
|
||||||
implements AggregationOperationWithAggregation<T>, ReactiveAggregation<T>, TerminatingAggregationOperation<T> {
|
implements AggregationOperationWithAggregation<T>, ReactiveAggregation<T>, TerminatingAggregationOperation<T> {
|
||||||
|
|
||||||
private final ReactiveMongoTemplate template;
|
@NonNull ReactiveMongoTemplate template;
|
||||||
private final Class<T> domainType;
|
@NonNull Class<T> domainType;
|
||||||
private final Aggregation aggregation;
|
Aggregation aggregation;
|
||||||
private final String collection;
|
String collection;
|
||||||
|
|
||||||
ReactiveAggregationSupport(ReactiveMongoTemplate template, Class<T> domainType, Aggregation aggregation,
|
|
||||||
String collection) {
|
|
||||||
|
|
||||||
this.template = template;
|
|
||||||
this.domainType = domainType;
|
|
||||||
this.aggregation = aggregation;
|
|
||||||
this.collection = collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveAggregationOperation.AggregationOperationWithCollection#inCollection(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AggregationOperationWithAggregation<T> inCollection(String collection) {
|
public AggregationOperationWithAggregation<T> inCollection(String collection) {
|
||||||
|
|
||||||
@@ -79,6 +84,10 @@ class ReactiveAggregationOperationSupport implements ReactiveAggregationOperatio
|
|||||||
return new ReactiveAggregationSupport<>(template, domainType, aggregation, collection);
|
return new ReactiveAggregationSupport<>(template, domainType, aggregation, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveAggregationOperation.AggregationOperationWithAggregation#by(org.springframework.data.mongodb.core.Aggregation)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingAggregationOperation<T> by(Aggregation aggregation) {
|
public TerminatingAggregationOperation<T> by(Aggregation aggregation) {
|
||||||
|
|
||||||
@@ -87,6 +96,10 @@ class ReactiveAggregationOperationSupport implements ReactiveAggregationOperatio
|
|||||||
return new ReactiveAggregationSupport<>(template, domainType, aggregation, collection);
|
return new ReactiveAggregationSupport<>(template, domainType, aggregation, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveAggregationOperation.TerminatingAggregationOperation#all()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Flux<T> all() {
|
public Flux<T> all() {
|
||||||
return template.aggregate(aggregation, getCollectionName(aggregation), domainType);
|
return template.aggregate(aggregation, getCollectionName(aggregation), domainType);
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public interface ReactiveChangeStreamOperation {
|
|||||||
/**
|
/**
|
||||||
* Start listening to changes. The stream will not be completed unless the {@link org.reactivestreams.Subscription}
|
* Start listening to changes. The stream will not be completed unless the {@link org.reactivestreams.Subscription}
|
||||||
* is {@link org.reactivestreams.Subscription#cancel() canceled}.
|
* is {@link org.reactivestreams.Subscription#cancel() canceled}.
|
||||||
* <br />
|
* <p />
|
||||||
* However, the stream may become dead, or invalid, if all watched collections, databases are dropped.
|
* However, the stream may become dead, or invalid, if all watched collections, databases are dropped.
|
||||||
*/
|
*/
|
||||||
Flux<ChangeStreamEvent<T>> listen();
|
Flux<ChangeStreamEvent<T>> listen();
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
|||||||
this.template = template;
|
this.template = template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation#changeStream(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T> ReactiveChangeStream<T> changeStream(Class<T> domainType) {
|
public <T> ReactiveChangeStream<T> changeStream(Class<T> domainType) {
|
||||||
|
|
||||||
@@ -72,6 +76,10 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
|||||||
this.options = options;
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation.ChangeStreamWithCollection#watchCollection(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ChangeStreamWithFilterAndProjection<T> watchCollection(String collection) {
|
public ChangeStreamWithFilterAndProjection<T> watchCollection(String collection) {
|
||||||
|
|
||||||
@@ -80,6 +88,10 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
|||||||
return new ReactiveChangeStreamSupport<>(template, domainType, returnType, collection, options);
|
return new ReactiveChangeStreamSupport<>(template, domainType, returnType, collection, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation.ChangeStreamWithCollection#watchCollection(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ChangeStreamWithFilterAndProjection<T> watchCollection(Class<?> entityClass) {
|
public ChangeStreamWithFilterAndProjection<T> watchCollection(Class<?> entityClass) {
|
||||||
|
|
||||||
@@ -88,6 +100,10 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
|||||||
return watchCollection(template.getCollectionName(entityClass));
|
return watchCollection(template.getCollectionName(entityClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation.ResumingChangeStream#resumeAt(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingChangeStream<T> resumeAt(Object token) {
|
public TerminatingChangeStream<T> resumeAt(Object token) {
|
||||||
|
|
||||||
@@ -101,6 +117,10 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation.ResumingChangeStream#resumeAfter(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingChangeStream<T> resumeAfter(Object token) {
|
public TerminatingChangeStream<T> resumeAfter(Object token) {
|
||||||
|
|
||||||
@@ -109,6 +129,10 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
|||||||
return withOptions(builder -> builder.resumeAfter((BsonValue) token));
|
return withOptions(builder -> builder.resumeAfter((BsonValue) token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation.ResumingChangeStream#startAfter(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingChangeStream<T> startAfter(Object token) {
|
public TerminatingChangeStream<T> startAfter(Object token) {
|
||||||
|
|
||||||
@@ -117,6 +141,10 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
|||||||
return withOptions(builder -> builder.startAfter((BsonValue) token));
|
return withOptions(builder -> builder.startAfter((BsonValue) token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation.ChangeStreamWithOptions#withOptions(java.util.function.Consumer)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ReactiveChangeStreamSupport<T> withOptions(Consumer<ChangeStreamOptionsBuilder> optionsConsumer) {
|
public ReactiveChangeStreamSupport<T> withOptions(Consumer<ChangeStreamOptionsBuilder> optionsConsumer) {
|
||||||
|
|
||||||
@@ -126,6 +154,10 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
|||||||
return new ReactiveChangeStreamSupport<>(template, domainType, returnType, collection, builder.build());
|
return new ReactiveChangeStreamSupport<>(template, domainType, returnType, collection, builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation.ChangeStreamWithProjection#as(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <R> ChangeStreamWithFilterAndProjection<R> as(Class<R> resultType) {
|
public <R> ChangeStreamWithFilterAndProjection<R> as(Class<R> resultType) {
|
||||||
|
|
||||||
@@ -134,11 +166,19 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
|||||||
return new ReactiveChangeStreamSupport<>(template, domainType, resultType, collection, options);
|
return new ReactiveChangeStreamSupport<>(template, domainType, resultType, collection, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation.ChangeStreamWithFilter#filter(org.springframework.data.mongodb.core.aggregation.Aggregation)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ChangeStreamWithFilterAndProjection<T> filter(Aggregation filter) {
|
public ChangeStreamWithFilterAndProjection<T> filter(Aggregation filter) {
|
||||||
return withOptions(builder -> builder.filter(filter));
|
return withOptions(builder -> builder.filter(filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation.ChangeStreamWithFilter#filter(org.springframework.data.mongodb.core.query.CriteriaDefinition)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ChangeStreamWithFilterAndProjection<T> filter(CriteriaDefinition by) {
|
public ChangeStreamWithFilterAndProjection<T> filter(CriteriaDefinition by) {
|
||||||
|
|
||||||
@@ -148,6 +188,10 @@ class ReactiveChangeStreamOperationSupport implements ReactiveChangeStreamOperat
|
|||||||
return filter(aggregation);
|
return filter(aggregation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveChangeStreamOperation.TerminatingChangeStream#listen()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Flux<ChangeStreamEvent<T>> listen() {
|
public Flux<ChangeStreamEvent<T>> listen() {
|
||||||
return template.changeStream(collection, options != null ? options : ChangeStreamOptions.empty(), returnType);
|
return template.changeStream(collection, options != null ? options : ChangeStreamOptions.empty(), returnType);
|
||||||
|
|||||||
@@ -91,10 +91,10 @@ public interface ReactiveFindOperation {
|
|||||||
* Get all matching elements using a {@link com.mongodb.CursorType#TailableAwait tailable cursor}. The stream will
|
* Get all matching elements using a {@link com.mongodb.CursorType#TailableAwait tailable cursor}. The stream will
|
||||||
* not be completed unless the {@link org.reactivestreams.Subscription} is
|
* not be completed unless the {@link org.reactivestreams.Subscription} is
|
||||||
* {@link org.reactivestreams.Subscription#cancel() canceled}.
|
* {@link org.reactivestreams.Subscription#cancel() canceled}.
|
||||||
* <br />
|
* <p />
|
||||||
* However, the stream may become dead, or invalid, if either the query returns no match or the cursor returns the
|
* However, the stream may become dead, or invalid, if either the query returns no match or the cursor returns the
|
||||||
* document at the "end" of the collection and then the application deletes that document.
|
* document at the "end" of the collection and then the application deletes that document.
|
||||||
* <br />
|
* <p />
|
||||||
* A stream that is no longer in use must be {@link reactor.core.Disposable#dispose()} disposed} otherwise the
|
* A stream that is no longer in use must be {@link reactor.core.Disposable#dispose()} disposed} otherwise the
|
||||||
* streams will linger and exhaust resources. <br/>
|
* streams will linger and exhaust resources. <br/>
|
||||||
* <strong>NOTE:</strong> Requires a capped collection.
|
* <strong>NOTE:</strong> Requires a capped collection.
|
||||||
@@ -106,12 +106,6 @@ public interface ReactiveFindOperation {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of matching elements.
|
* Get the number of matching elements.
|
||||||
* <br />
|
|
||||||
* This method uses an
|
|
||||||
* {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
|
|
||||||
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but
|
|
||||||
* guarantees shard, session and transaction compliance. In case an inaccurate count satisfies the applications
|
|
||||||
* needs use {@link ReactiveMongoOperations#estimatedCount(String)} for empty queries instead.
|
|
||||||
*
|
*
|
||||||
* @return {@link Mono} emitting total number of matching elements. Never {@literal null}.
|
* @return {@link Mono} emitting total number of matching elements. Never {@literal null}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,10 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
|
||||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
@@ -34,16 +39,17 @@ import org.springframework.util.StringUtils;
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
||||||
|
|
||||||
private static final Query ALL_QUERY = new Query();
|
private static final Query ALL_QUERY = new Query();
|
||||||
|
|
||||||
private final ReactiveMongoTemplate template;
|
private final @NonNull ReactiveMongoTemplate template;
|
||||||
|
|
||||||
ReactiveFindOperationSupport(ReactiveMongoTemplate template) {
|
|
||||||
this.template = template;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation#query(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T> ReactiveFind<T> query(Class<T> domainType) {
|
public <T> ReactiveFind<T> query(Class<T> domainType) {
|
||||||
|
|
||||||
@@ -58,25 +64,21 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||||
static class ReactiveFindSupport<T>
|
static class ReactiveFindSupport<T>
|
||||||
implements ReactiveFind<T>, FindWithCollection<T>, FindWithProjection<T>, FindWithQuery<T> {
|
implements ReactiveFind<T>, FindWithCollection<T>, FindWithProjection<T>, FindWithQuery<T> {
|
||||||
|
|
||||||
private final ReactiveMongoTemplate template;
|
@NonNull ReactiveMongoTemplate template;
|
||||||
private final Class<?> domainType;
|
@NonNull Class<?> domainType;
|
||||||
private final Class<T> returnType;
|
Class<T> returnType;
|
||||||
private final String collection;
|
String collection;
|
||||||
private final Query query;
|
Query query;
|
||||||
|
|
||||||
ReactiveFindSupport(ReactiveMongoTemplate template, Class<?> domainType, Class<T> returnType,
|
|
||||||
String collection, Query query) {
|
|
||||||
|
|
||||||
this.template = template;
|
|
||||||
this.domainType = domainType;
|
|
||||||
this.returnType = returnType;
|
|
||||||
this.collection = collection;
|
|
||||||
this.query = query;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.FindWithCollection#inCollection(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public FindWithProjection<T> inCollection(String collection) {
|
public FindWithProjection<T> inCollection(String collection) {
|
||||||
|
|
||||||
@@ -85,6 +87,10 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
|||||||
return new ReactiveFindSupport<>(template, domainType, returnType, collection, query);
|
return new ReactiveFindSupport<>(template, domainType, returnType, collection, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.FindWithProjection#as(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T1> FindWithQuery<T1> as(Class<T1> returnType) {
|
public <T1> FindWithQuery<T1> as(Class<T1> returnType) {
|
||||||
|
|
||||||
@@ -93,6 +99,10 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
|||||||
return new ReactiveFindSupport<>(template, domainType, returnType, collection, query);
|
return new ReactiveFindSupport<>(template, domainType, returnType, collection, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.FindWithQuery#matching(org.springframework.data.mongodb.core.query.Query)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingFind<T> matching(Query query) {
|
public TerminatingFind<T> matching(Query query) {
|
||||||
|
|
||||||
@@ -101,6 +111,10 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
|||||||
return new ReactiveFindSupport<>(template, domainType, returnType, collection, query);
|
return new ReactiveFindSupport<>(template, domainType, returnType, collection, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.TerminatingFind#first()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Mono<T> first() {
|
public Mono<T> first() {
|
||||||
|
|
||||||
@@ -110,6 +124,10 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
|||||||
return result.next();
|
return result.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.TerminatingFind#one()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Mono<T> one() {
|
public Mono<T> one() {
|
||||||
|
|
||||||
@@ -131,31 +149,55 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.TerminatingFind#all()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Flux<T> all() {
|
public Flux<T> all() {
|
||||||
return doFind(null);
|
return doFind(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.TerminatingFind#tail()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Flux<T> tail() {
|
public Flux<T> tail() {
|
||||||
return doFind(template.new TailingQueryFindPublisherPreparer(query, domainType));
|
return doFind(template.new TailingQueryFindPublisherPreparer(query, domainType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.FindWithQuery#near(org.springframework.data.mongodb.core.query.NearQuery)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingFindNear<T> near(NearQuery nearQuery) {
|
public TerminatingFindNear<T> near(NearQuery nearQuery) {
|
||||||
return () -> template.geoNear(nearQuery, domainType, getCollectionName(), returnType);
|
return () -> template.geoNear(nearQuery, domainType, getCollectionName(), returnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.TerminatingFind#count()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Mono<Long> count() {
|
public Mono<Long> count() {
|
||||||
return template.count(query, domainType, getCollectionName());
|
return template.count(query, domainType, getCollectionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.TerminatingFind#exists()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Mono<Boolean> exists() {
|
public Mono<Boolean> exists() {
|
||||||
return template.exists(query, domainType, getCollectionName());
|
return template.exists(query, domainType, getCollectionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.FindDistinct#distinct(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingDistinct<Object> distinct(String field) {
|
public TerminatingDistinct<Object> distinct(String field) {
|
||||||
|
|
||||||
@@ -207,6 +249,10 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
|||||||
this.field = field;
|
this.field = field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.DistinctWithProjection#as(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <R> TerminatingDistinct<R> as(Class<R> resultType) {
|
public <R> TerminatingDistinct<R> as(Class<R> resultType) {
|
||||||
|
|
||||||
@@ -215,6 +261,10 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
|||||||
return new DistinctOperationSupport<>((ReactiveFindSupport) delegate.as(resultType), field);
|
return new DistinctOperationSupport<>((ReactiveFindSupport) delegate.as(resultType), field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveFindOperation.DistinctWithQuery#matching(org.springframework.data.mongodb.core.query.Query)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public TerminatingDistinct<T> matching(Query query) {
|
public TerminatingDistinct<T> matching(Query query) {
|
||||||
@@ -224,6 +274,10 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
|||||||
return new DistinctOperationSupport<>((ReactiveFindSupport<T>) delegate.matching(query), field);
|
return new DistinctOperationSupport<>((ReactiveFindSupport<T>) delegate.matching(query), field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core..ReactiveFindOperation.TerminatingDistinct#all()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Flux<T> all() {
|
public Flux<T> all() {
|
||||||
return delegate.doFindDistinct(field);
|
return delegate.doFindDistinct(field);
|
||||||
|
|||||||
@@ -15,6 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
@@ -30,14 +34,15 @@ import org.springframework.util.StringUtils;
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class ReactiveInsertOperationSupport implements ReactiveInsertOperation {
|
class ReactiveInsertOperationSupport implements ReactiveInsertOperation {
|
||||||
|
|
||||||
private final ReactiveMongoTemplate template;
|
private final @NonNull ReactiveMongoTemplate template;
|
||||||
|
|
||||||
ReactiveInsertOperationSupport(ReactiveMongoTemplate template) {
|
|
||||||
this.template = template;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveInsertOperation#insert(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T> ReactiveInsert<T> insert(Class<T> domainType) {
|
public <T> ReactiveInsert<T> insert(Class<T> domainType) {
|
||||||
|
|
||||||
@@ -46,19 +51,18 @@ class ReactiveInsertOperationSupport implements ReactiveInsertOperation {
|
|||||||
return new ReactiveInsertSupport<>(template, domainType, null);
|
return new ReactiveInsertSupport<>(template, domainType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||||
static class ReactiveInsertSupport<T> implements ReactiveInsert<T> {
|
static class ReactiveInsertSupport<T> implements ReactiveInsert<T> {
|
||||||
|
|
||||||
private final ReactiveMongoTemplate template;
|
@NonNull ReactiveMongoTemplate template;
|
||||||
private final Class<T> domainType;
|
@NonNull Class<T> domainType;
|
||||||
private final String collection;
|
String collection;
|
||||||
|
|
||||||
ReactiveInsertSupport(ReactiveMongoTemplate template, Class<T> domainType, String collection) {
|
|
||||||
|
|
||||||
this.template = template;
|
|
||||||
this.domainType = domainType;
|
|
||||||
this.collection = collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveInsertOperation.TerminatingInsert#one(java.lang.Object)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Mono<T> one(T object) {
|
public Mono<T> one(T object) {
|
||||||
|
|
||||||
@@ -67,6 +71,10 @@ class ReactiveInsertOperationSupport implements ReactiveInsertOperation {
|
|||||||
return template.insert(object, getCollectionName());
|
return template.insert(object, getCollectionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveInsertOperation.TerminatingInsert#all(java.util.Collection)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Flux<T> all(Collection<? extends T> objects) {
|
public Flux<T> all(Collection<? extends T> objects) {
|
||||||
|
|
||||||
@@ -75,6 +83,10 @@ class ReactiveInsertOperationSupport implements ReactiveInsertOperation {
|
|||||||
return template.insert(objects, getCollectionName());
|
return template.insert(objects, getCollectionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveInsertOperation.InsertWithCollection#inCollection(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ReactiveInsert<T> inCollection(String collection) {
|
public ReactiveInsert<T> inCollection(String collection) {
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
|
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
|
||||||
@@ -29,15 +31,12 @@ import org.springframework.util.StringUtils;
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class ReactiveMapReduceOperationSupport implements ReactiveMapReduceOperation {
|
class ReactiveMapReduceOperationSupport implements ReactiveMapReduceOperation {
|
||||||
|
|
||||||
private static final Query ALL_QUERY = new Query();
|
private static final Query ALL_QUERY = new Query();
|
||||||
|
|
||||||
private final ReactiveMongoTemplate template;
|
private final @NonNull ReactiveMongoTemplate template;
|
||||||
|
|
||||||
ReactiveMapReduceOperationSupport(ReactiveMongoTemplate template) {
|
|
||||||
this.template = template;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javascript)
|
* (non-Javascript)
|
||||||
|
|||||||
@@ -15,15 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import org.reactivestreams.Publisher;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.util.context.Context;
|
import reactor.util.context.Context;
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
import com.mongodb.reactivestreams.client.ClientSession;
|
import com.mongodb.reactivestreams.client.ClientSession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,7 +29,7 @@ import com.mongodb.reactivestreams.client.ClientSession;
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
* @see Mono#deferContextual(Function)
|
* @see Mono#subscriberContext()
|
||||||
* @see Context
|
* @see Context
|
||||||
*/
|
*/
|
||||||
public class ReactiveMongoContext {
|
public class ReactiveMongoContext {
|
||||||
@@ -50,14 +46,8 @@ public class ReactiveMongoContext {
|
|||||||
*/
|
*/
|
||||||
public static Mono<ClientSession> getSession() {
|
public static Mono<ClientSession> getSession() {
|
||||||
|
|
||||||
return Mono.deferContextual(ctx -> {
|
return Mono.subscriberContext().filter(ctx -> ctx.hasKey(SESSION_KEY))
|
||||||
|
.flatMap(ctx -> ctx.<Mono<ClientSession>> get(SESSION_KEY));
|
||||||
if (ctx.hasKey(SESSION_KEY)) {
|
|
||||||
return ctx.<Mono<ClientSession>> get(SESSION_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Mono.empty();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ import com.mongodb.reactivestreams.client.MongoCollection;
|
|||||||
* Implemented by {@link ReactiveMongoTemplate}. Not often used but a useful option for extensibility and testability
|
* Implemented by {@link ReactiveMongoTemplate}. Not often used but a useful option for extensibility and testability
|
||||||
* (as it can be easily mocked, stubbed, or be the target of a JDK proxy). Command execution using
|
* (as it can be easily mocked, stubbed, or be the target of a JDK proxy). Command execution using
|
||||||
* {@link ReactiveMongoOperations} is deferred until subscriber subscribes to the {@link Publisher}.
|
* {@link ReactiveMongoOperations} is deferred until subscriber subscribes to the {@link Publisher}.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>NOTE:</strong> Some operations cannot be executed within a MongoDB transaction. Please refer to the MongoDB
|
* <strong>NOTE:</strong> Some operations cannot be executed within a MongoDB transaction. Please refer to the MongoDB
|
||||||
* specific documentation to learn more about <a href="https://docs.mongodb.com/manual/core/transactions/">Multi
|
* specific documentation to learn more about <a href="https://docs.mongodb.com/manual/core/transactions/">Multi
|
||||||
* Document Transactions</a>.
|
* Document Transactions</a>.
|
||||||
@@ -121,7 +121,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a {@link ReactiveDatabaseCallback} translating any exceptions as necessary.
|
* Executes a {@link ReactiveDatabaseCallback} translating any exceptions as necessary.
|
||||||
* <br />
|
* <p/>
|
||||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||||
*
|
*
|
||||||
* @param action callback object that specifies the MongoDB actions to perform on the passed in DB instance. Must not
|
* @param action callback object that specifies the MongoDB actions to perform on the passed in DB instance. Must not
|
||||||
@@ -133,7 +133,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the given {@link ReactiveCollectionCallback} on the entity collection of the specified class.
|
* Executes the given {@link ReactiveCollectionCallback} on the entity collection of the specified class.
|
||||||
* <br />
|
* <p/>
|
||||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||||
*
|
*
|
||||||
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
|
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
|
||||||
@@ -145,7 +145,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the given {@link ReactiveCollectionCallback} on the collection of the given name.
|
* Executes the given {@link ReactiveCollectionCallback} on the collection of the given name.
|
||||||
* <br />
|
* <p/>
|
||||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||||
*
|
*
|
||||||
* @param collectionName the name of the collection that specifies which {@link MongoCollection} instance will be
|
* @param collectionName the name of the collection that specifies which {@link MongoCollection} instance will be
|
||||||
@@ -159,7 +159,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Obtain a {@link ClientSession session} bound instance of {@link SessionScoped} binding the {@link ClientSession}
|
* Obtain a {@link ClientSession session} bound instance of {@link SessionScoped} binding the {@link ClientSession}
|
||||||
* provided by the given {@link Supplier} to each and every command issued against MongoDB.
|
* provided by the given {@link Supplier} to each and every command issued against MongoDB.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle. Use
|
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle. Use
|
||||||
* {@link ReactiveSessionScoped#execute(ReactiveSessionCallback, Consumer)} to provide a hook for processing the
|
* {@link ReactiveSessionScoped#execute(ReactiveSessionCallback, Consumer)} to provide a hook for processing the
|
||||||
* {@link ClientSession} when done.
|
* {@link ClientSession} when done.
|
||||||
@@ -178,7 +178,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Obtain a {@link ClientSession session} bound instance of {@link SessionScoped} binding a new {@link ClientSession}
|
* Obtain a {@link ClientSession session} bound instance of {@link SessionScoped} binding a new {@link ClientSession}
|
||||||
* with given {@literal sessionOptions} to each and every command issued against MongoDB.
|
* with given {@literal sessionOptions} to each and every command issued against MongoDB.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle. Use
|
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle. Use
|
||||||
* {@link ReactiveSessionScoped#execute(ReactiveSessionCallback, Consumer)} to provide a hook for processing the
|
* {@link ReactiveSessionScoped#execute(ReactiveSessionCallback, Consumer)} to provide a hook for processing the
|
||||||
* {@link ClientSession} when done.
|
* {@link ClientSession} when done.
|
||||||
@@ -192,7 +192,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Obtain a {@link ClientSession session} bound instance of {@link ReactiveSessionScoped} binding the
|
* Obtain a {@link ClientSession session} bound instance of {@link ReactiveSessionScoped} binding the
|
||||||
* {@link ClientSession} provided by the given {@link Publisher} to each and every command issued against MongoDB.
|
* {@link ClientSession} provided by the given {@link Publisher} to each and every command issued against MongoDB.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle. Use
|
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle. Use
|
||||||
* {@link ReactiveSessionScoped#execute(ReactiveSessionCallback, Consumer)} to provide a hook for processing the
|
* {@link ReactiveSessionScoped#execute(ReactiveSessionCallback, Consumer)} to provide a hook for processing the
|
||||||
* {@link ClientSession} when done.
|
* {@link ClientSession} when done.
|
||||||
@@ -205,7 +205,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain a {@link ClientSession} bound instance of {@link ReactiveMongoOperations}.
|
* Obtain a {@link ClientSession} bound instance of {@link ReactiveMongoOperations}.
|
||||||
* <br />
|
* <p />
|
||||||
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle.
|
* <strong>Note:</strong> It is up to the caller to manage the {@link ClientSession} lifecycle.
|
||||||
*
|
*
|
||||||
* @param session must not be {@literal null}.
|
* @param session must not be {@literal null}.
|
||||||
@@ -218,7 +218,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* Initiate a new {@link ClientSession} and obtain a {@link ClientSession session} bound instance of
|
* Initiate a new {@link ClientSession} and obtain a {@link ClientSession session} bound instance of
|
||||||
* {@link ReactiveSessionScoped}. Starts the transaction and adds the {@link ClientSession} to each and every command
|
* {@link ReactiveSessionScoped}. Starts the transaction and adds the {@link ClientSession} to each and every command
|
||||||
* issued against MongoDB.
|
* issued against MongoDB.
|
||||||
* <br />
|
* <p/>
|
||||||
* Each {@link ReactiveSessionScoped#execute(ReactiveSessionCallback) execution} initiates a new managed transaction
|
* Each {@link ReactiveSessionScoped#execute(ReactiveSessionCallback) execution} initiates a new managed transaction
|
||||||
* that is {@link ClientSession#commitTransaction() committed} on success. Transactions are
|
* that is {@link ClientSession#commitTransaction() committed} on success. Transactions are
|
||||||
* {@link ClientSession#abortTransaction() rolled back} upon errors.
|
* {@link ClientSession#abortTransaction() rolled back} upon errors.
|
||||||
@@ -233,7 +233,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* Obtain a {@link ClientSession session} bound instance of {@link ReactiveSessionScoped}, start the transaction and
|
* Obtain a {@link ClientSession session} bound instance of {@link ReactiveSessionScoped}, start the transaction and
|
||||||
* bind the {@link ClientSession} provided by the given {@link Publisher} to each and every command issued against
|
* bind the {@link ClientSession} provided by the given {@link Publisher} to each and every command issued against
|
||||||
* MongoDB.
|
* MongoDB.
|
||||||
* <br />
|
* <p/>
|
||||||
* Each {@link ReactiveSessionScoped#execute(ReactiveSessionCallback) execution} initiates a new managed transaction
|
* Each {@link ReactiveSessionScoped#execute(ReactiveSessionCallback) execution} initiates a new managed transaction
|
||||||
* that is {@link ClientSession#commitTransaction() committed} on success. Transactions are
|
* that is {@link ClientSession#commitTransaction() committed} on success. Transactions are
|
||||||
* {@link ClientSession#abortTransaction() rolled back} upon errors.
|
* {@link ClientSession#abortTransaction() rolled back} upon errors.
|
||||||
@@ -293,7 +293,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* created on first interaction with the server. Collections can be explicitly created via
|
* created on first interaction with the server. Collections can be explicitly created via
|
||||||
* {@link #createCollection(Class)}. Please make sure to check if the collection {@link #collectionExists(Class)
|
* {@link #createCollection(Class)}. Please make sure to check if the collection {@link #collectionExists(Class)
|
||||||
* exists} first.
|
* exists} first.
|
||||||
* <br />
|
* <p/>
|
||||||
* Translate any exceptions as necessary.
|
* Translate any exceptions as necessary.
|
||||||
*
|
*
|
||||||
* @param collectionName name of the collection.
|
* @param collectionName name of the collection.
|
||||||
@@ -303,7 +303,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if a collection with a name indicated by the entity class exists.
|
* Check to see if a collection with a name indicated by the entity class exists.
|
||||||
* <br />
|
* <p/>
|
||||||
* Translate any exceptions as necessary.
|
* Translate any exceptions as necessary.
|
||||||
*
|
*
|
||||||
* @param entityClass class that determines the name of the collection. Must not be {@literal null}.
|
* @param entityClass class that determines the name of the collection. Must not be {@literal null}.
|
||||||
@@ -313,7 +313,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if a collection with a given name exists.
|
* Check to see if a collection with a given name exists.
|
||||||
* <br />
|
* <p/>
|
||||||
* Translate any exceptions as necessary.
|
* Translate any exceptions as necessary.
|
||||||
*
|
*
|
||||||
* @param collectionName name of the collection. Must not be {@literal null}.
|
* @param collectionName name of the collection. Must not be {@literal null}.
|
||||||
@@ -323,7 +323,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop the collection with the name indicated by the entity class.
|
* Drop the collection with the name indicated by the entity class.
|
||||||
* <br />
|
* <p/>
|
||||||
* Translate any exceptions as necessary.
|
* Translate any exceptions as necessary.
|
||||||
*
|
*
|
||||||
* @param entityClass class that determines the collection to drop/delete. Must not be {@literal null}.
|
* @param entityClass class that determines the collection to drop/delete. Must not be {@literal null}.
|
||||||
@@ -332,7 +332,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop the collection with the given name.
|
* Drop the collection with the given name.
|
||||||
* <br />
|
* <p/>
|
||||||
* Translate any exceptions as necessary.
|
* Translate any exceptions as necessary.
|
||||||
*
|
*
|
||||||
* @param collectionName name of the collection to drop/delete.
|
* @param collectionName name of the collection to drop/delete.
|
||||||
@@ -341,10 +341,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Query for a {@link Flux} of objects of type T from the collection used by the entity class.
|
* Query for a {@link Flux} of objects of type T from the collection used by the entity class.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
||||||
* to map objects since the test for class type is done in the client and not on the server.
|
* to map objects since the test for class type is done in the client and not on the server.
|
||||||
*
|
*
|
||||||
@@ -355,10 +355,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Query for a {@link Flux} of objects of type T from the specified collection.
|
* Query for a {@link Flux} of objects of type T from the specified collection.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
||||||
* to map objects since the test for class type is done in the client and not on the server.
|
* to map objects since the test for class type is done in the client and not on the server.
|
||||||
*
|
*
|
||||||
@@ -371,10 +371,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Map the results of an ad-hoc query on the collection for the entity class to a single instance of an object of the
|
* Map the results of an ad-hoc query on the collection for the entity class to a single instance of an object of the
|
||||||
* specified type.
|
* specified type.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -388,10 +388,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified
|
* Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified
|
||||||
* type.
|
* type.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -435,10 +435,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Map the results of an ad-hoc query on the collection for the entity class to a {@link Flux} of the specified type.
|
* Map the results of an ad-hoc query on the collection for the entity class to a {@link Flux} of the specified type.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -451,10 +451,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Map the results of an ad-hoc query on the specified collection to a {@link Flux} of the specified type.
|
* Map the results of an ad-hoc query on the specified collection to a {@link Flux} of the specified type.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -566,10 +566,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute an aggregation operation.
|
* Execute an aggregation operation.
|
||||||
* <br />
|
* <p/>
|
||||||
* The raw results will be mapped to the given entity class and are returned as stream. The name of the
|
* The raw results will be mapped to the given entity class and are returned as stream. The name of the
|
||||||
* inputCollection is derived from the {@link TypedAggregation#getInputType() aggregation input type}.
|
* inputCollection is derived from the {@link TypedAggregation#getInputType() aggregation input type}.
|
||||||
* <br />
|
* <p/>
|
||||||
* Aggregation streaming cannot be used with {@link AggregationOptions#isExplain() aggregation explain} nor with
|
* Aggregation streaming cannot be used with {@link AggregationOptions#isExplain() aggregation explain} nor with
|
||||||
* {@link AggregationOptions#getCursorBatchSize()}. Enabling explanation mode or setting batch size cause
|
* {@link AggregationOptions#getCursorBatchSize()}. Enabling explanation mode or setting batch size cause
|
||||||
* {@link IllegalArgumentException}.
|
* {@link IllegalArgumentException}.
|
||||||
@@ -584,10 +584,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute an aggregation operation.
|
* Execute an aggregation operation.
|
||||||
* <br />
|
* <p/>
|
||||||
* The raw results will be mapped to the given {@code ouputType}. The name of the inputCollection is derived from the
|
* The raw results will be mapped to the given {@code ouputType}. The name of the inputCollection is derived from the
|
||||||
* {@code inputType}.
|
* {@code inputType}.
|
||||||
* <br />
|
* <p/>
|
||||||
* Aggregation streaming cannot be used with {@link AggregationOptions#isExplain() aggregation explain} nor with
|
* Aggregation streaming cannot be used with {@link AggregationOptions#isExplain() aggregation explain} nor with
|
||||||
* {@link AggregationOptions#getCursorBatchSize()}. Enabling explanation mode or setting batch size cause
|
* {@link AggregationOptions#getCursorBatchSize()}. Enabling explanation mode or setting batch size cause
|
||||||
* {@link IllegalArgumentException}.
|
* {@link IllegalArgumentException}.
|
||||||
@@ -604,9 +604,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute an aggregation operation.
|
* Execute an aggregation operation.
|
||||||
* <br />
|
* <p/>
|
||||||
* The raw results will be mapped to the given entity class.
|
* The raw results will be mapped to the given entity class.
|
||||||
* <br />
|
* <p/>
|
||||||
* Aggregation streaming cannot be used with {@link AggregationOptions#isExplain() aggregation explain} nor with
|
* Aggregation streaming cannot be used with {@link AggregationOptions#isExplain() aggregation explain} nor with
|
||||||
* {@link AggregationOptions#getCursorBatchSize()}. Enabling explanation mode or setting batch size cause
|
* {@link AggregationOptions#getCursorBatchSize()}. Enabling explanation mode or setting batch size cause
|
||||||
* {@link IllegalArgumentException}.
|
* {@link IllegalArgumentException}.
|
||||||
@@ -676,7 +676,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
<T> Flux<GeoResult<T>> geoNear(NearQuery near, Class<T> entityClass, String collectionName);
|
<T> Flux<GeoResult<T>> geoNear(NearQuery near, Class<T> entityClass, String collectionName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify</a>
|
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify<a/>
|
||||||
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
|
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
|
||||||
*
|
*
|
||||||
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
|
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
|
||||||
@@ -691,7 +691,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
<T> Mono<T> findAndModify(Query query, UpdateDefinition update, Class<T> entityClass);
|
<T> Mono<T> findAndModify(Query query, UpdateDefinition update, Class<T> entityClass);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify</a>
|
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify<a/>
|
||||||
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
|
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
|
||||||
*
|
*
|
||||||
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
|
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
|
||||||
@@ -707,7 +707,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
<T> Mono<T> findAndModify(Query query, UpdateDefinition update, Class<T> entityClass, String collectionName);
|
<T> Mono<T> findAndModify(Query query, UpdateDefinition update, Class<T> entityClass, String collectionName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify</a>
|
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify<a/>
|
||||||
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
|
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
|
||||||
* {@link FindAndModifyOptions} into account.
|
* {@link FindAndModifyOptions} into account.
|
||||||
*
|
*
|
||||||
@@ -725,7 +725,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
<T> Mono<T> findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class<T> entityClass);
|
<T> Mono<T> findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions options, Class<T> entityClass);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify</a>
|
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify<a/>
|
||||||
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
|
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
|
||||||
* {@link FindAndModifyOptions} into account.
|
* {@link FindAndModifyOptions} into account.
|
||||||
*
|
*
|
||||||
@@ -746,7 +746,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement}
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement}
|
||||||
* document. <br />
|
* document. <br />
|
||||||
* Options are defaulted to {@link FindAndReplaceOptions#empty()}. <br />
|
* Options are defaulted to {@link FindAndReplaceOptions#empty()}. <br />
|
||||||
@@ -764,7 +764,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement}
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement}
|
||||||
* document. <br />
|
* document. <br />
|
||||||
* Options are defaulted to {@link FindAndReplaceOptions#empty()}. <br />
|
* Options are defaulted to {@link FindAndReplaceOptions#empty()}. <br />
|
||||||
@@ -783,7 +783,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
||||||
* taking {@link FindAndReplaceOptions} into account. <br />
|
* taking {@link FindAndReplaceOptions} into account. <br />
|
||||||
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
||||||
@@ -803,7 +803,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
||||||
* taking {@link FindAndReplaceOptions} into account. <br />
|
* taking {@link FindAndReplaceOptions} into account. <br />
|
||||||
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
||||||
@@ -825,7 +825,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
||||||
* taking {@link FindAndReplaceOptions} into account. <br />
|
* taking {@link FindAndReplaceOptions} into account. <br />
|
||||||
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
||||||
@@ -849,7 +849,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
||||||
* taking {@link FindAndReplaceOptions} into account. <br />
|
* taking {@link FindAndReplaceOptions} into account. <br />
|
||||||
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
||||||
@@ -876,7 +876,7 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers
|
* Triggers
|
||||||
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace</a>
|
* <a href="https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndReplace/">findOneAndReplace<a/>
|
||||||
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
* to replace a single document matching {@link Criteria} of given {@link Query} with the {@code replacement} document
|
||||||
* taking {@link FindAndReplaceOptions} into account. <br />
|
* taking {@link FindAndReplaceOptions} into account. <br />
|
||||||
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
|
||||||
@@ -902,9 +902,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* Map the results of an ad-hoc query on the collection for the entity type to a single instance of an object of the
|
* Map the results of an ad-hoc query on the collection for the entity type to a single instance of an object of the
|
||||||
* specified type. The first document that matches the query is returned and also removed from the collection in the
|
* specified type. The first document that matches the query is returned and also removed from the collection in the
|
||||||
* database.
|
* database.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}.
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -918,10 +918,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified
|
* Map the results of an ad-hoc query on the specified collection to a single instance of an object of the specified
|
||||||
* type. The first document that matches the query is returned and also removed from the collection in the database.
|
* type. The first document that matches the query is returned and also removed from the collection in the database.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -940,12 +940,6 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
||||||
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
||||||
* count all matches.
|
* count all matches.
|
||||||
* <br />
|
|
||||||
* This method uses an
|
|
||||||
* {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
|
|
||||||
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
|
|
||||||
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
|
|
||||||
* {@link #estimatedCount(Class)} for empty queries instead.
|
|
||||||
*
|
*
|
||||||
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
|
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
|
||||||
* {@literal null}.
|
* {@literal null}.
|
||||||
@@ -962,12 +956,6 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
||||||
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
||||||
* count all matches.
|
* count all matches.
|
||||||
* <br />
|
|
||||||
* This method uses an
|
|
||||||
* {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
|
|
||||||
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
|
|
||||||
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
|
|
||||||
* {@link #estimatedCount(String)} for empty queries instead.
|
|
||||||
*
|
*
|
||||||
* @param query the {@link Query} class that specifies the criteria used to find documents.
|
* @param query the {@link Query} class that specifies the criteria used to find documents.
|
||||||
* @param collectionName must not be {@literal null} or empty.
|
* @param collectionName must not be {@literal null} or empty.
|
||||||
@@ -983,12 +971,6 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
* influence on the resulting number of documents found as those values are passed on to the server and potentially
|
||||||
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
|
||||||
* count all matches.
|
* count all matches.
|
||||||
* <br />
|
|
||||||
* This method uses an
|
|
||||||
* {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
|
|
||||||
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
|
|
||||||
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
|
|
||||||
* {@link #estimatedCount(String)} for empty queries instead.
|
|
||||||
*
|
*
|
||||||
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
|
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
|
||||||
* {@literal null}.
|
* {@literal null}.
|
||||||
@@ -998,70 +980,36 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
*/
|
*/
|
||||||
Mono<Long> count(Query query, @Nullable Class<?> entityClass, String collectionName);
|
Mono<Long> count(Query query, @Nullable Class<?> entityClass, String collectionName);
|
||||||
|
|
||||||
/**
|
|
||||||
* Estimate the number of documents, in the collection {@link #getCollectionName(Class) identified by the given type},
|
|
||||||
* based on collection statistics.
|
|
||||||
* <br />
|
|
||||||
* Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside
|
|
||||||
* transactions.
|
|
||||||
*
|
|
||||||
* @param entityClass must not be {@literal null}.
|
|
||||||
* @return a {@link Mono} emitting the estimated number of documents.
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
default Mono<Long> estimatedCount(Class<?> entityClass) {
|
|
||||||
|
|
||||||
Assert.notNull(entityClass, "Entity class must not be null!");
|
|
||||||
return estimatedCount(getCollectionName(entityClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Estimate the number of documents in the given collection based on collection statistics.
|
|
||||||
* <br />
|
|
||||||
* Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside
|
|
||||||
* transactions.
|
|
||||||
*
|
|
||||||
* @param collectionName must not be {@literal null}.
|
|
||||||
* @return a {@link Mono} emitting the estimated number of documents.
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
Mono<Long> estimatedCount(String collectionName);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert the object into the collection for the entity type of the object to save.
|
* Insert the object into the collection for the entity type of the object to save.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}.
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
* 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
|
* 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
|
* 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
|
* <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation" > Spring's
|
||||||
* Type Conversion"</a> for more details.
|
* Type Conversion"</a> for more details.
|
||||||
* <br />
|
* <p/>
|
||||||
|
* <p/>
|
||||||
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
||||||
* <br />
|
|
||||||
* The {@code objectToSave} must not be collection-like.
|
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
* @return the inserted object.
|
* @return the inserted object.
|
||||||
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
|
|
||||||
*/
|
*/
|
||||||
<T> Mono<T> insert(T objectToSave);
|
<T> Mono<T> insert(T objectToSave);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert the object into the specified collection.
|
* Insert the object into the specified collection.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
||||||
* <br />
|
|
||||||
* The {@code objectToSave} must not be collection-like.
|
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
|
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
|
||||||
* @return the inserted object.
|
* @return the inserted object.
|
||||||
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
|
|
||||||
*/
|
*/
|
||||||
<T> Mono<T> insert(T objectToSave, String collectionName);
|
<T> Mono<T> insert(T objectToSave, String collectionName);
|
||||||
|
|
||||||
@@ -1094,15 +1042,16 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert the object into the collection for the entity type of the object to save.
|
* Insert the object into the collection for the entity type of the object to save.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}.
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
* 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
|
* 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
|
* 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
|
* <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation" > Spring's
|
||||||
* Type Conversion"</a> for more details.
|
* Type Conversion"</a> for more details.
|
||||||
* <br />
|
* <p/>
|
||||||
|
* <p/>
|
||||||
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
@@ -1140,54 +1089,52 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Save the object to the collection for the entity type of the object to save. This will perform an insert if the
|
* Save the object to the collection for the entity type of the object to save. This will perform an insert if the
|
||||||
* object is not already present, that is an 'upsert'.
|
* object is not already present, that is an 'upsert'.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
* 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
|
* 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
|
* 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
|
* <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation" > Spring's
|
||||||
* Type Conversion"</a> for more details.
|
* Type Conversion"</a> for more details.
|
||||||
* <br />
|
|
||||||
* The {@code objectToSave} must not be collection-like.
|
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
* @return the saved object.
|
* @return the saved object.
|
||||||
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
|
|
||||||
*/
|
*/
|
||||||
<T> Mono<T> save(T objectToSave);
|
<T> Mono<T> save(T objectToSave);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the object to the specified collection. This will perform an insert if the object is not already present, that
|
* Save the object to the specified collection. This will perform an insert if the object is not already present, that
|
||||||
* is an 'upsert'.
|
* is an 'upsert'.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
* 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
|
* 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.
|
* property type will be handled by Spring's BeanWrapper class that leverages Type Conversion API. See <a
|
||||||
* See <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation">Spring's Type Conversion</a> for more details.
|
* https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation">Spring's Type
|
||||||
|
* Conversion"</a> for more details.
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
|
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
|
||||||
* @return the saved object.
|
* @return the saved object.
|
||||||
* @throws IllegalArgumentException in case the {@code objectToSave} is collection-like.
|
|
||||||
*/
|
*/
|
||||||
<T> Mono<T> save(T objectToSave, String collectionName);
|
<T> Mono<T> save(T objectToSave, String collectionName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the object to the collection for the entity type of the object to save. This will perform an insert if the
|
* Save the object to the collection for the entity type of the object to save. This will perform an insert if the
|
||||||
* object is not already present, that is an 'upsert'.
|
* object is not already present, that is an 'upsert'.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
* 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
|
* 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.
|
* property type will be handled by Spring's BeanWrapper class that leverages Type Conversion API. See
|
||||||
* See <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation"> Spring's Type Conversion</a> for more details.
|
* <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation" > Spring's
|
||||||
|
* Type Conversion"</a> for more details.
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
* @return the saved object.
|
* @return the saved object.
|
||||||
@@ -1197,16 +1144,17 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
/**
|
/**
|
||||||
* Save the object to the specified collection. This will perform an insert if the object is not already present, that
|
* Save the object to the specified collection. This will perform an insert if the object is not already present, that
|
||||||
* is an 'upsert'.
|
* is an 'upsert'.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* If your object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
* 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
|
* 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.
|
* property type will be handled by Spring's BeanWrapper class that leverages Type Conversion API. See <a
|
||||||
* See <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation">Spring's Type Conversion</a> for more details.
|
* https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#validation">Spring's Type
|
||||||
|
* Conversion"</a> for more details.
|
||||||
*
|
*
|
||||||
* @param objectToSave the object to store in the collReactiveMongoOperationsection. Must not be {@literal null}.
|
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
|
||||||
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
|
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
|
||||||
* @return the saved object.
|
* @return the saved object.
|
||||||
*/
|
*/
|
||||||
@@ -1478,10 +1426,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* type. The stream uses a {@link com.mongodb.CursorType#TailableAwait tailable} cursor that may be an infinite
|
* type. The stream uses a {@link com.mongodb.CursorType#TailableAwait tailable} cursor that may be an infinite
|
||||||
* stream. The stream will not be completed unless the {@link org.reactivestreams.Subscription} is
|
* stream. The stream will not be completed unless the {@link org.reactivestreams.Subscription} is
|
||||||
* {@link Subscription#cancel() canceled}.
|
* {@link Subscription#cancel() canceled}.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -1497,10 +1445,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* type. The stream uses a {@link com.mongodb.CursorType#TailableAwait tailable} cursor that may be an infinite
|
* type. The stream uses a {@link com.mongodb.CursorType#TailableAwait tailable} cursor that may be an infinite
|
||||||
* stream. The stream will not be completed unless the {@link org.reactivestreams.Subscription} is
|
* stream. The stream will not be completed unless the {@link org.reactivestreams.Subscription} is
|
||||||
* {@link Subscription#cancel() canceled}.
|
* {@link Subscription#cancel() canceled}.
|
||||||
* <br />
|
* <p/>
|
||||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||||
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
* configured otherwise, an instance of {@link MappingMongoConverter} will be used.
|
||||||
* <br />
|
* <p/>
|
||||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||||
* feature rich {@link Query}.
|
* feature rich {@link Query}.
|
||||||
*
|
*
|
||||||
@@ -1517,10 +1465,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* the configured default database via the reactive infrastructure. Use the optional provided {@link Aggregation} to
|
* the configured default database via the reactive infrastructure. Use the optional provided {@link Aggregation} to
|
||||||
* filter events. The stream will not be completed unless the {@link org.reactivestreams.Subscription} is
|
* filter events. The stream will not be completed unless the {@link org.reactivestreams.Subscription} is
|
||||||
* {@link Subscription#cancel() canceled}.
|
* {@link Subscription#cancel() canceled}.
|
||||||
* <br />
|
* <p />
|
||||||
* The {@link ChangeStreamEvent#getBody()} is mapped to the {@literal resultType} while the
|
* The {@link ChangeStreamEvent#getBody()} is mapped to the {@literal resultType} while the
|
||||||
* {@link ChangeStreamEvent#getRaw()} contains the unmodified payload.
|
* {@link ChangeStreamEvent#getRaw()} contains the unmodified payload.
|
||||||
* <br />
|
* <p />
|
||||||
* Use {@link ChangeStreamOptions} to set arguments like {@link ChangeStreamOptions#getResumeToken() the resumseToken}
|
* Use {@link ChangeStreamOptions} to set arguments like {@link ChangeStreamOptions#getResumeToken() the resumseToken}
|
||||||
* for resuming change streams.
|
* for resuming change streams.
|
||||||
*
|
*
|
||||||
@@ -1541,10 +1489,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* the given collection via the reactive infrastructure. Use the optional provided {@link Aggregation} to filter
|
* the given collection via the reactive infrastructure. Use the optional provided {@link Aggregation} to filter
|
||||||
* events. The stream will not be completed unless the {@link org.reactivestreams.Subscription} is
|
* events. The stream will not be completed unless the {@link org.reactivestreams.Subscription} is
|
||||||
* {@link Subscription#cancel() canceled}.
|
* {@link Subscription#cancel() canceled}.
|
||||||
* <br />
|
* <p />
|
||||||
* The {@link ChangeStreamEvent#getBody()} is mapped to the {@literal resultType} while the
|
* The {@link ChangeStreamEvent#getBody()} is mapped to the {@literal resultType} while the
|
||||||
* {@link ChangeStreamEvent#getRaw()} contains the unmodified payload.
|
* {@link ChangeStreamEvent#getRaw()} contains the unmodified payload.
|
||||||
* <br />
|
* <p />
|
||||||
* Use {@link ChangeStreamOptions} to set arguments like {@link ChangeStreamOptions#getResumeToken() the resumseToken}
|
* Use {@link ChangeStreamOptions} to set arguments like {@link ChangeStreamOptions#getResumeToken() the resumseToken}
|
||||||
* for resuming change streams.
|
* for resuming change streams.
|
||||||
*
|
*
|
||||||
@@ -1566,10 +1514,10 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
|||||||
* Subscribe to a MongoDB <a href="https://docs.mongodb.com/manual/changeStreams/">Change Stream</a> via the reactive
|
* Subscribe to a MongoDB <a href="https://docs.mongodb.com/manual/changeStreams/">Change Stream</a> via the reactive
|
||||||
* infrastructure. Use the optional provided {@link Aggregation} to filter events. The stream will not be completed
|
* infrastructure. Use the optional provided {@link Aggregation} to filter events. The stream will not be completed
|
||||||
* unless the {@link org.reactivestreams.Subscription} is {@link Subscription#cancel() canceled}.
|
* unless the {@link org.reactivestreams.Subscription} is {@link Subscription#cancel() canceled}.
|
||||||
* <br />
|
* <p />
|
||||||
* The {@link ChangeStreamEvent#getBody()} is mapped to the {@literal resultType} while the
|
* The {@link ChangeStreamEvent#getBody()} is mapped to the {@literal resultType} while the
|
||||||
* {@link ChangeStreamEvent#getRaw()} contains the unmodified payload.
|
* {@link ChangeStreamEvent#getRaw()} contains the unmodified payload.
|
||||||
* <br />
|
* <p />
|
||||||
* Use {@link ChangeStreamOptions} to set arguments like {@link ChangeStreamOptions#getResumeToken() the resumseToken}
|
* Use {@link ChangeStreamOptions} to set arguments like {@link ChangeStreamOptions#getResumeToken() the resumseToken}
|
||||||
* for resuming change streams.
|
* for resuming change streams.
|
||||||
*
|
*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
@@ -31,16 +35,17 @@ import com.mongodb.client.result.DeleteResult;
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
class ReactiveRemoveOperationSupport implements ReactiveRemoveOperation {
|
class ReactiveRemoveOperationSupport implements ReactiveRemoveOperation {
|
||||||
|
|
||||||
private static final Query ALL_QUERY = new Query();
|
private static final Query ALL_QUERY = new Query();
|
||||||
|
|
||||||
private final ReactiveMongoTemplate tempate;
|
private final @NonNull ReactiveMongoTemplate tempate;
|
||||||
|
|
||||||
ReactiveRemoveOperationSupport(ReactiveMongoTemplate tempate) {
|
|
||||||
this.tempate = tempate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveRemoveOperation#remove(java.lang.Class)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T> ReactiveRemove<T> remove(Class<T> domainType) {
|
public <T> ReactiveRemove<T> remove(Class<T> domainType) {
|
||||||
|
|
||||||
@@ -49,21 +54,19 @@ class ReactiveRemoveOperationSupport implements ReactiveRemoveOperation {
|
|||||||
return new ReactiveRemoveSupport<>(tempate, domainType, ALL_QUERY, null);
|
return new ReactiveRemoveSupport<>(tempate, domainType, ALL_QUERY, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||||
static class ReactiveRemoveSupport<T> implements ReactiveRemove<T>, RemoveWithCollection<T> {
|
static class ReactiveRemoveSupport<T> implements ReactiveRemove<T>, RemoveWithCollection<T> {
|
||||||
|
|
||||||
private final ReactiveMongoTemplate template;
|
@NonNull ReactiveMongoTemplate template;
|
||||||
private final Class<T> domainType;
|
@NonNull Class<T> domainType;
|
||||||
private final Query query;
|
Query query;
|
||||||
private final String collection;
|
String collection;
|
||||||
|
|
||||||
ReactiveRemoveSupport(ReactiveMongoTemplate template, Class<T> domainType, Query query, String collection) {
|
|
||||||
|
|
||||||
this.template = template;
|
|
||||||
this.domainType = domainType;
|
|
||||||
this.query = query;
|
|
||||||
this.collection = collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveRemoveOperation.RemoveWithCollection#inCollection(String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public RemoveWithQuery<T> inCollection(String collection) {
|
public RemoveWithQuery<T> inCollection(String collection) {
|
||||||
|
|
||||||
@@ -72,6 +75,10 @@ class ReactiveRemoveOperationSupport implements ReactiveRemoveOperation {
|
|||||||
return new ReactiveRemoveSupport<>(template, domainType, query, collection);
|
return new ReactiveRemoveSupport<>(template, domainType, query, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveRemoveOperation.RemoveWithQuery#matching(org.springframework.data.mongodb.core.Query)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TerminatingRemove<T> matching(Query query) {
|
public TerminatingRemove<T> matching(Query query) {
|
||||||
|
|
||||||
@@ -80,6 +87,10 @@ class ReactiveRemoveOperationSupport implements ReactiveRemoveOperation {
|
|||||||
return new ReactiveRemoveSupport<>(template, domainType, query, collection);
|
return new ReactiveRemoveSupport<>(template, domainType, query, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveRemoveOperation.TerminatingRemove#all()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Mono<DeleteResult> all() {
|
public Mono<DeleteResult> all() {
|
||||||
|
|
||||||
@@ -88,6 +99,10 @@ class ReactiveRemoveOperationSupport implements ReactiveRemoveOperation {
|
|||||||
return template.doRemove(collectionName, query, domainType);
|
return template.doRemove(collectionName, query, domainType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mongodb.core.ReactiveRemoveOperation.TerminatingRemove#findAndRemove()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Flux<T> findAndRemove() {
|
public Flux<T> findAndRemove() {
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public interface ReactiveSessionCallback<T> {
|
|||||||
/**
|
/**
|
||||||
* Execute operations against a MongoDB instance via session bound {@link ReactiveMongoOperations}. The session is
|
* Execute operations against a MongoDB instance via session bound {@link ReactiveMongoOperations}. The session is
|
||||||
* inferred directly into the operation so that no further interaction is necessary.
|
* inferred directly into the operation so that no further interaction is necessary.
|
||||||
* <br />
|
* <p />
|
||||||
* Please note that only Spring Data-specific abstractions like {@link ReactiveMongoOperations#find(Query, Class)} and
|
* Please note that only Spring Data-specific abstractions like {@link ReactiveMongoOperations#find(Query, Class)} and
|
||||||
* others are enhanced with the {@link com.mongodb.session.ClientSession}. When obtaining plain MongoDB gateway
|
* others are enhanced with the {@link com.mongodb.session.ClientSession}. When obtaining plain MongoDB gateway
|
||||||
* objects like {@link com.mongodb.reactivestreams.client.MongoCollection} or
|
* objects like {@link com.mongodb.reactivestreams.client.MongoCollection} or
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public interface ReactiveSessionScoped {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the given {@link ReactiveSessionCallback} within the {@link com.mongodb.session.ClientSession}.
|
* Executes the given {@link ReactiveSessionCallback} within the {@link com.mongodb.session.ClientSession}.
|
||||||
* <br />
|
* <p/>
|
||||||
* It is up to the caller to make sure the {@link com.mongodb.session.ClientSession} is {@link ClientSession#close()
|
* It is up to the caller to make sure the {@link com.mongodb.session.ClientSession} is {@link ClientSession#close()
|
||||||
* closed} when done.
|
* closed} when done.
|
||||||
*
|
*
|
||||||
@@ -47,7 +47,7 @@ public interface ReactiveSessionScoped {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the given {@link ReactiveSessionCallback} within the {@link com.mongodb.session.ClientSession}.
|
* Executes the given {@link ReactiveSessionCallback} within the {@link com.mongodb.session.ClientSession}.
|
||||||
* <br />
|
* <p/>
|
||||||
* It is up to the caller to make sure the {@link com.mongodb.session.ClientSession} is {@link ClientSession#close()
|
* It is up to the caller to make sure the {@link com.mongodb.session.ClientSession} is {@link ClientSession#close()
|
||||||
* closed} when done.
|
* closed} when done.
|
||||||
*
|
*
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user