From SDK2 to SDK3: A Comprehensive Guide for Spring Boot and Couchbase Users

Meltem Demir
Trendyol Tech
Published in
5 min readMar 21, 2023

As a Trendyol Search team, with the upgrade of Spring-Data-Couchbase dependency from version 3.1.4 to 4.4.5, the usage of Couchbase SDK also transitioned from SDK2 to SDK3, which affected the as-is usage in certain scenarios. This article will summarize the changes that were made and provide some guidance on how to migrate from the previous version to the latest one. We will explain the sdk upgrade with spring data couchbase upgrade. Let’s see what we changed.

Couchbase Server Version

The version of Couchbase Server used is important when upgrading to the SDK 3. The minimum version required is 5.5, but the recommended version is at least 6.0.x. It is better to use a version above 6.0.* for better compatibility with the new SDK.

Configuration Steps

  • The CouchbaseEnvironment from SDK 2 has been renamed to ClusterEnvironment in SDK 3. The new environment can be customized through a builder and is more flexible than its predecessor. The configuration steps have been cleaned up to be more easily discoverable.
// SDK 2 custom KV timeout
CouchbaseEnvironment env = DefaultCouchbaseEnvironment
.builder()
.kvTimeout(TimeUnit.SECONDS.toMillis(5))
.build();

// SDK 3 equivalent
ClusterEnvironment env = ClusterEnvironment
.builder() .timeoutConfig(TimeoutConfig.kvTimeout(Duration.ofSeconds(5))).build();
  • You can connect directly to bucket via username and password but if you want to specify environment variables differently from default values you should create ClusterOptions,
//SDK 3 option 1
Cluster.connect("127.0.0.1", "Administrator", "password");

//SDK 3 option 2 with custom values
Cluster.connect(connectionStringPersonalization, ClusterOptions.clusterOptions(
PasswordAuthenticator.create(userNamePersonalization, passwordPersonalization))
.environment(couchbaseClusterEnvironment));
  • The major change in the new version of the Spring Data Couchbase(4.4.5) is the switch from using bootstrap-hosts to connection-string. In the old version, bootstrap-hosts were of type List<String>, but now with connection-string, the type is String. However, since the value of the connection-string is split to convert it into a List<String>, the actual value remains the same. For example,
//spring-data-couchbase 3.* couchbase yml variable usage with spring boot class integration 

couchbase:
bootstrap-hosts: 127.0.0.1, 127.0.0.2
username: test
password: test

private List<String> bootstrapHosts;



//spring-data-couchbase 4.* couchbase yml variable usage with spring boot class integration
couchbase:
connection-string: 127.0.0.1, 127.0.0.2
username: test
password: test

private String connectionString;
  • In the previous version, we had to override the couchbaseCluster() method to provide custom configurations. However, this is no longer required. Nevertheless, if we want to set a timeout connection, we can create our own couchbaseCluster() method and set the timeout duration in it, as shown in the code example below:
@Bean(destroyMethod = "disconnect", name = couchbaseClusterName)
public Cluster couchbaseCluster() {
ClusterEnvironment env = ClusterEnvironment.builder()
.timeoutConfig(TimeoutConfig.connectTimeout(Duration.ofSeconds(this.connectTimeout)))
.build();
return super.couchbaseCluster(env);
}
  • In the new SDK, RBAC (role-based access control) is mandatory, so different properties need to be overridden in order to configure it. These include getConnectionString, getUserName, getPassword, and getBucketName. If you want to use certificate-based authentication or customize password authentication, you can override the authenticator method.
  • When using Couchbase, support for repositories is always available, but in order to use them, you must enable them either in general or for a specific namespace. If you are extending AbstractCouchbaseConfiguration, you can simply use the @EnableCouchbaseRepositories annotation. This annotation provides a range of options to narrow or customize the search path, with one of the most commonly used options being basePackages.
  • This part is important. Here, basePackages is crucial because spring boot can not autowire couchbaseConfiguration class. When we do not defined basePackages we got this type of error,
Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘com.couchbase.client.java.ReactiveCollection’ available: expected at least 1 bean which qualifies as autowire candidate.
  • Usage example,
//spring-data-couchbase 3.* version usage
@Configuration
@EnableCouchbaseRepositories(basePackages)
public class Config extends AbstractCouchbaseConfiguration {
//...
}


//spring-data-couchbase 4.* version equivalent
@Configuration
@EnableCouchbaseRepositories(basePackages = {"com.couchbase.example.repos"})
public class Config extends AbstractCouchbaseConfiguration {
//...
}

Import Changes

  • The usage of entities has not changed, but some imports have. These are,
  • com.couchbase.client.java.repository.annotation.Id replaced with org.springframework.data.annotation.Id
  • com.couchbase.client.java.repository.annotation.Field replaced with org.springframework.data.couchbase.core.mapping.Field

Coding Side

  • The new SDK no longer supports JsonDocument; instead, it uses JsonObject. JsonObject can be used to create and manipulate JSON data in memory, and it can be used to construct the content of a document that will be inserted into a bucket. However, when performing a CRUD operation on a document using the Collection interface, a MutationResult object is returned instead of a JsonDocument.
  • Previously, in Couchbase, bucket objects could open connections and use all available methods directly. However, this is no longer the case. Buckets can no longer access methods directly; instead, they must first open a collection. Therefore, the concept of a Cluster and a Bucket remains the same, but with the addition of Collections and Scopes, the architecture of Couchbase has become even more versatile.
//sdk 2 usage
Cluster cluster = Cluster.connect(connectionString, username, password);
Bucket bucket = cluster.bucket(bucketName);
JsonDocument jsonResult = bucket.get("documentId");
cluster.disconnect();



//sdk 3 equivalent
Cluster cluster = Cluster.connect(connectionString, username, password);
Collection collection = cluster.bucket(bucketName).defaultCollection();
GetResult getResult = collection.get("documentId");
cluster.disconnect();
  • Besides collections, we decided to use reactiveCollections because it is optimized for high-performance, non-blocking I/O and network concurrency.
  • Basic differences between collection and reactiveCollection usage is the reactiveCollection class in the Java Couchbase client provides additional functionality and optimization specifically for working with Couchbase collections. It provides a reactive API for CRUD operations on collections and supports advanced features like sub-document operations, durability constraints, and query execution. It also leverages the underlying Couchbase SDK’s optimizations for non-blocking I/O and network concurrency.
  • So using the reactiveCollection class can provide a more streamlined and optimized experience specifically for working with Couchbase collections.
//sdk 3 reactiveCollection equivalent
Cluster cluster = Cluster.connect(connectionString, username, password);
ReactiveCollection reactiveCollection = cluster.reactive().bucket(bucketName).defaultCollection();
Mono<GetResult> getResult = reactiveCollection.get("documentId");
cluster.disconnect();

Conclusion

In conclusion, upgrading to the Spring-Data-Couchbase dependency version 3.1.4 and above requires some changes in the configuration and coding side. The Couchbase server version should be at least 6.0.x and RBAC is now mandatory. The configuration steps have been simplified, and the ClusterEnvironment has been renamed to ClusterEnvironment and can be customized through a builder. We also discussed the changes in imports and the introduction of Collections and Scopes. Finally, the use of reactiveCollections provides additional functionality and optimization specifically for working with Couchbase collections. Overall, upgrading to the new version of Spring-Data-Couchbase provides better performance and more efficient usage of Couchbase.

Want to work in this team?

Be a part of something great! Trendyol is currently hiring. Visit the pages below for more information and to apply.

Have a look at the roles we’re looking for!

--

--