eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

1. Introduction

After our introduction to Spring Data Couchbase, in this second tutorial we focus on the support for entity validation (JSR-303), optimistic locking, and different levels of query consistency for a Couchbase document database.

2. Entity Validation

Spring Data Couchbase provides support for JSR-303 entity validation annotations. In order to take advantage of this feature, first we add the JSR-303 library to the dependencies section of our Maven project:

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>

Then we add an implementation of JSR-303. We will use the Hibernate implementation:

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>8.0.1.Final</version>
</dependency>

Finally, we add a validator factory bean and corresponding Couchbase event listener to our Couchbase configuration:

@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean() {
    return new LocalValidatorFactoryBean();
}

@Bean
public ValidatingCouchbaseEventListener validatingCouchbaseEventListener() {
    return new ValidatingCouchbaseEventListener(localValidatorFactoryBean());
}

The equivalent XML configuration looks like this:

<bean id="validator"
  class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

<bean id="validatingEventListener" 
  class="org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener"/>

Now we add JSR-303 annotations to our entity classes. When a constraint violation is encountered during a persistence operation, the operation will fail, throwing a ConstraintViolationException.

Here is a sample of the constraints that we can enforce involving our Student entities:

@Field
@NotNull
@Size(min=1, max=20)
@Pattern(regexp="^[a-zA-Z .'-]+$")
private String firstName;

...
@Field
@Past
private DateTime dateOfBirth;

3. Optimistic Locking

Spring Data Couchbase does not support multi-document transactions similar to those you can achieve in other Spring Data modules such as Spring Data JPA (via the @Transactional annotation), nor does it provide a rollback feature.

However it does support optimistic locking in much the same way as other Spring Data modules through the use of the @Version annotation:

@Version
private long version;

Under the covers, Couchbase uses what is known as a “compare and swap” (CAS) mechanism to achieve optimistic locking at the datastore level.

Each document in Couchbase has an associated CAS value that is modified automatically any time the document’s metadata or contents are altered. The use of the @Version annotation on a field causes that field to be populated with the current CAS value whenever a document is retrieved from Couchbase.

When you attempt to save the document back to Couchbase, this field is checked against the current CAS value in Couchbase. If the values do not match, the persistence operation will fail with an OptimisticLockingException.

It is extremely important to note that you should never attempt to access or modify this field in your code.

4. Query Consistency

When implementing a persistence layer over Couchbase, you have to consider the possibility of stale reads and writes. This is because when documents are inserted, updated, or deleted, it may take some time before the backing views and indexes are updated to reflect these changes.

And if you have a large dataset backed by a cluster of Couchbase nodes, this can become a significant problem, especially for a OLTP system.

Spring Data provides a robust level of consistency for some repository and template operations, plus a couple of options that let you determine the level of read and write consistency that is acceptable for your application.

4.1. Levels of Consistency

Spring Data allows you to specify various levels of query consistency and staleness for your application via the Consistency enum found in the org.springframework.data.couchbase.core.query package.

This enum defines the following levels of query consistency and staleness, from least to most strict:

  • EVENTUALLY_CONSISTENT
    • stale reads are allowed
    • indexes are updated according to Couchbase standard algorithm
  • UPDATE_AFTER
    • stale reads are allowed
    • indexes are updated after each request
  • DEFAULT_CONSISTENCY (same as READ_YOUR_OWN_WRITES)
  • READ_YOUR_OWN_WRITES
    • stale reads are not allowed
    • indexes are updated after each request
  • STRONGLY_CONSISTENT
    • stale reads are not allowed
    • indexes are updated after each statement

4.2. Default Behavior

Consider the case where you have documents that have been deleted from Couchbase, and the backing views and indexes have not been fully updated.

The CouchbaseRepository built-in method deleteAll() safely ignores documents that were found by the backing view but whose deletion is not yet reflected by the view.

Likewise, the CouchbaseTemplate built-in methods findByView and findBySpatialView offer a similar level of consistency by not returning documents that were initially found by the backing view but which have since been deleted.

For all other template methods, built-in repository methods, and derived repository query methods, according to the official Spring Data Couchbase 2.1.x documentation as of this writing, Spring Data uses a default consistency level of Consistency.READ_YOUR_OWN_WRITES.

It is worth noting that earlier versions of the library used a default of Consistency.UPDATE_AFTER.

Whichever version you are using, if you have any reservations about blindly accepting the default consistency level being provided, Spring offers two methods by which you can declaratively control the consistency level(s) being used, as the following subsections will describe.

4.3. Global Consistency Setting

If you are using Couchbase repositories and your application calls for a stronger level of consistency, or if it can tolerate a weaker level, then you may override the default consistency setting for all repositories by overriding the getDefaultConsistency() method in your Couchbase configuration.

Here is how you can override global consistency level in your Couchbase configuration class:

@Override
public Consistency getDefaultConsistency() {
    return Consistency.STRONGLY_CONSISTENT;
}

Here is the equivalent XML configuration:

<couchbase:template consistency="STRONGLY_CONSISTENT"/>

Note that the price of stricter levels of consistency is increased latency at query time, so be sure to tailor this setting based on the needs of your application.

For example, a data warehouse or reporting application in which data is often appended or updated only in a batch would be a good candidate for EVENTUALLY_CONSISTENT, whereas an OLTP application should probably tend towards the more strict levels such as READ_YOUR_OWN_WRITES or STRONGLY_CONSISTENT.

4.4. Custom Consistency Implementation

If you need more finely tuned consistency settings, you can override the default consistency level on a query-by-query basis by providing your own repository implementation for any queries whose consistency level you want to control independently and making use of the queryView and/or queryN1QL methods provided by CouchbaseTemplate.

Let’s implement a custom repository method called findByFirstNameStartsWith for our Student entity for which we do not want to allow stale reads.

First, create an interface containing the custom method declaration:

public interface CustomStudentRepository {
    List<Student> findByFirstNameStartsWith(String s);
}

Next, implement the interface, setting the Stale setting from the underlying Couchbase Java SDK to the desired level:

public class CustomStudentRepositoryImpl implements CustomStudentRepository {

    @Autowired
    private CouchbaseTemplate template;

    public List<Student> findByFirstNameStartsWith(String s) {
        return template.findByView(ViewQuery.from("student", "byFirstName")
          .startKey(s)
          .stale(Stale.FALSE),
          Student.class);
    }
}

Finally, by having your standard repository interface extend both the generic CrudRepository interface and your custom repository interface, clients will have access to all the built-in and derived methods of your standard repository interface, plus any custom methods you implemented in your custom repository class:

public interface StudentRepository extends CrudRepository<Student, String>,
  CustomStudentRepository {
    ...
}

5. Conclusion

In this tutorial, we showed how to implement JSR-303 entity validation and achieve optimistic locking capability when using the Spring Data Couchbase community project.

We also discussed the need for understanding query consistency in Couchbase, and we introduced the different levels of consistency provided by Spring Data Couchbase.

Finally, we explained the default consistency levels used by Spring Data Couchbase globally and for a few specific methods, and we demonstrated ways to override the global default consistency setting as well as how to override consistency settings on a query-by-query basis by providing your own custom repository implementations.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.

To learn more about Spring Data Couchbase, visit the official Spring Data Couchbase project site.

Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)