diff --git a/.github/dco.yml b/.github/dco.yml
new file mode 100644
index 000000000..0c4b142e9
--- /dev/null
+++ b/.github/dco.yml
@@ -0,0 +1,2 @@
+require:
+ members: false
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 000000000..ecab23c37
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,73 @@
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ 'main', '1.0.x', '1.1.x', '1.2.x', '1.3.x', '1.4.x', '1.5.x', '2.0.x', '2.1.x', '2.2.x', '3.0.x', '3.1.x', '3.2.x', '4.0.x', '4.1.x', '4.2.x', '4.3.x', '4.4.x', '5.0.x', '5.1.x' ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ 'main' ]
+ schedule:
+ - cron: '59 19 * * 2'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
+ timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'java' ]
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
+ # Use only 'java' to analyze code written in Java, Kotlin or both
+ # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
+ # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - if: matrix.language == 'java'
+ name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'adopt'
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+
+ # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
+ # queries: security-extended,security-and-quality
+
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v2
+
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
+
+ # If the Autobuild fails above, remove it and uncomment the following three lines.
+ # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
+
+ # - run: |
+ # echo "Run, Build Application using script"
+ # ./location_of_script_within_repo/buildscript.sh
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
+ with:
+ category: "/language:${{matrix.language}}"
diff --git a/.gitignore b/.gitignore
index adadb46a7..78662375b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,10 @@ target/
*.iml
.idea
+
+build/
+node_modules
+node
+package-lock.json
+
+.mvn/.develocity
diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml
new file mode 100644
index 000000000..e0857eaa2
--- /dev/null
+++ b/.mvn/extensions.xml
@@ -0,0 +1,8 @@
+
+
+
+ io.spring.develocity.conventions
+ develocity-conventions-maven-extension
+ 0.0.22
+
+
diff --git a/.mvn/jvm.config b/.mvn/jvm.config
new file mode 100644
index 000000000..e27f6e8f5
--- /dev/null
+++ b/.mvn/jvm.config
@@ -0,0 +1,14 @@
+--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
+--add-opens=java.base/java.util=ALL-UNNAMED
+--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
+--add-opens=java.base/java.text=ALL-UNNAMED
+--add-opens=java.desktop/java.awt.font=ALL-UNNAMED
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index ef8617c5f..a54be2b1d 100755
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -1,2 +1,2 @@
-#Mon Jan 30 10:48:22 CET 2023
-distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
+#Thu Jul 17 13:59:56 CEST 2025
+distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
diff --git a/Jenkinsfile b/Jenkinsfile
index 3b6378fca..d1245b878 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,7 +1,7 @@
def p = [:]
node {
- checkout scm
- p = readProperties interpolate: true, file: 'ci/pipeline.properties'
+ checkout scm
+ p = readProperties interpolate: true, file: 'ci/pipeline.properties'
}
pipeline {
@@ -18,7 +18,7 @@ pipeline {
}
stages {
- stage("test: baseline (Java 17)") {
+ stage("test: baseline (main)") {
when {
beforeAgent(true)
anyOf {
@@ -31,16 +31,47 @@ pipeline {
}
options { timeout(time: 30, unit: 'MINUTES') }
environment {
- DOCKER_HUB = credentials("${p['docker.credentials']}")
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
+ DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
}
steps {
script {
- docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
+ docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) {
- sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}"
- sh 'PROFILE=ci ci/test.sh'
- sh "ci/clean.sh"
+ sh "PROFILE=ci JENKINS_USER_NAME=${p['jenkins.user.name']} ci/test.sh"
+ sh "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
+ }
+ }
+ }
+ }
+ }
+
+ stage("Test other configurations") {
+ when {
+ beforeAgent(true)
+ allOf {
+ branch(pattern: "main|(\\d\\.\\d\\.x)", comparator: "REGEXP")
+ not { triggeredBy 'UpstreamCause' }
+ }
+ }
+ parallel {
+ stage("test: baseline (next)") {
+ agent {
+ label 'data'
+ }
+ options { timeout(time: 30, unit: 'MINUTES') }
+ environment {
+ ARTIFACTORY = credentials("${p['artifactory.credentials']}")
+ DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
+ }
+ steps {
+ script {
+ docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
+ docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) {
+ sh "PROFILE=ci JENKINS_USER_NAME=${p['jenkins.user.name']} ci/test.sh"
+ sh "JENKINS_USER_NAME=${p['jenkins.user.name']} ci/clean.sh"
+ }
+ }
}
}
}
@@ -59,23 +90,25 @@ pipeline {
label 'data'
}
options { timeout(time: 20, unit: 'MINUTES') }
-
environment {
ARTIFACTORY = credentials("${p['artifactory.credentials']}")
+ DEVELOCITY_ACCESS_KEY = credentials("${p['develocity.access-key']}")
}
-
steps {
script {
- docker.withRegistry(p['docker.registry'], p['docker.credentials']) {
- docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.basic']) {
- sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml -Pci,artifactory -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-couchbase-non-root ' +
- '-Dartifactory.server=https://repo.spring.io ' +
+ docker.withRegistry(p['docker.proxy.registry'], p['docker.proxy.credentials']) {
+ docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) {
+ sh 'MAVEN_OPTS="-Duser.name=' + "${p['jenkins.user.name']}" + ' -Duser.home=/tmp/jenkins-home" ' +
+ "./mvnw -s settings.xml -Pci,artifactory " +
+ "-Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root " +
+ "-Dartifactory.server=${p['artifactory.url']} " +
"-Dartifactory.username=${ARTIFACTORY_USR} " +
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
- "-Dartifactory.staging-repository=libs-snapshot-local " +
+ "-Dartifactory.staging-repository=${p['artifactory.repository.snapshot']} " +
"-Dartifactory.build-name=spring-data-couchbase " +
- "-Dartifactory.build-number=${BUILD_NUMBER} " +
- '-Dmaven.test.skip=true clean deploy -U -B'
+ "-Dartifactory.build-number=spring-data-couchbase-${BRANCH_NAME}-build-${BUILD_NUMBER} " +
+ "-Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-couchbase " +
+ "-Dmaven.test.skip=true clean deploy -U -B"
}
}
}
@@ -86,10 +119,6 @@ pipeline {
post {
changed {
script {
- slackSend(
- color: (currentBuild.currentResult == 'SUCCESS') ? 'good' : 'danger',
- channel: '#spring-data-dev',
- message: "${currentBuild.fullDisplayName} - `${currentBuild.currentResult}`\n${env.BUILD_URL}")
emailext(
subject: "[${currentBuild.fullDisplayName}] ${currentBuild.currentResult}",
mimeType: 'text/html',
diff --git a/README.adoc b/README.adoc
index e6a3f4812..14d6c6e26 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1,6 +1,4 @@
-image:https://spring.io/badges/spring-data-couchbase/ga.svg[Spring Data Couchbase,link=https://projects.spring.io/spring-data-couchbase#quick-start] image:https://spring.io/badges/spring-data-couchbase/snapshot.svg[Spring Data Couchbase,link=https://projects.spring.io/spring-data-couchbase#quick-start]
-
-= Spring Data Couchbase image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-couchbase%2Fmain&subject=Build[link=https://jenkins.spring.io/view/SpringData/job/spring-data-couchbase/] https://gitter.im/spring-projects/spring-data[image:https://badges.gitter.im/spring-projects/spring-data.svg[Gitter]]
+= Spring Data Couchbase image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-couchbase%2Fmain&subject=Build[link=https://jenkins.spring.io/view/SpringData/job/spring-data-couchbase/] https://gitter.im/spring-projects/spring-data[image:https://badges.gitter.im/spring-projects/spring-data.svg[Gitter]] image:https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A["Revved up by Develocity", link="https://ge.spring.io/scans?search.rootProjectNames=Spring Data Couchbase"]
The primary goal of the https://www.springsource.org/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
@@ -32,16 +30,15 @@ This project is lead and maintained by Couchbase, Inc.
== Version compatibility
-`Spring-Data Couchbase 3.0.x` is the Spring Data connector for the `Couchbase Java SDK 2.x` generation.
+`Spring-Data Couchbase` is the Spring Data connector for the `Couchbase Java SDK 2.x` generation.
-Both the SDK and this Spring Data community project are major version changes with lots of differences from their
-respective previous versions.
+Both the SDK and this Spring Data community project are major version changes with lots of differences from their respective previous versions.
Notably, this version is compatible with `Couchbase Server 4.0`, bringing support for the `N1QL` query language.
== 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 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.
== Getting Started
@@ -124,9 +121,9 @@ If you'd rather like the latest snapshots of the upcoming major version, use our
- spring-libs-snapshot
+ spring-snapshotSpring Snapshot Repository
- https://repo.spring.io/libs-snapshot
+ https://repo.spring.io/snapshot
----
@@ -144,14 +141,16 @@ You can also chat with the community on https://gitter.im/spring-projects/spring
== Reporting Issues
-Spring Data uses JIRA as issue tracking system to record bugs and feature requests. If you want to raise an issue, please follow the recommendations below:
+Spring Data uses GitHub as issue tracking system to record bugs and feature requests.
+If you want to raise an issue, please follow the recommendations below:
* Before you log a bug, please search the
-https://jira.spring.io/browse/DATACOUCH[issue tracker] to see if someone has already reported the problem.
-* If the issue doesn’t already exist, https://jira.spring.io/browse/DATACOUCH[create a new issue].
+https://github.com/spring-projects/spring-data-couchbase/issues[issue tracker] to see if someone has already reported the problem.
+* If the issue does not already exist, https://github.com/spring-projects/spring-data-couchbase/issues/new[create a new issue].
* Please provide as much information as possible with the issue report, we like to know the version of Spring Data that you are using and JVM version.
-* If you need to paste code, or include a stack trace use JIRA `{code}…{code}` escapes before and after your text.
-* If possible try to create a test-case or project that replicates the issue. Attach a link to your code or a compressed file containing your code.
+* If you need to paste code, or include a stack trace use Markdown +++```+++ escapes before and after your text.
+* If possible try to create a test-case or project that replicates the issue.
+Attach a link to your code or a compressed file containing your code.
== Building from Source
@@ -173,10 +172,10 @@ Building the documentation builds also the project without running tests.
[source,bash]
----
- $ ./mvnw clean install -Pdistribute
+ $ ./mvnw clean install -Pantora
----
-The generated documentation is available from `target/site/reference/html/index.html`.
+The generated documentation is available from `target/antora/site/index.html`.
=== Building and staging reference documentation for review
@@ -185,7 +184,7 @@ The generated documentation is available from `target/site/reference/html/index.
export MY_GIT_USER=
mvn generate-resources
docs=`pwd`/target/site/reference/html
- pushd /tmp
+ pushd /tmp
mkdir $$
cd $$
# see https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site
diff --git a/ci/clean.sh b/ci/clean.sh
index 4986aaf40..732797ea2 100755
--- a/ci/clean.sh
+++ b/ci/clean.sh
@@ -2,5 +2,7 @@
set -euo pipefail
-MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" \
- ./mvnw -s settings.xml clean -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-couchbase
+export JENKINS_USER=${JENKINS_USER_NAME}
+
+MAVEN_OPTS="-Duser.name=${JENKINS_USER} -Duser.home=/tmp/jenkins-home" \
+ ./mvnw -s settings.xml clean -Dscan=false -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-couchbase -Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root
diff --git a/ci/pipeline.properties b/ci/pipeline.properties
index 5b5444523..a79feac95 100644
--- a/ci/pipeline.properties
+++ b/ci/pipeline.properties
@@ -1,19 +1,20 @@
# Java versions
-java.main.tag=17.0.6_10-jdk-focal
+java.main.tag=24.0.1_9-jdk-noble
+java.next.tag=24.0.1_9-jdk-noble
# Docker container images - standard
-docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag}
+docker.java.main.image=library/eclipse-temurin:${java.main.tag}
+docker.java.next.image=library/eclipse-temurin:${java.next.tag}
# Supported versions of MongoDB
-docker.mongodb.4.4.version=4.4.18
-docker.mongodb.5.0.version=5.0.14
-docker.mongodb.6.0.version=6.0.4
+docker.mongodb.6.0.version=6.0.23
+docker.mongodb.7.0.version=7.0.20
+docker.mongodb.8.0.version=8.0.9
# Supported versions of Redis
-docker.redis.6.version=6.2.10
-
-# Supported versions of Cassandra
-docker.cassandra.3.version=3.11.14
+docker.redis.6.version=6.2.13
+docker.redis.7.version=7.2.4
+docker.valkey.8.version=8.1.1
# Docker environment settings
docker.java.inside.basic=-v $HOME:/tmp/jenkins-home
@@ -22,4 +23,10 @@ docker.java.inside.docker=-u root -v /var/run/docker.sock:/var/run/docker.sock -
# Credentials
docker.registry=
docker.credentials=hub.docker.com-springbuildmaster
+docker.proxy.registry=https://docker-hub.usw1.packages.broadcom.com
+docker.proxy.credentials=usw1_packages_broadcom_com-jenkins-token
artifactory.credentials=02bd1690-b54f-4c9f-819d-a77cb7a9822c
+artifactory.url=https://repo.spring.io
+artifactory.repository.snapshot=libs-snapshot-local
+develocity.access-key=gradle_enterprise_secret_access_key
+jenkins.user.name=spring-builds+jenkins
diff --git a/ci/test.sh b/ci/test.sh
index 5601c3736..0d015bed4 100755
--- a/ci/test.sh
+++ b/ci/test.sh
@@ -3,8 +3,9 @@
set -euo pipefail
mkdir -p /tmp/jenkins-home/.m2/spring-data-couchbase
-chown -R 1001:1001 .
-MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" \
+export JENKINS_USER=${JENKINS_USER_NAME}
+
+MAVEN_OPTS="-Duser.name=${JENKINS_USER} -Duser.home=/tmp/jenkins-home" \
./mvnw -s settings.xml \
- -P${PROFILE} clean dependency:list test -Dsort -Dbundlor.enabled=false -U -B -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-couchbase
+ -P${PROFILE} clean dependency:list test -Dsort -U -B -Dmaven.repo.local=/tmp/jenkins-home/.m2/spring-data-couchbase -Ddevelocity.storage.directory=/tmp/jenkins-home/.develocity-root
diff --git a/package.json b/package.json
new file mode 100644
index 000000000..057a40fe8
--- /dev/null
+++ b/package.json
@@ -0,0 +1,10 @@
+{
+ "dependencies": {
+ "antora": "3.2.0-alpha.6",
+ "@antora/atlas-extension": "1.0.0-alpha.2",
+ "@antora/collector-extension": "1.0.0-alpha.7",
+ "@asciidoctor/tabs": "1.0.0-beta.6",
+ "@springio/antora-extensions": "1.13.0",
+ "@springio/asciidoctor-extensions": "1.0.0-alpha.11"
+ }
+}
diff --git a/pom.xml b/pom.xml
index 8f65493ac..7d6018f09 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,11 +1,11 @@
-
+
4.0.0org.springframework.dataspring-data-couchbase
- 5.1.0-M2
+ 6.0.0-SNAPSHOTSpring Data CouchbaseSpring Data integration for Couchbase
@@ -14,22 +14,19 @@
org.springframework.data.buildspring-data-parent
- 3.1.0-M2
+ 4.0.0-SNAPSHOT
- 3.4.1
- 3.4.1
- 3.1.0-M2
+ 3.8.2
+ 4.0.0-SNAPSHOTspring.data.couchbase7.0.1.Final
- 1.1.3
- 5.0.0
- 3.7.43.1.02.10.132.13.44.0.0
+ 6.11
@@ -47,9 +44,9 @@
- com.querydsl
+ io.github.openfeign.querydslquerydsl-apt
- ${querydsl}
+ ${querydsl_of}provided
@@ -247,32 +244,32 @@
-
-
- spring-libs-milestone
- https://repo.spring.io/libs-milestone
-
-
- sonatype-snapshot
- https://oss.sonatype.org/content/repositories/snapshots
-
- true
-
-
- false
-
-
-
-
-
-
- spring-plugins-release
- https://repo.spring.io/plugins-release
-
-
-
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ test-annotation-processing
+ generate-test-sources
+
+ testCompile
+
+
+ only
+
+ org.springframework.data.couchbase.repository.support.CouchbaseAnnotationProcessor
+
+ target/generated-test-sources
+
+ -Aquerydsl.logInfo=true
+
+
+
+
+
+
org.apache.maven.pluginsmaven-surefire-plugin
@@ -313,33 +310,54 @@
maven-assembly-plugin
- org.asciidoctor
- asciidoctor-maven-plugin
-
-
- com.mysema.maven
- apt-maven-plugin
- ${apt}
-
-
- com.querydsl
- querydsl-apt
- ${querydsl}
-
-
-
-
- generate-test-sources
-
- test-process
-
-
- target/generated-test-sources
- org.springframework.data.couchbase.repository.support.CouchbaseAnnotationProcessor
-
-
-
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ true
+
+
+
+
+ antora-process-resources
+
+
+
+ src/main/antora/resources/antora-resources
+ true
+
+
+
+
+
+ antora
+
+
+
+ org.antora
+ antora-maven-plugin
+
+
+
+
+
+
+
+
+ spring-snapshot
+ https://repo.spring.io/snapshot
+
+ true
+
+
+ false
+
+
+
+ spring-milestone
+ https://repo.spring.io/milestone
+
+
diff --git a/src/main/antora/.github/workflows/deploy-docs.yml b/src/main/antora/.github/workflows/deploy-docs.yml
new file mode 100644
index 000000000..9d272779a
--- /dev/null
+++ b/src/main/antora/.github/workflows/deploy-docs.yml
@@ -0,0 +1,33 @@
+name: Deploy Docs
+on:
+ push:
+ branches-ignore: [ gh-pages ]
+ tags: '**'
+ repository_dispatch:
+ types: request-build-reference # legacy
+ #schedule:
+ #- cron: '0 10 * * *' # Once per day at 10am UTC
+ workflow_dispatch:
+permissions:
+ actions: write
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ # FIXME: enable when pushed to spring-projects
+ # if: github.repository_owner == 'spring-projects'
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ ref: docs-build
+ fetch-depth: 1
+ - name: Dispatch (partial build)
+ if: github.ref_type == 'branch'
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }}
+ - name: Dispatch (full build)
+ if: github.ref_type == 'tag'
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD)
diff --git a/src/main/antora/antora-playbook.yml b/src/main/antora/antora-playbook.yml
new file mode 100644
index 000000000..af730e043
--- /dev/null
+++ b/src/main/antora/antora-playbook.yml
@@ -0,0 +1,40 @@
+# PACKAGES antora@3.2.0-alpha.2 @antora/atlas-extension:1.0.0-alpha.1 @antora/collector-extension@1.0.0-alpha.3 @springio/antora-extensions@1.1.0-alpha.2 @asciidoctor/tabs@1.0.0-alpha.12 @opendevise/antora-release-line-extension@1.0.0-alpha.2
+#
+# The purpose of this Antora playbook is to build the docs in the current branch.
+antora:
+ extensions:
+ - require: '@springio/antora-extensions'
+ root_component_name: 'data-couchbase'
+site:
+ title: Spring Data Couchbase
+ url: https://docs.spring.io/spring-data-couchbase/reference/
+content:
+ sources:
+ - url: ./../../..
+ branches: HEAD
+ start_path: src/main/antora
+ worktrees: true
+ - url: https://github.com/spring-projects/spring-data-commons
+ # Refname matching:
+ # https://docs.antora.org/antora/latest/playbook/content-refname-matching/
+ branches: [ main, 3.2.x ]
+ start_path: src/main/antora
+asciidoc:
+ attributes:
+ hide-uri-scheme: '@'
+ tabs-sync-option: '@'
+ extensions:
+ - '@asciidoctor/tabs'
+ - '@springio/asciidoctor-extensions'
+ - '@springio/asciidoctor-extensions/javadoc-extension'
+ sourcemap: true
+urls:
+ latest_version_segment: ''
+runtime:
+ log:
+ failure_level: warn
+ format: pretty
+ui:
+ bundle:
+ url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.16/ui-bundle.zip
+ snapshot: true
diff --git a/src/main/antora/antora.yml b/src/main/antora/antora.yml
new file mode 100644
index 000000000..7c0f37f68
--- /dev/null
+++ b/src/main/antora/antora.yml
@@ -0,0 +1,17 @@
+name: data-couchbase
+version: true
+title: Spring Data Couchbase
+nav:
+ - modules/ROOT/nav.adoc
+ext:
+ collector:
+ - run:
+ command: ./mvnw validate process-resources -am -Pantora-process-resources
+ local: true
+ scan:
+ dir: target/classes/
+ - run:
+ command: ./mvnw package -Pdistribute
+ local: true
+ scan:
+ dir: target/antora
diff --git a/src/main/antora/modules/ROOT/nav.adoc b/src/main/antora/modules/ROOT/nav.adoc
new file mode 100644
index 000000000..ac8b6a553
--- /dev/null
+++ b/src/main/antora/modules/ROOT/nav.adoc
@@ -0,0 +1,32 @@
+* xref:index.adoc[Overview]
+** xref:commons/upgrade.adoc[]
+** xref:commons/migrating.adoc[]
+
+* xref:couchbase.adoc[]
+** xref:couchbase/configuration.adoc[]
+** xref:couchbase/entity.adoc[]
+** xref:couchbase/autokeygeneration.adoc[]
+** xref:couchbase/template.adoc[]
+** xref:couchbase/transactions.adoc[]
+** xref:couchbase/collections.adoc[]
+** xref:couchbase/fieldlevelencryption.adoc[]
+** xref:couchbase/ansijoins.adoc[]
+** xref:couchbase/caching.adoc[]
+
+* xref:repositories.adoc[]
+** xref:repositories/core-concepts.adoc[]
+** xref:repositories/definition.adoc[]
+** xref:couchbase/repository.adoc[]
+** xref:couchbase/reactiverepository.adoc[]
+** xref:repositories/create-instances.adoc[]
+** xref:repositories/query-methods-details.adoc[]
+** xref:repositories/projections.adoc[]
+** xref:repositories/custom-implementations.adoc[]
+** xref:repositories/core-domain-events.adoc[]
+** xref:repositories/core-extensions.adoc[]
+** xref:repositories/null-handling.adoc[]
+** xref:repositories/query-keywords-reference.adoc[]
+** xref:repositories/query-return-types-reference.adoc[]
+
+* xref:attachment$api/java/index.html[Javadoc,role=link-external,window=_blank]
+* https://github.com/spring-projects/spring-data-commons/wiki[Wiki,role=link-external,window=_blank]
diff --git a/src/main/asciidoc/migrating.adoc b/src/main/antora/modules/ROOT/pages/commons/migrating.adoc
similarity index 72%
rename from src/main/asciidoc/migrating.adoc
rename to src/main/antora/modules/ROOT/pages/commons/migrating.adoc
index 1c399611e..e2406ee3a 100644
--- a/src/main/asciidoc/migrating.adoc
+++ b/src/main/antora/modules/ROOT/pages/commons/migrating.adoc
@@ -12,45 +12,48 @@ Since the main objective was to migrate from the Java SDK 2 to 3, configuration
IMPORTANT: XML Configuration support has been dropped, so only java/annotation based configuration is supported.
-Your configuration still has to extend the `AbstractCouchbaseConfiguration`, but since RBAC (role-based access control) is now mandatory, different properties need to be overridden in order to be configured: `getConnectionString`, `getUserName`, `getPassword` and `getBucketName`. If you want to use a non-default scope optionally you can override the `getScopeName` method. Note that if you want to use certificate based authentication or you need to customize the password authentication, the `authenticator` method can be overridden to perform this task.
+Your configuration still has to extend the `AbstractCouchbaseConfiguration`, but since RBAC (role-based access control) is now mandatory, different properties need to be overridden in order to be configured: `getConnectionString`, `getUserName`, `getPassword` and `getBucketName`.If you want to use a non-default scope optionally you can override the `getScopeName` method.Note that if you want to use certificate based authentication or you need to customize the password authentication, the `authenticator` method can be overridden to perform this task.
The new SDK still has an environment that is used to configure it, so you can override the `configureEnvironment` method and supply custom configuration if needed.
-For more information, see <>.
+For more information, see xref:couchbase/configuration.adoc[Installation & Configuration].
+[[spring-boot-version-compatibility]]
=== Spring Boot Version Compatibility
-Spring Boot 2.3.x or higher depends on Spring Data Couchbase 4.x. Earlier versions of Couchbase are not available because SDK 2 and 3 cannot live on the same classpath.
+Spring Boot 2.3.x or higher depends on Spring Data Couchbase 4.x.Earlier versions of Couchbase are not available because SDK 2 and 3 cannot live on the same classpath.
[[couchbase.migrating.entities]]
+[[entities]]
== Entities
How to deal with entities has not changed, although since the SDK now does not ship annotations anymore only Spring-Data related annotations are supported.
Specifically:
- - `com.couchbase.client.java.repository.annotation.Id` became `import org.springframework.data.annotation.Id`
- - `com.couchbase.client.java.repository.annotation.Field` became `import org.springframework.data.couchbase.core.mapping.Field`
+- `com.couchbase.client.java.repository.annotation.Id` became `import org.springframework.data.annotation.Id`
+- `com.couchbase.client.java.repository.annotation.Field` became `import org.springframework.data.couchbase.core.mapping.Field`
The `org.springframework.data.couchbase.core.mapping.Document` annotation stayed the same.
-For more information, see <>.
+For more information, see xref:couchbase/entity.adoc[Modeling Entities].
[[couchbase.migrating.indexes]]
== Automatic Index Management
-Automatic Index Management has been redesigned to allow more flexible indexing. New annotations have been introduced and old ones like `@ViewIndexed`, `@N1qlSecondaryIndexed` and `@N1qlPrimaryIndexed` were removed.
+Automatic Index Management has been redesigned to allow more flexible indexing.
+New annotations have been introduced and old ones like `@ViewIndexed`, `@N1qlSecondaryIndexed` and `@N1qlPrimaryIndexed` were removed.
-For more information, see <>.
+For more information, see xref:couchbase/repository.adoc#couchbase.repository.indexing[Automatic Index Management].
[[couchbase.migrating.template]]
== Template and ReactiveTemplate
Since the Couchbase SDK 3 removes support for `RxJava` and instead adds support for `Reactor`, both the `couchbaseTemplate` as well as the `reactiveCouchbaseTemplate` can be directly accessed from the `AbstractCouchbaseConfiguration`.
-The template has been completely overhauled so that it now uses a fluent API to configure instead of many method overloads. This has the advantage that in the future we are able to extend the functionality without having to introduce more and more overloads that make it complicated to navigate.
+The template has been completely overhauled so that it now uses a fluent API to configure instead of many method overloads.This has the advantage that in the future we are able to extend the functionality without having to introduce more and more overloads that make it complicated to navigate.
The following table describes the method names in 3.x and compares them to their 4.x equivalents:
@@ -113,14 +116,14 @@ In addition, the following methods have been added which were not available in 3
We tried to unify and align the APIs more closely to the underlying SDK semantics so they are easier to correlate and navigate.
-For more information, see <>.
+For more information, see xref:couchbase/template.adoc[Template & direct operations].
[[couchbase.migrating.repository]]
== Repositories & Queries
- - `org.springframework.data.couchbase.core.query.Query` became `org.springframework.data.couchbase.repository.Query`
- - `org.springframework.data.couchbase.repository.ReactiveCouchbaseSortingRepository` has been removed. Consider extending `ReactiveSortingRepository` or `ReactiveCouchbaseRepository`
- - `org.springframework.data.couchbase.repository.CouchbasePagingAndSortingRepository` has been removed. Consider extending `PagingAndSortingRepository` or `CouchbaseRepository`
+- `org.springframework.data.couchbase.core.query.Query` became `org.springframework.data.couchbase.repository.Query`
+- `org.springframework.data.couchbase.repository.ReactiveCouchbaseSortingRepository` has been removed.Consider extending `ReactiveSortingRepository` or `ReactiveCouchbaseRepository`
+- `org.springframework.data.couchbase.repository.CouchbasePagingAndSortingRepository` has been removed.Consider extending `PagingAndSortingRepository` or `CouchbaseRepository`
IMPORTANT: Support for views has been removed and N1QL queries are now the first-class citizens for all custom repository methods as well as the built-in ones by default.
@@ -151,9 +154,10 @@ public class MyService {
----
====
-See <> for more information.
+See xref:couchbase/repository.adoc[Couchbase repositories] for more information.
+[[full-text-search-fts]]
== Full Text Search (FTS)
The FTS API has been simplified and now can be accessed via the `Cluster` class:
@@ -193,4 +197,4 @@ public class MyService {
----
====
-See link:https://docs.couchbase.com/java-sdk/current/howtos/full-text-searching-with-sdk.html[the FTS Documentation] for more information.
\ No newline at end of file
+See link:https://docs.couchbase.com/java-sdk/current/howtos/full-text-searching-with-sdk.html[the FTS Documentation] for more information.
diff --git a/src/main/antora/modules/ROOT/pages/commons/upgrade.adoc b/src/main/antora/modules/ROOT/pages/commons/upgrade.adoc
new file mode 100644
index 000000000..51a9189aa
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/commons/upgrade.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$upgrade.adoc[]
diff --git a/src/main/antora/modules/ROOT/pages/couchbase.adoc b/src/main/antora/modules/ROOT/pages/couchbase.adoc
new file mode 100644
index 000000000..0b1c813e1
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/couchbase.adoc
@@ -0,0 +1,15 @@
+[[couchbase.core]]
+= Couchbase Support
+:page-section-summary-toc: 1
+
+Spring Data support for Couchbase contains a wide range of features:
+
+* Spring configuration support with xref:couchbase/configuration.adoc[Java-based `@Configuration` classes].
+* The xref:couchbase/template.adoc[`CouchbaseTemplate` and `ReactiveCouchbaseTemplate`] helper classes that provide object mapping between Couchbase collections and POJOs.
+* xref:couchbase/template.adoc#exception-translation[Exception translation] into Spring's portable {spring-data-commons-docs-url}data-access.html#dao-exceptions[Data Access Exception Hierarchy].
+* Feature rich object mapping integrated with _Spring's_ {spring-data-commons-docs-url}core.html#core-convert[Conversion Service].
+* Annotation-based mapping metadata that is extensible to support other metadata formats.
+* Automatic implementation of xref:repositories.adoc[imperative and reactive `Repository` interfaces] including support for xref:repositories/custom-implementations.adoc[custom query methods].
+
+For most data-oriented tasks, you can use the `[Reactive]CouchbaseTemplate` or the `Repository` support, both of which use the rich object-mapping functionality.
+Spring Data Couchbase uses consistent naming conventions on objects in various APIs to those found in the Couchbase Java SDK so that they are familiar and so that you can map your existing knowledge onto the Spring APIs.
diff --git a/src/main/asciidoc/ansijoins.adoc b/src/main/antora/modules/ROOT/pages/couchbase/ansijoins.adoc
similarity index 95%
rename from src/main/asciidoc/ansijoins.adoc
rename to src/main/antora/modules/ROOT/pages/couchbase/ansijoins.adoc
index 732f39ae1..11c756948 100644
--- a/src/main/asciidoc/ansijoins.adoc
+++ b/src/main/antora/modules/ROOT/pages/couchbase/ansijoins.adoc
@@ -58,16 +58,19 @@ List books;
[[couchbase.ansijoins.joinhints]]
== ANSI Join Hints
+[[use-index-hint]]
=== Use Index Hint
`index` element on the `@N1qlJoin` can be used to provided the hint for the `lks` (current entity) index and `rightIndex`
element can be used to provided the `rks` (associated entity) index.
+[[hash-join-hint]]
=== Hash Join Hint
If the join type is going to be hash join, the hash side can be specified for the `rks` (associated entity).
If the associated entity is on the build side, it can be specified as `HashSide.BUILD` else `HashSide.PROBE`.
+[[use-keys-hint]]
=== Use Keys Hint
-`keys` element on the `@N1qlJoin` annotation can be used to specify unique document keys to restrict the join key space.
\ No newline at end of file
+`keys` element on the `@N1qlJoin` annotation can be used to specify unique document keys to restrict the join key space.
diff --git a/src/main/asciidoc/autokeygeneration.adoc b/src/main/antora/modules/ROOT/pages/couchbase/autokeygeneration.adoc
similarity index 90%
rename from src/main/asciidoc/autokeygeneration.adoc
rename to src/main/antora/modules/ROOT/pages/couchbase/autokeygeneration.adoc
index 8ddf7cce0..03cc71f01 100644
--- a/src/main/asciidoc/autokeygeneration.adoc
+++ b/src/main/antora/modules/ROOT/pages/couchbase/autokeygeneration.adoc
@@ -4,8 +4,8 @@
This chapter describes how couchbase document keys can be auto-generated using builtin mechanisms.
There are two types of auto-generation strategies supported.
-- <>
-- <>
+- xref:couchbase/autokeygeneration.adoc#couchbase.autokeygeneration.usingattributes[Key generation using attributes]
+- xref:couchbase/autokeygeneration.adoc#couchbase.autokeygeneration.unique[Key generation using uuid]
NOTE: The maximum key length supported by couchbase is 250 bytes.
@@ -75,4 +75,4 @@ public class User {
...
}
----
-====
\ No newline at end of file
+====
diff --git a/src/main/asciidoc/caching.adoc b/src/main/antora/modules/ROOT/pages/couchbase/caching.adoc
similarity index 97%
rename from src/main/asciidoc/caching.adoc
rename to src/main/antora/modules/ROOT/pages/couchbase/caching.adoc
index 5aacff6a5..cffc00b59 100644
--- a/src/main/asciidoc/caching.adoc
+++ b/src/main/antora/modules/ROOT/pages/couchbase/caching.adoc
@@ -54,4 +54,4 @@ public String simulateLongRun(long time) {
If you run the method multiple times, you'll see a set operation happening first, followed by multiple get operations and no sleep time (which fakes the expensive execution). You can store whatever you want, if it is JSON of course you can access it through views and look at it in the Web UI.
-Note that to use cache.clear() or catch.invalidate(), the bucket must have a primary key.
+Note that to use cache.clear() or cache.invalidate(), the bucket must have a primary key.
diff --git a/src/main/asciidoc/collections.adoc b/src/main/antora/modules/ROOT/pages/couchbase/collections.adoc
similarity index 97%
rename from src/main/asciidoc/collections.adoc
rename to src/main/antora/modules/ROOT/pages/couchbase/collections.adoc
index d6fbf18d0..fc49b4db6 100644
--- a/src/main/asciidoc/collections.adoc
+++ b/src/main/antora/modules/ROOT/pages/couchbase/collections.adoc
@@ -7,14 +7,17 @@ The https://github.com/couchbaselabs/try-cb-spring[try-cb-spring] sample applica
The 2021 Couchbase Connect presentation on Collections in Spring Data can be found at https://www.youtube.com/watch?v=MrplTeEFItk[Presentation Only] and https://web.cvent.com/hub/events/1dce8283-986d-4de9-8368-94c98f60df01/sessions/9ee89a85-833c-4e0c-81b0-807864fa351b?goBackHref=%2Fevents%2F1dce8283-986d-4de9-8368-94c98f60df01%2Fsessions&goBackName=Add%2FView+Sessions&goBackTab=all[Presentation with Slide Deck]
+[[requirements]]
== Requirements
- Couchbase Server 7.0 or above.
- Spring Data Couchbase 4.3.1 or above.
+[[getting-started-configuration]]
== Getting Started & Configuration
+[[scope-and-collection-specification]]
=== Scope and Collection Specification
There are several mechanisms of specifying scopes and collections, and these may be combined, or one mechanism may override another.
First some definitions for scopes and collections. An unspecified scope indicates that the default scope is to be used, likewise, an
diff --git a/src/main/antora/modules/ROOT/pages/couchbase/configuration.adoc b/src/main/antora/modules/ROOT/pages/couchbase/configuration.adoc
new file mode 100644
index 000000000..491861d45
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/couchbase/configuration.adoc
@@ -0,0 +1,252 @@
+[[couchbase.configuration]]
+= Installation & Configuration
+
+This chapter describes the common installation and configuration steps needed when working with the library.
+
+[[installation]]
+== Installation
+
+All versions intended for production use are distributed across Maven Central and the Spring release repository.
+As a result, the library can be included like any other maven dependency:
+
+
+[[compatibility]]
+== Compatibility
+
+The simplest way to get the correct dependencies is by making a project with https://start.spring.io/[spring initializr]
+The parent Spring Boot Starter artfacts have the required dependencies, they do not need to be specified.
+
+=== Spring Boot Version Compatibility
+
+* Spring Boot 3.4.* uses Spring Data Couchbase 5.4.*.
+* Spring Boot 3.3.* uses Spring Data Couchbase 5.3.*.
+* Spring Boot 3.2.* uses Spring Data Couchbase 5.2.*.
+
+=== Couchbase Java SDK Compatibility
+
+* Spring Data Couchbase 5.4.* depends on Couchbase Java SDK 3.7.*
+* Spring Data Couchbase 5.3.* depends on Couchbase Java SDK 3.6.*
+* Spring Data Couchbase 5.2.* depends on Couchbase Java SDK 3.3.*
+
+[[configuration]]
+== Configuration
+.Including the dependency through maven
+====
+[source,xml,subs="+attributes"]
+----
+
+ org.springframework.data
+ spring-data-couchbase
+ {version}
+
+----
+====
+
+This will pull in several dependencies, including the underlying Couchbase Java SDK, common Spring dependencies and also Jackson as the JSON mapping infrastructure.
+
+You can also grab snapshots from the https://repo.spring.io/ui/repos/tree/General/snapshot/org/springframework/data/spring-data-couchbase[spring snapshot repository] ( \https://repo.spring.io/snapshot ) and milestone releases from the https://repo.spring.io/ui/repos/tree/General/milestone/org/springframework/data/spring-data-couchbase[spring milestone repository] ( \https://repo.spring.io/milestone ).
+Here is an example on how to use the current SNAPSHOT dependency:
+
+[[snapshot-configuration]]
+== Snapshot Configuration
+
+.Using a snapshot version
+====
+[source,xml]
+----
+
+ org.springframework.data
+ spring-data-couchbase
+ ${version}-SNAPSHOT
+
+
+
+ spring-snapshot
+ Spring Snapshot Repository
+ https://repo.spring.io/snapshot
+
+----
+====
+
+[[overriding-the-couchbase-sdk-version]]
+== Overriding the Couchbase SDK Version
+
+Some users may wish to use a Couchbase Java SDK version different from the one referenced in a Spring Data Couchbase release for the purpose of obtaining bug and vulnerability fixes. Since Couchbase Java SDK minor version releases are backwards compatible, this version of Spring Data Couchbase is compatible and supported with any 3.x version of the Couchbase Java SDK newer than the one specified in the release dependencies. To change the Couchbase Java SDK version used by Spring Data Couchbase, simply override the dependency in the application pom.xml as follows:
+
+.If Using the spring-data-couchbase Dependency Directly
+====
+[source,xml]
+----
+
+ org.springframework.data
+ spring-data-couchbase
+ ${version}
+
+
+ com.couchbase.client
+ java-client
+
+
+
+
+
+ com.couchbase.client
+ java-client
+ 3.4.7
+
+----
+====
+
+.If Using the spring-data-starter-couchbase Dependency (from Spring Initialzr)
+====
+[source,xml]
+----
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ x.y.z
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-couchbase
+
+
+ com.couchbase.client
+ java-client
+
+
+
+
+
+ com.couchbase.client
+ java-client
+ 3.4.7
+
+----
+====
+
+Once you have all needed dependencies on the classpath, you can start configuring it.
+Only Java config is supported (XML config has been removed in 4.0).
+
+[[configuration-java]]
+== Annotation-based Configuration ("JavaConfig")
+
+To get started, all you need to do is subclass the `AbstractCouchbaseConfiguration` and implement the abstract methods.
+
+.Extending the `AbstractCouchbaseConfiguration`
+====
+[source,java]
+----
+
+@Configuration
+public class Config extends AbstractCouchbaseConfiguration {
+
+ @Override
+ public String getConnectionString() {
+ return "couchbase://127.0.0.1";
+ }
+
+ @Override
+ public String getUserName() {
+ return "Administrator";
+ }
+
+ @Override
+ public String getPassword() {
+ return "password";
+ }
+
+ @Override
+ public String getBucketName() {
+ return "travel-sample";
+ }
+}
+----
+====
+
+The connection string is made up of a list of hosts and an optional scheme (`couchbase://`) as shown in the code above.
+All you need to provide is a list of Couchbase nodes to bootstrap into (separated by a `,`). Please note that while one
+host is sufficient in development, it is recommended to add 3 to 5 bootstrap nodes here. Couchbase will pick up all nodes
+from the cluster automatically, but it could be the case that the only node you've provided is experiencing issues while
+you are starting the application.
+
+The `userName` and `password` are configured in your Couchbase Server cluster through RBAC (role-based access control).
+The `bucketName` reflects the bucket you want to use for this configuration.
+
+Additionally, the SDK environment can be tuned by overriding the `configureEnvironment` method which takes a
+`ClusterEnvironment.Builder` to return a configured `ClusterEnvironment`.
+
+Many more things can be customized and overridden as custom beans from this configuration (for example repositories,
+validation and custom converters).
+
+TIP: If you use `SyncGateway` and `CouchbaseMobile`, you may run into problem with fields prefixed by `_`.
+Since Spring Data Couchbase by default stores the type information as a `_class` attribute this can be problematic.
+Override `typeKey()` (for example to return `MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE`) to change the
+name of said attribute.
+
+If you start your application, you should see Couchbase INFO level logging in the logs, indicating that the underlying
+Couchbase Java SDK is connecting to the database.If any errors are reported, make sure that the given credentials
+and host information are correct.
+
+
+[[configuring-multiple-buckets]]
+== Configuring Multiple Buckets
+
+To leverage multi-bucket repositories, implement the methods below in your Config class.
+The config*OperationsMapping methods configure the mapping of entity-objects to buckets.
+Be careful with the method names - using a method name that is a Bean will result in the value of that bean being used instead of the result of the method.
+
+This example maps Person -> protected, User -> mybucket, and everything else goes to getBucketName().
+Note that this only maps calls through the Repository.
+
+====
+[source,java]
+----
+@Override
+public void configureReactiveRepositoryOperationsMapping(ReactiveRepositoryOperationsMapping baseMapping) {
+ try {
+ ReactiveCouchbaseTemplate personTemplate = myReactiveCouchbaseTemplate(myCouchbaseClientFactory("protected"),new MappingCouchbaseConverter());
+ baseMapping.mapEntity(Person.class, personTemplate); // Person goes in "protected" bucket
+ ReactiveCouchbaseTemplate userTemplate = myReactiveCouchbaseTemplate(myCouchbaseClientFactory("mybucket"),new MappingCouchbaseConverter());
+ baseMapping.mapEntity(User.class, userTemplate); // User goes in "mybucket"
+ // everything else goes in getBucketName()
+ } catch (Exception e) {
+ throw e;
+ }
+}
+@Override
+public void configureRepositoryOperationsMapping(RepositoryOperationsMapping baseMapping) {
+ try {
+ CouchbaseTemplate personTemplate = myCouchbaseTemplate(myCouchbaseClientFactory("protected"),new MappingCouchbaseConverter());
+ baseMapping.mapEntity(Person.class, personTemplate); // Person goes in "protected" bucket
+ CouchbaseTemplate userTemplate = myCouchbaseTemplate(myCouchbaseClientFactory("mybucket"),new MappingCouchbaseConverter());
+ baseMapping.mapEntity(User.class, userTemplate); // User goes in "mybucket"
+ // everything else goes in getBucketName()
+ } catch (Exception e) {
+ throw e;
+ }
+}
+
+// do not use reactiveCouchbaseTemplate for the name of this method, otherwise the value of that bean
+// will be used instead of the result of this call (the client factory arg is different)
+public ReactiveCouchbaseTemplate myReactiveCouchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
+ MappingCouchbaseConverter mappingCouchbaseConverter) {
+ return new ReactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter);
+}
+
+// do not use couchbaseTemplate for the name of this method, otherwise the value of that been
+// will be used instead of the result from this call (the client factory arg is different)
+public CouchbaseTemplate myCouchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
+ MappingCouchbaseConverter mappingCouchbaseConverter) {
+ return new CouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter);
+}
+
+// do not use couchbaseClientFactory for the name of this method, otherwise the value of that bean will
+// will be used instead of this call being made ( bucketname is an arg here, instead of using bucketName() )
+public CouchbaseClientFactory myCouchbaseClientFactory(String bucketName) {
+ return new SimpleCouchbaseClientFactory(getConnectionString(),authenticator(), bucketName );
+}
+----
+====
diff --git a/src/main/asciidoc/entity.adoc b/src/main/antora/modules/ROOT/pages/couchbase/entity.adoc
similarity index 98%
rename from src/main/asciidoc/entity.adoc
rename to src/main/antora/modules/ROOT/pages/couchbase/entity.adoc
index ed9c3dceb..c4b1dc749 100644
--- a/src/main/asciidoc/entity.adoc
+++ b/src/main/antora/modules/ROOT/pages/couchbase/entity.adoc
@@ -3,7 +3,7 @@
This chapter describes how to model Entities and explains their counterpart representation in Couchbase Server itself.
-include::{spring-data-commons-docs}/object-mapping.adoc[leveloffset=+1]
+include::{commons}@data-commons::page$object-mapping.adoc[leveloffset=+1]
[[basics]]
== Documents and Fields
@@ -78,8 +78,8 @@ This key needs to be any string with a length of maximum 250 characters.
Feel free to use whatever fits your use case, be it a UUID, an email address or anything else.
Writes to Couchbase-Server buckets can optionally be assigned durability requirements; which instruct Couchbase Server to update the specified document on multiple nodes in memory and/or disk locations across the cluster; before considering the write to be committed.
-Default durability requirements can also be configured through the `@Document` annotation.
-For example: `@Document(durabilityLevel = DurabilityLevel.MAJORITY)` will force mutations to be replicated to a majority of the Data Service nodes.
+Default durability requirements can also be configured through the `@Document` or `@Durability` annotations.
+For example: `@Document(durabilityLevel = DurabilityLevel.MAJORITY)` will force mutations to be replicated to a majority of the Data Service nodes. Both of the annotations support expression based durability level assignment via `durabilityExpression` attribute (Note SPEL is not supported).
[[datatypes]]
== Datatypes and Converters
diff --git a/src/main/asciidoc/fieldlevelencryption.adoc b/src/main/antora/modules/ROOT/pages/couchbase/fieldlevelencryption.adoc
similarity index 95%
rename from src/main/asciidoc/fieldlevelencryption.adoc
rename to src/main/antora/modules/ROOT/pages/couchbase/fieldlevelencryption.adoc
index 7554180ab..e8a8de5a3 100644
--- a/src/main/asciidoc/fieldlevelencryption.adoc
+++ b/src/main/antora/modules/ROOT/pages/couchbase/fieldlevelencryption.adoc
@@ -3,16 +3,20 @@
Couchbase supports https://docs.couchbase.com/java-sdk/current/howtos/encrypting-using-sdk.html[Field Level Encryption]. This section documents how to use it with Spring Data Couchbase.
+[[requirements]]
== Requirements
- Spring Data Couchbase 5.0.0-RC1 or above.
+[[overview]]
== Overview
Fields annotated with com.couchbase.client.java.encryption.annotation.Encrypted (@Encrypted) will be automatically encrypted on write and decrypted on read. Unencrypted fields can be migrated to encrypted by specifying @Encrypted(migration = Encrypted.Migration.FROM_UNENCRYPTED).
+[[getting-started-configuration]]
== Getting Started & Configuration
+[[dependencies]]
=== Dependencies
Field Level Encryption is available with the dependency ( see https://docs.couchbase.com/java-sdk/current/howtos/encrypting-using-sdk.html[Field Level Encryption] )
@@ -25,6 +29,7 @@ HashiCorp Vault Transit integration requires https://docs.spring.io/spring-vault
org.springframework.vaultspring-vault-core
```
+[[providing-a-cryptomanager]]
=== Providing a CryptoManager
A CryptoManager needs to be provided by overriding the cryptoManager() method in AbstractCouchbaseConfiguration. This CryptoManager will be used by Spring Data Couchbase and also by Couchbase Java SDK direct calls made from a CouchbaseClientFactory.
@@ -43,15 +48,18 @@ protected CryptoManager cryptoManager() {
CryptoManager cryptoManager = DefaultCryptoManager.builder().decrypter(provider.decrypter())
.defaultEncrypter(provider.encrypterForKey("myKey")).build();
+ return cryptoManager;
}
```
+[[defining-a-field-as-encrypted-]]
=== Defining a Field as Encrypted.
1. @Encrypted defines a field as encrypted.
2. @Encrypted(migration = Encrypted.Migration.FROM_UNENCRYPTED) defines a field that may or may not be encrypted when read. It will be encrypted when written.
-3. @Encrypted(encrypter = "") specifies the alias of the encrypter to use for encryption. Note this is not the algorithm, but the name specified when adding the encrypter to the CryptoManager.
-
+3. @Encrypted(encrypter = "") specifies the alias of the encrypter to use for encryption. Note this is not the algorithm, but the name specified when adding the encrypter to the CryptoManager.
+
+[[example]]
=== Example
.AbstractCouchbaseConfiguration
====
@@ -69,7 +77,7 @@ static class Config extends AbstractCouchbaseConfiguration {
@Override public String getBucketName() { /* ... */ }
/* provide a cryptoManager */
- @Override
+ @Override
protected CryptoManager cryptoManager() {
KeyStore javaKeyStore = KeyStore.getInstance("MyKeyStoreType");
FileInputStream fis = new java.io.FileInputStream("keyStoreName");
@@ -82,6 +90,7 @@ static class Config extends AbstractCouchbaseConfiguration {
CryptoManager cryptoManager = DefaultCryptoManager.builder().decrypter(provider.decrypter())
.defaultEncrypter(provider.encrypterForKey("myKey")).build();
+ return cryptoManager;
}
}
diff --git a/src/main/asciidoc/reactiverepository.adoc b/src/main/antora/modules/ROOT/pages/couchbase/reactiverepository.adoc
similarity index 92%
rename from src/main/asciidoc/reactiverepository.adoc
rename to src/main/antora/modules/ROOT/pages/couchbase/reactiverepository.adoc
index b4f0c3688..25bbc24f8 100644
--- a/src/main/asciidoc/reactiverepository.adoc
+++ b/src/main/antora/modules/ROOT/pages/couchbase/reactiverepository.adoc
@@ -5,7 +5,7 @@
== Introduction
This chapter describes the reactive repository support for couchbase.
-This builds on the core repository support explained in <>.
+This builds on the core repository support explained in xref:couchbase/repository.adoc[Couchbase repositories].
So make sure you’ve got a sound understanding of the basic concepts explained there.
[[couchbase.reactiverepository.libraries]]
@@ -101,4 +101,4 @@ public class PersonRepositoryTests {
[[couchbase.reactiverepository.querying]]
== Repositories and Querying
-Spring Data's Reactive Couchbase comes with full querying support already provided by the blocking <>
+Spring Data's Reactive Couchbase comes with full querying support already provided by the blocking xref:couchbase/repository.adoc#couchbase.repository.querying[Repositories and Querying]
diff --git a/src/main/asciidoc/repository.adoc b/src/main/antora/modules/ROOT/pages/couchbase/repository.adoc
similarity index 85%
rename from src/main/asciidoc/repository.adoc
rename to src/main/antora/modules/ROOT/pages/couchbase/repository.adoc
index 5e3471e3f..df8a32df2 100644
--- a/src/main/asciidoc/repository.adoc
+++ b/src/main/antora/modules/ROOT/pages/couchbase/repository.adoc
@@ -3,9 +3,10 @@
The goal of Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.
-By default, operations are backed by Key/Value if they are single-document operations and the ID is known. For all other operations by default N1QL queries are generated, and as a result proper indexes must be created for performant data access.
+By default, operations are backed by Key/Value if they are single-document operations and the ID is known.
+For all other operations by default N1QL queries are generated, and as a result proper indexes must be created for performant data access.
-Note that you can tune the consistency you want for your queries (see <>) and have different repositories backed by different buckets (see <>)
+Note that you can tune the consistency you want for your queries (see xref:couchbase/repository.adoc#couchbase.repository.consistency[Querying with consistency]) and have different repositories backed by different buckets (see <>)
[[couchbase.repository.configuration]]
== Configuration
@@ -30,6 +31,74 @@ public class Config extends AbstractCouchbaseConfiguration {
An advanced usage is described in <>.
+[[couchbase.repository.configuration.dsl]]
+=== QueryDSL Configuration
+Spring Data Couchbase supports QueryDSL for building type-safe queries. To enable code generation, setting `CouchbaseAnnotationProcessor` as an annotation processor is required.
+Additionally, the runtime needs querydsl-apt to enable QueryDSL on repositories.
+
+.Maven Configuration Example
+====
+[source,xml]
+----
+ . existing depdendencies including those required for spring-data-couchbase
+ .
+ .
+
+ com.querydsl
+ querydsl-apt
+ ${querydslVersion}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ annotation-processing
+ generate-sources
+
+ compile
+
+
+ only
+
+ org.springframework.data.couchbase.repository.support.CouchbaseAnnotationProcessor
+
+ target/generated-sources
+
+ -Aquerydsl.logInfo=true
+
+
+
+
+
+
+
+
+----
+====
+
+.Gradle Configuration Example
+====
+[source,groovy,indent=0,subs="verbatim,quotes",role="secondary"]
+----
+dependencies {
+ annotationProcessor 'com.querydsl:querydsl-apt:${querydslVersion}'
+ annotationProcessor 'org.springframework.data:spring-data-couchbase'
+ testAnnotationProcessor 'com.querydsl:querydsl-apt:${querydslVersion}'
+ testAnnotationProcessor 'org.springframework.data:spring-data-couchbase'
+}
+tasks.withType(JavaCompile).configureEach {
+ options.compilerArgs += [
+ "-processor",
+ "org.springframework.data.couchbase.repository.support.CouchbaseAnnotationProcessor"]
+}
+----
+====
+
[[couchbase.repository.usage]]
== Usage
@@ -360,6 +429,7 @@ public interface AirportRepository extends PagingAndSortingRepository result = txOperator.execute((ctx) ->
----
====
+[[transactions-directly-with-the-sdk]]
== Transactions Directly with the SDK
Spring Data Couchbase works seamlessly with the Couchbase Java SDK for transaction processing. Spring Data Couchbase operations that
diff --git a/src/main/antora/modules/ROOT/pages/index.adoc b/src/main/antora/modules/ROOT/pages/index.adoc
new file mode 100644
index 000000000..b4ae0a5ea
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/index.adoc
@@ -0,0 +1,20 @@
+[[spring-data-couchbase-reference-documentation]]
+= Spring Data Couchbase
+:revnumber: {version}
+:revdate: {localdate}
+:feature-scroll: true
+
+_Spring Data Couchbase provides repository support for the Couchbase database.
+It eases development of applications with a consistent programming model that need to access Couchbase data sources._
+
+[horizontal]
+xref:couchbase.adoc[Couchbase] :: Couchbase support and connectivity
+xref:repositories.adoc[Repositories] :: Couchbase Repositories
+xref:commons/migrating.adoc[Migration] :: Migration Guides
+https://github.com/spring-projects/spring-data-commons/wiki[Wiki] :: What's New, Upgrade Notes, Supported Versions, additional cross-version information.
+
+Michael Nitschinger, Oliver Gierke, Simon Basle, Michael Reiche, Tigran Babloyan
+
+(C) 2014-{copyright-year} The original author(s)
+
+Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
diff --git a/src/main/antora/modules/ROOT/pages/repositories.adoc b/src/main/antora/modules/ROOT/pages/repositories.adoc
new file mode 100644
index 000000000..f7fc60fb1
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories.adoc
@@ -0,0 +1,8 @@
+[[couchbase.repositories]]
+= Repositories
+:page-section-summary-toc: 1
+
+This chapter explains the basic foundations of Spring Data repositories and Couchbase specifics.
+Before continuing to the Couchbase specifics, make sure you have a sound understanding of the basic concepts.
+
+The goal of the Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.
diff --git a/src/main/antora/modules/ROOT/pages/repositories/core-concepts.adoc b/src/main/antora/modules/ROOT/pages/repositories/core-concepts.adoc
new file mode 100644
index 000000000..579ae7da4
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/core-concepts.adoc
@@ -0,0 +1,4 @@
+include::{commons}@data-commons::page$repositories/core-concepts.adoc[]
+
+[[couchbase.entity-persistence.state-detection-strategies]]
+include::{commons}@data-commons::page$is-new-state-detection.adoc[leveloffset=+1]
diff --git a/src/main/antora/modules/ROOT/pages/repositories/core-domain-events.adoc b/src/main/antora/modules/ROOT/pages/repositories/core-domain-events.adoc
new file mode 100644
index 000000000..f84313e9d
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/core-domain-events.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$repositories/core-domain-events.adoc[]
diff --git a/src/main/antora/modules/ROOT/pages/repositories/core-extensions.adoc b/src/main/antora/modules/ROOT/pages/repositories/core-extensions.adoc
new file mode 100644
index 000000000..a7c2ff8d3
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/core-extensions.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$repositories/core-extensions.adoc[]
diff --git a/src/main/antora/modules/ROOT/pages/repositories/create-instances.adoc b/src/main/antora/modules/ROOT/pages/repositories/create-instances.adoc
new file mode 100644
index 000000000..2ae01801b
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/create-instances.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$repositories/create-instances.adoc[]
diff --git a/src/main/antora/modules/ROOT/pages/repositories/custom-implementations.adoc b/src/main/antora/modules/ROOT/pages/repositories/custom-implementations.adoc
new file mode 100644
index 000000000..c7615191a
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/custom-implementations.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$repositories/custom-implementations.adoc[]
diff --git a/src/main/antora/modules/ROOT/pages/repositories/definition.adoc b/src/main/antora/modules/ROOT/pages/repositories/definition.adoc
new file mode 100644
index 000000000..bd65a8af8
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/definition.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$repositories/definition.adoc[]
diff --git a/src/main/antora/modules/ROOT/pages/repositories/null-handling.adoc b/src/main/antora/modules/ROOT/pages/repositories/null-handling.adoc
new file mode 100644
index 000000000..081bac9f6
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/null-handling.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$repositories/null-handling.adoc[]
diff --git a/src/main/antora/modules/ROOT/pages/repositories/projections.adoc b/src/main/antora/modules/ROOT/pages/repositories/projections.adoc
new file mode 100644
index 000000000..6168b162d
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/projections.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$repositories/projections.adoc[]
diff --git a/src/main/antora/modules/ROOT/pages/repositories/query-keywords-reference.adoc b/src/main/antora/modules/ROOT/pages/repositories/query-keywords-reference.adoc
new file mode 100644
index 000000000..e495eddc6
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/query-keywords-reference.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$repositories/query-keywords-reference.adoc[]
diff --git a/src/main/antora/modules/ROOT/pages/repositories/query-methods-details.adoc b/src/main/antora/modules/ROOT/pages/repositories/query-methods-details.adoc
new file mode 100644
index 000000000..dfe481495
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/query-methods-details.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$repositories/query-methods-details.adoc[]
diff --git a/src/main/antora/modules/ROOT/pages/repositories/query-return-types-reference.adoc b/src/main/antora/modules/ROOT/pages/repositories/query-return-types-reference.adoc
new file mode 100644
index 000000000..a73c3201d
--- /dev/null
+++ b/src/main/antora/modules/ROOT/pages/repositories/query-return-types-reference.adoc
@@ -0,0 +1 @@
+include::{commons}@data-commons::page$repositories/query-return-types-reference.adoc[]
diff --git a/src/main/antora/resources/antora-resources/antora.yml b/src/main/antora/resources/antora-resources/antora.yml
new file mode 100644
index 000000000..b6230226c
--- /dev/null
+++ b/src/main/antora/resources/antora-resources/antora.yml
@@ -0,0 +1,19 @@
+version: ${antora-component.version}
+prerelease: ${antora-component.prerelease}
+
+asciidoc:
+ attributes:
+ copyright-year: ${current.year}
+ version: ${project.version}
+ springversionshort: ${spring.short}
+ springversion: ${spring}
+ attribute-missing: 'warn'
+ commons: ${springdata.commons.docs}
+ include-xml-namespaces: false
+ spring-data-commons-docs-url: https://docs.spring.io/spring-data/commons/reference
+ spring-data-commons-javadoc-base: https://docs.spring.io/spring-data/commons/docs/${springdata.commons}/api/
+ spring-framework-docs: https://docs.spring.io/spring-framework/reference/{springversionshort}
+ spring-framework-javadoc: https://docs.spring.io/spring-framework/docs/${spring}/javadoc-api
+ springhateoasversion: ${spring-hateoas}
+ releasetrainversion: ${releasetrain}
+ store: Couchbase
diff --git a/src/main/asciidoc/configuration.adoc b/src/main/asciidoc/configuration.adoc
deleted file mode 100644
index a57354808..000000000
--- a/src/main/asciidoc/configuration.adoc
+++ /dev/null
@@ -1,109 +0,0 @@
-[[couchbase.configuration]]
-= Installation & Configuration
-
-This chapter describes the common installation and configuration steps needed when working with the library.
-
-[[installation]]
-== Installation
-
-All versions intended for production use are distributed across Maven Central and the Spring release repository.
-As a result, the library can be included like any other maven dependency:
-
-.Including the dependency through maven
-====
-[source,xml,subs="+attributes"]
-----
-
- org.springframework.data
- spring-data-couchbase
- {version}
-
-----
-====
-
-This will pull in several dependencies, including the underlying Couchbase Java SDK, common Spring dependencies and also Jackson as the JSON mapping infrastructure.
-
-You can also grab snapshots from the https://repo.spring.io/ui/repos/tree/General/libs-snapshot/org/springframework/data/spring-data-couchbase[spring snapshot repository] ( \https://repo.spring.io/libs-snapshot ) and milestone releases from the https://repo.spring.io/ui/repos/tree/General/libs-milestone/org/springframework/data/spring-data-couchbase[spring milestone repository] ( \https://repo.spring.io/libs-milestone ).
-Here is an example on how to use the current SNAPSHOT dependency:
-
-.Using a snapshot version
-====
-[source,xml]
-----
-
- org.springframework.data
- spring-data-couchbase
- ${version}-SNAPSHOT
-
-
-
- spring-libs-snapshot
- Spring Snapshot Repository
- https://repo.spring.io/libs-snapshot
-
-----
-====
-
-Once you have all needed dependencies on the classpath, you can start configuring it.
-Only Java config is supported (XML config has been removed in 4.0).
-
-[[configuration-java]]
-== Annotation-based Configuration ("JavaConfig")
-
-To get started, all you need to do is subclcass the `AbstractCouchbaseConfiguration` and implement the abstract methods.
-
-.Extending the `AbstractCouchbaseConfiguration`
-====
-[source,java]
-----
-
-@Configuration
-public class Config extends AbstractCouchbaseConfiguration {
-
- @Override
- public String getConnectionString() {
- return "couchbase://127.0.0.1";
- }
-
- @Override
- public String getUserName() {
- return "Administrator";
- }
-
- @Override
- public String getPassword() {
- return "password";
- }
-
- @Override
- public String getBucketName() {
- return "travel-sample";
- }
-}
-----
-====
-
-The connection string is made up of a list of hosts and an optional scheme (`couchbase://`) as shown in the code above.
-All you need to provide is a list of Couchbase nodes to bootstrap into (separated by a `,`). Please note that while one
-host is sufficient in development, it is recommended to add 3 to 5 bootstrap nodes here. Couchbase will pick up all nodes
-from the cluster automatically, but it could be the case that the only node you've provided is experiencing issues while
-you are starting the application.
-
-The `userName` and `password` are configured in your Couchbase Server cluster through RBAC (role-based access control).
-The `bucketName` reflects the bucket you want to use for this configuration.
-
-Additionally, the SDK environment can be tuned by overriding the `configureEnvironment` method which takes a
-`ClusterEnvironment.Builder` to return a configured `ClusterEnvironment`.
-
-Many more things can be customized and overridden as custom beans from this configuration (for example repositories,
-validation and custom converters).
-
-TIP: If you use `SyncGateway` and `CouchbaseMobile`, you may run into problem with fields prefixed by `_`.
-Since Spring Data Couchbase by default stores the type information as a `_class` attribute this can be problematic.
-Override `typeKey()` (for example to return `MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE`) to change the
-name of said attribute.
-
-If you start your application, you should see Couchbase INFO level logging in the logs, indicating that the underlying
-Couchbase Java SDK is connecting to the database. If any errors are reported, make sure that the given credentials
-and host information are correct.
-
diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc
deleted file mode 100644
index 9def75779..000000000
--- a/src/main/asciidoc/index.adoc
+++ /dev/null
@@ -1,43 +0,0 @@
-= Spring Data Couchbase - Reference Documentation
-Michael Nitschinger, Oliver Gierke, Simon Baslé, Michael Reiche
-:revnumber: {version}
-:revdate: {localdate}
-:spring-data-commons-docs: ../../../../spring-data-commons/src/main/asciidoc
-
-(C) 2014-2022 The original author(s).
-
-NOTE: Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
-
-toc::[]
-
-include::preface.adoc[]
-include::{spring-data-commons-docs}/upgrade.adoc[leveloffset=+1]
-
-[[reference]]
-= Reference Documentation
-
-:leveloffset: +1
-include::configuration.adoc[]
-include::entity.adoc[]
-include::autokeygeneration.adoc[]
-include::{spring-data-commons-docs}/repositories.adoc[]
-include::repository.adoc[]
-include::reactiverepository.adoc[]
-include::template.adoc[]
-include::transactions.adoc[]
-include::collections.adoc[]
-include::fieldlevelencryption.adoc[]
-include::ansijoins.adoc[]
-include::caching.adoc[]
-:leveloffset: -1
-
-[[appendix]]
-= Appendix
-
-:numbered!:
-:leveloffset: +1
-include::{spring-data-commons-docs}/repository-namespace-reference.adoc[]
-include::{spring-data-commons-docs}/repository-populator-namespace-reference.adoc[]
-include::{spring-data-commons-docs}/repository-query-keywords-reference.adoc[]
-include::{spring-data-commons-docs}/repository-query-return-types-reference.adoc[]
-:leveloffset: -1
diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc
deleted file mode 100644
index 395c67e03..000000000
--- a/src/main/asciidoc/preface.adoc
+++ /dev/null
@@ -1,18 +0,0 @@
-[[couchbase.preface]]
-= Preface
-
-This reference documentation describes the general usage of the Spring Data Couchbase library.
-
-[[metadata]]
-[preface]
-== Project Information
-
-* Version control - https://github.com/spring-projects/spring-data-couchbase
-* Bugtracker - https://jira.springsource.org/browse/DATACOUCH
-* Release repository - https://repo.spring.io/libs-release
-* Milestone repository - https://repo.spring.io/libs-milestone
-* Snapshot repository - https://repo.spring.io/libs-snapshot
-
-[preface]
-include::migrating.adoc[leveloffset=+1]
-
diff --git a/src/main/java/com/couchbase/client/java/transactions/AttemptContextReactiveAccessor.java b/src/main/java/com/couchbase/client/java/transactions/AttemptContextReactiveAccessor.java
deleted file mode 100644
index 05c0e5596..000000000
--- a/src/main/java/com/couchbase/client/java/transactions/AttemptContextReactiveAccessor.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-/*
- * Copyright 2021-2023 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 com.couchbase.client.java.transactions;
-
-import com.couchbase.client.core.annotation.Stability;
-import com.couchbase.client.core.transaction.CoreTransactionAttemptContext;
-import com.couchbase.client.java.codec.JsonSerializer;
-
-/**
- * To access the ReactiveTransactionAttemptContext held by TransactionAttemptContext
- *
- * @author Michael Reiche
- */
-@Stability.Internal
-public class AttemptContextReactiveAccessor {
- public static ReactiveTransactionAttemptContext createReactiveTransactionAttemptContext(
- CoreTransactionAttemptContext core, JsonSerializer jsonSerializer) {
- return new ReactiveTransactionAttemptContext(core, jsonSerializer);
- }
-}
diff --git a/src/main/java/org/springframework/data/couchbase/CouchbaseClientFactory.java b/src/main/java/org/springframework/data/couchbase/CouchbaseClientFactory.java
index 1901a0cd1..dc2a9ed5a 100644
--- a/src/main/java/org/springframework/data/couchbase/CouchbaseClientFactory.java
+++ b/src/main/java/org/springframework/data/couchbase/CouchbaseClientFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors
+ * Copyright 2012-2025 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.
diff --git a/src/main/java/org/springframework/data/couchbase/SimpleCouchbaseClientFactory.java b/src/main/java/org/springframework/data/couchbase/SimpleCouchbaseClientFactory.java
index 06cb5c5c0..3e82d71d0 100644
--- a/src/main/java/org/springframework/data/couchbase/SimpleCouchbaseClientFactory.java
+++ b/src/main/java/org/springframework/data/couchbase/SimpleCouchbaseClientFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors
+ * Copyright 2012-2025 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.
diff --git a/src/main/java/org/springframework/data/couchbase/cache/CacheKeyPrefix.java b/src/main/java/org/springframework/data/couchbase/cache/CacheKeyPrefix.java
index 96a47478a..64669acbf 100644
--- a/src/main/java/org/springframework/data/couchbase/cache/CacheKeyPrefix.java
+++ b/src/main/java/org/springframework/data/couchbase/cache/CacheKeyPrefix.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors
+ * Copyright 2012-2025 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.
diff --git a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCache.java b/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCache.java
index cc5944046..8ee5780e0 100644
--- a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCache.java
+++ b/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCache.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors
+ * Copyright 2012-2025 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.
@@ -15,6 +15,7 @@
*/
package org.springframework.data.couchbase.cache;
+
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
@@ -23,7 +24,6 @@
import java.util.concurrent.Callable;
import org.springframework.cache.support.AbstractValueAdaptingCache;
-import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
@@ -31,6 +31,13 @@
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
+/**
+ * Couchbase-backed Cache Methods that take a Class return non-wrapped objects - cache-miss cannot be distinguished from
+ * cached null - this is what AbstractValueAdaptingCache does Methods that do not take a Class return wrapped objects -
+ * the wrapper is null for cache-miss - the exception is T get(final Object key, final Callable<T> valueLoader), which
+ * does not return a wrapper because if there is a cache-miss, it gets the value from valueLoader (and caches it). There
+ * are anomalies with get(key, ValueLoader) - which returns non-wrapped object.
+ */
public class CouchbaseCache extends AbstractValueAdaptingCache {
private final String name;
@@ -70,11 +77,18 @@ public CouchbaseCacheWriter getNativeCache() {
return cacheWriter;
}
+ /**
+ * same as inherited, but passes clazz for transcoder
+ */
+ protected Object lookup(final Object key, Class> clazz) {
+ return cacheWriter.get(cacheConfig.getCollectionName(), createCacheKey(key), cacheConfig.getValueTranscoder(),
+ clazz);
+ }
+
@Override
protected Object lookup(final Object key) {
- return cacheWriter.get(cacheConfig.getCollectionName(), createCacheKey(key), cacheConfig.getValueTranscoder());
+ return lookup(key, Object.class);
}
-
/**
* Returns the configuration for this {@link CouchbaseCache}.
*/
@@ -97,33 +111,56 @@ public synchronized T get(final Object key, final Callable valueLoader) {
}
@Override
- public void put(final Object key, final Object value) {
- if (!isAllowNullValues() && value == null) {
+ @SuppressWarnings("unchecked")
+ public T get(final Object key, Class type) {
+ Object value = this.fromStoreValue(this.lookup(key, type));
+ if (value != null && type != null && !type.isInstance(value)) {
+ throw new IllegalStateException("Cached value is not of required type [" + type.getName() + "]: " + value);
+ } else {
+ return (T) value;
+ }
+ }
- throw new IllegalArgumentException(String.format(
- "Cache '%s' does not allow 'null' values. Avoid storing null via '@Cacheable(unless=\"#result == null\")' or "
- + "configure CouchbaseCache to allow 'null' via CouchbaseCacheConfiguration.",
- name));
+ public synchronized T get(final Object key, final Callable valueLoader, Class type) {
+ T value = get(key, type);
+ if (value == null) { // cannot distinguish between cache miss and cached null
+ value = valueFromLoader(key, valueLoader);
+ put(key, value);
}
+ return value;
+ }
+ @Override
+ public void put(final Object key, final Object value) {
cacheWriter.put(cacheConfig.getCollectionName(), createCacheKey(key), toStoreValue(value), cacheConfig.getExpiry(),
cacheConfig.getValueTranscoder());
}
@Override
public ValueWrapper putIfAbsent(final Object key, final Object value) {
- if (!isAllowNullValues() && value == null) {
- return get(key);
- }
Object result = cacheWriter.putIfAbsent(cacheConfig.getCollectionName(), createCacheKey(key), toStoreValue(value),
cacheConfig.getExpiry(), cacheConfig.getValueTranscoder());
- if (result == null) {
- return null;
- }
+ return toValueWrapper(result);
+ }
- return new SimpleValueWrapper(result);
+ /**
+ * Not sure why this isn't in AbstractValueAdaptingCache
+ *
+ * @param key
+ * @param value
+ * @param clazz
+ * @return
+ * @param
+ */
+ @SuppressWarnings("unchecked")
+ public T putIfAbsent(final Object key, final Object value, final Class clazz) {
+
+ Object result = cacheWriter.putIfAbsent(cacheConfig.getCollectionName(), createCacheKey(key),
+ toStoreValue(value), cacheConfig.getExpiry(), cacheConfig.getValueTranscoder(), clazz);
+
+ return (T) result;
}
@Override
@@ -168,6 +205,9 @@ protected String createCacheKey(final Object key) {
* @throws IllegalStateException if {@code key} cannot be converted to {@link String}.
*/
protected String convertKey(final Object key) {
+ if (key == null) {
+ throw new IllegalArgumentException(String.format("Cache '%s' does not allow 'null' key.", name));
+ }
if (key instanceof String) {
return (String) key;
}
diff --git a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheConfiguration.java b/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheConfiguration.java
index 625e42e56..a618c66ca 100644
--- a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheConfiguration.java
+++ b/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors
+ * Copyright 2012-2025 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.
@@ -62,7 +62,7 @@ public static CouchbaseCacheConfiguration defaultCacheConfig() {
/**
* Registers default cache key converters. The following converters get registered:
*
- *
{@link String} to {@link byte byte[]} using UTF-8 encoding.
+ *
{@link String} to byte using UTF-8 encoding.
*
{@link SimpleKey} to {@link String}
*
*
diff --git a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheManager.java b/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheManager.java
index 4c296ebe6..e18e09c23 100644
--- a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheManager.java
+++ b/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors
+ * Copyright 2012-2025 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.
@@ -28,7 +28,7 @@
import org.springframework.cache.Cache;
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;
import org.springframework.data.couchbase.CouchbaseClientFactory;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
public class CouchbaseCacheManager extends AbstractTransactionSupportingCacheManager {
diff --git a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheWriter.java b/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheWriter.java
index cc80e20a7..55450d7ca 100644
--- a/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheWriter.java
+++ b/src/main/java/org/springframework/data/couchbase/cache/CouchbaseCacheWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors
+ * Copyright 2012-2025 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.
@@ -18,7 +18,7 @@
import java.time.Duration;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import com.couchbase.client.java.codec.Transcoder;
@@ -48,6 +48,20 @@ public interface CouchbaseCacheWriter {
Object putIfAbsent(String collectionName, String key, Object value, @Nullable Duration expiry,
@Nullable Transcoder transcoder);
+ /**
+ * Write the given value to Couchbase if the key does not already exist.
+ *
+ * @param collectionName The cache name must not be {@literal null}.
+ * @param key The key for the cache entry. Must not be {@literal null}.
+ * @param value The value stored for the key. Must not be {@literal null}.
+ * @param expiry Optional expiration time. Can be {@literal null}.
+ * @param transcoder Optional transcoder to use. Can be {@literal null}.
+ * @param clazz Optional class for contentAs(clazz)
+ */
+ @Nullable
+ Object putIfAbsent(String collectionName, String key, Object value, @Nullable Duration expiry,
+ @Nullable Transcoder transcoder, @Nullable Class> clazz);
+
/**
* Get the binary value representation from Couchbase stored for the given key.
*
@@ -59,6 +73,18 @@ Object putIfAbsent(String collectionName, String key, Object value, @Nullable Du
@Nullable
Object get(String collectionName, String key, @Nullable Transcoder transcoder);
+ /**
+ * Get the binary value representation from Couchbase stored for the given key.
+ *
+ * @param collectionName must not be {@literal null}.
+ * @param key must not be {@literal null}.
+ * @param transcoder Optional transcoder to use. Can be {@literal null}.
+ * @param clazz Optional class for contentAs(clazz)
+ * @return {@literal null} if key does not exist.
+ */
+ @Nullable
+ Object get(String collectionName, String key, @Nullable Transcoder transcoder, @Nullable Class> clazz);
+
/**
* Remove the given key from Couchbase.
*
diff --git a/src/main/java/org/springframework/data/couchbase/cache/DefaultCouchbaseCacheWriter.java b/src/main/java/org/springframework/data/couchbase/cache/DefaultCouchbaseCacheWriter.java
index 635d0792f..20b6c9f5b 100644
--- a/src/main/java/org/springframework/data/couchbase/cache/DefaultCouchbaseCacheWriter.java
+++ b/src/main/java/org/springframework/data/couchbase/cache/DefaultCouchbaseCacheWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors
+ * Copyright 2012-2025 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.
@@ -18,12 +18,14 @@
import static com.couchbase.client.core.io.CollectionIdentifier.DEFAULT_COLLECTION;
import static com.couchbase.client.core.io.CollectionIdentifier.DEFAULT_SCOPE;
-import static com.couchbase.client.java.kv.GetOptions.*;
-import static com.couchbase.client.java.kv.InsertOptions.*;
-import static com.couchbase.client.java.kv.UpsertOptions.*;
-import static com.couchbase.client.java.query.QueryOptions.*;
+import static com.couchbase.client.java.kv.GetOptions.getOptions;
+import static com.couchbase.client.java.kv.InsertOptions.insertOptions;
+import static com.couchbase.client.java.kv.UpsertOptions.upsertOptions;
+import static com.couchbase.client.java.query.QueryOptions.queryOptions;
import static com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS;
+import io.micrometer.common.lang.Nullable;
+
import java.time.Duration;
import org.springframework.data.couchbase.CouchbaseClientFactory;
@@ -65,6 +67,22 @@ public void put(final String collectionName, final String key, final Object valu
@Override
public Object putIfAbsent(final String collectionName, final String key, final Object value, final Duration expiry,
final Transcoder transcoder) {
+ return putIfAbsent(collectionName, key, value, expiry, transcoder, Object.class);
+ }
+
+ /**
+ * same as above, plus clazz
+ *
+ * @param collectionName
+ * @param key
+ * @param value
+ * @param expiry
+ * @param transcoder
+ * @param clazz
+ */
+ @Override
+ public Object putIfAbsent(final String collectionName, final String key, final Object value, final Duration expiry,
+ final Transcoder transcoder, @Nullable final Class> clazz) {
InsertOptions options = insertOptions();
if (expiry != null) {
@@ -79,15 +97,20 @@ public Object putIfAbsent(final String collectionName, final String key, final O
return null;
} catch (final DocumentExistsException ex) {
// If the document exists, return the current one per contract
- return get(collectionName, key, transcoder);
+ return get(collectionName, key, transcoder, clazz);
}
}
@Override
public Object get(final String collectionName, final String key, final Transcoder transcoder) {
- // TODO .. the decoding side transcoding needs to be figured out?
+ return get(collectionName, key, transcoder, Object.class);
+ }
+
+ @Override
+ public Object get(final String collectionName, final String key, final Transcoder transcoder,
+ final Class> clazz) {
try {
- return getCollection(collectionName).get(key, getOptions().transcoder(transcoder)).contentAs(Object.class);
+ return getCollection(collectionName).get(key, getOptions().transcoder(transcoder)).contentAs(clazz);
} catch (DocumentNotFoundException ex) {
return null;
}
diff --git a/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java b/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java
index 9eacc4c26..3b24aaa8d 100644
--- a/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java
+++ b/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors
+ * Copyright 2012-2025 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.
@@ -26,12 +26,15 @@
import java.util.Map;
import java.util.Set;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
-import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.convert.PropertyValueConverterRegistrar;
@@ -94,6 +97,7 @@
* @author Subhashni Balakrishnan
* @author Jorge Rodriguez Martin
* @author Michael Reiche
+ * @author Vipul Gupta
*/
@Configuration
public abstract class AbstractCouchbaseConfiguration {
@@ -274,8 +278,7 @@ public String typeKey() {
@Bean
public MappingCouchbaseConverter mappingCouchbaseConverter(CouchbaseMappingContext couchbaseMappingContext,
CouchbaseCustomConversions couchbaseCustomConversions) {
- MappingCouchbaseConverter converter = new MappingCouchbaseConverter(couchbaseMappingContext, typeKey());
- converter.setCustomConversions(couchbaseCustomConversions);
+ MappingCouchbaseConverter converter = new MappingCouchbaseConverter(couchbaseMappingContext, typeKey(), couchbaseCustomConversions);
couchbaseMappingContext.setSimpleTypeHolder(couchbaseCustomConversions.getSimpleTypeHolder());
return converter;
}
@@ -374,19 +377,32 @@ public CouchbaseTransactionalOperator couchbaseTransactionalOperator(
return CouchbaseTransactionalOperator.create(couchbaseCallbackTransactionManager);
}
- @Bean
- @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
- public TransactionInterceptor transactionInterceptor(TransactionManager couchbaseTransactionManager) {
- TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
- TransactionInterceptor interceptor = new CouchbaseTransactionInterceptor(couchbaseTransactionManager,
- transactionAttributeSource);
- interceptor.setTransactionAttributeSource(transactionAttributeSource);
- if (couchbaseTransactionManager != null) {
- interceptor.setTransactionManager(couchbaseTransactionManager);
- }
- return interceptor;
- }
-
+ @Bean
+ @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
+ static BeanPostProcessor transactionInterceptorCustomizer(
+ ObjectProvider transactionManagerProvider, ConfigurableListableBeanFactory beanFactory) {
+
+ BeanPostProcessor processor = new BeanPostProcessor() {
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+ if (bean instanceof TransactionInterceptor) {
+ TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
+ TransactionManager transactionManager = transactionManagerProvider.getObject();
+ TransactionInterceptor interceptor = new CouchbaseTransactionInterceptor(transactionManager,
+ transactionAttributeSource);
+ interceptor.setTransactionAttributeSource(transactionAttributeSource);
+ if (transactionManager != null) {
+ interceptor.setTransactionManager(transactionManager);
+ }
+ return interceptor;
+ }
+ return bean;
+ }
+
+ };
+ beanFactory.addBeanPostProcessor(processor);
+ return processor;
+ }
/**
* Configure whether to automatically create indices for domain types by deriving the from the entity or not.
*/
@@ -412,10 +428,17 @@ public CustomConversions customConversions() {
* and {@link #couchbaseMappingContext(CustomConversions)}.
*
* @param cryptoManager
+ * @param objectMapper
* @return must not be {@literal null}.
*/
public CustomConversions customConversions(CryptoManager cryptoManager, ObjectMapper objectMapper) {
- List newConverters = new ArrayList();
+ List