Spring Data Couchbase Transactions error when startup

Hi, I’m absolute beginner of couchbase and I’m trying to make use of transactions in my spring boot application integrated with couchbase server.
I’ve configured the bean for injecting dependency of Transactions from com.couchbase.transactions package in my configuration class.
But when I start the application, some error logs as below are generated continuously.

2021-02-05 17:28:57.823  INFO 20650 --- [      cb-events] com.couchbase.transactions.clientrecord  : [com.couchbase.transactions.clientrecord][TransactionLogEvent] fbeedc02-87fd-42e5-844e-76183bcb0a2a retrying processing client record on error 'java.lang.NullPointerException'
2021-02-05 17:28:57.823  INFO 20650 --- [      cb-events] com.couchbase.transactions.clientrecord  : [com.couchbase.transactions.clientrecord][TransactionLogEvent] fbeedc02-87fd-42e5-844e-76183bcb0a2a retrying processing client record on error 'java.lang.NullPointerException'
2021-02-05 17:28:58.338  INFO 20650 --- [      cb-events] com.couchbase.transactions.cleanup.lost  : [com.couchbase.transactions.cleanup.lost][TransactionLogEvent] lost/testcache/_default/clientId=fbeed retrying lost cleanup on error 'java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 500ms in 'retryWhen' (and no fallback has been configured)'
2021-02-05 17:29:00.485  WARN 20650 --- [      cb-events] com.couchbase.endpoint                   : [com.couchbase.endpoint][UnexpectedEndpointDisconnectedEvent] The remote side disconnected the endpoint unexpectedly {"circuitBreaker":"DISABLED","coreId":"0xb67d010600000001","local":"","remote":"","type":"SEARCH"}
2021-02-05 17:29:00.485  WARN 20650 --- [      cb-events] com.couchbase.endpoint                   : [com.couchbase.endpoint][UnexpectedEndpointDisconnectedEvent] The remote side disconnected the endpoint unexpectedly {"circuitBreaker":"DISABLED","coreId":"0xb67d010600000001","local":"","remote":"","type":"SEARCH"}
2021-02-05 17:29:00.485  WARN 20650 --- [      cb-events] com.couchbase.endpoint                   : [com.couchbase.endpoint][UnexpectedEndpointDisconnectedEvent] The remote side disconnected the endpoint unexpectedly {"circuitBreaker":"DISABLED","coreId":"0xb67d010600000001","local":"","remote":"","type":"QUERY"}
  • Couchbase server version: 6.6
  • Spring Boot version: 2.3.1
  • spring-data-couchbase version: 4.0.6
  • couchbase java-client version: 3.1.0
  • couchbase-transactions version: 1.1.0

Is there any possible missing configurations?
If you need more information, please let me know.
Thanks in advance for any help.

Hi @hayden
Could you try upgrading to latest version of couchbase-transactions, 1.1.4? 1.1.0 is rather old now. I don’t know if it will resolve your problem but there have been changes around the client record logic.

Hi @graham.pople ,
After I changed the version of couchbase-transactions to 1.1.4 , the errors didn’t occur.
Thanks for your help :slight_smile:
But there is another issue, when I try to get my document by context in transaction,

TransactionGetResult doc = ctx.get(couchbaseClientFactory.getDefaultCollection(), docKey);

exceptions as below are thrown.


com.couchbase.transactions.error.TransactionFailed: Transaction has failed with cause 'com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $'
	at com.couchbase.transactions.TransactionsReactive.executeHandleErrorsPostRetry(TransactionsReactive.java:305)
	at com.couchbase.transactions.TransactionsReactive.lambda$executeTransaction$4(TransactionsReactive.java:134)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:88)
	at reactor.core.publisher.SerializedSubscriber.onError(SerializedSubscriber.java:124)
	at reactor.core.publisher.FluxRetryWhen$RetryWhenMainSubscriber.whenError(FluxRetryWhen.java:213)
	at reactor.core.publisher.FluxRetryWhen$RetryWhenOtherSubscriber.onError(FluxRetryWhen.java:255)
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:406)
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onNext(FluxConcatMap.java:243)
	at reactor.core.publisher.FluxIndex$IndexSubscriber.onNext(FluxIndex.java:95)
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:114)
	at reactor.core.publisher.DirectProcessor$DirectInner.onNext(DirectProcessor.java:333)
	at reactor.core.publisher.DirectProcessor.onNext(DirectProcessor.java:142)
	at reactor.core.publisher.SerializedSubscriber.onNext(SerializedSubscriber.java:99)
	at reactor.core.publisher.FluxRetryWhen$RetryWhenMainSubscriber.onError(FluxRetryWhen.java:180)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:100)
	at reactor.core.publisher.Operators$MonoSubscriber.onError(Operators.java:1829)
	at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onError(MonoIgnoreThen.java:306)
	at reactor.core.publisher.Operators.error(Operators.java:196)
	at reactor.core.publisher.MonoError.subscribe(MonoError.java:52)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:153)
	at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4219)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:97)
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onError(FluxPeekFuseable.java:227)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:165)
	at reactor.core.publisher.Operators$MonoSubscriber.onError(Operators.java:1829)
	at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onError(MonoIgnoreThen.java:306)
	at reactor.core.publisher.Operators$MonoSubscriber.onError(Operators.java:1829)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreInner.onError(MonoIgnoreThen.java:235)
	at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:214)
	at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:214)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:100)
	at reactor.core.publisher.Operators.error(Operators.java:196)
	at reactor.core.publisher.MonoError.subscribe(MonoError.java:52)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4219)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:97)
	at reactor.core.publisher.FluxSubscribeOnCallable$CallableSubscribeOnSubscription.run(FluxSubscribeOnCallable.java:228)
	at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68)
	at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28)
	at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
	Suppressed: java.lang.Exception: #block terminated with an error
		at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99)
		at reactor.core.publisher.Mono.block(Mono.java:1679)
		at com.couchbase.transactions.Transactions.run(Transactions.java:201)
		at sample.playlist.service.CouchbaseTest.testDocumentGet(CouchbaseTest.java:210)
		at 
Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
	at com.google.gson.Gson.fromJson(Gson.java:944)
	at com.google.gson.Gson.fromJson(Gson.java:897)
	at com.google.gson.Gson.fromJson(Gson.java:846)
	at com.google.gson.Gson.fromJson(Gson.java:817)
	at sample.playlist.couchbase.CouchbaseConfig$1.deserialize(CouchbaseConfig.java:94)
	at com.couchbase.client.java.kv.LookupInResult.contentAs(LookupInResult.java:105)
	at com.couchbase.transactions.TransactionGetResult.createFrom(TransactionGetResult.java:370)
	at com.couchbase.transactions.components.DocumentGetter.lambda$justGetDoc$5(DocumentGetter.java:172)
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:100)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:73)
	at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:123)
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1782)
	at com.couchbase.client.core.Reactor$SilentMonoCompletionStage.lambda$subscribe$0(Reactor.java:178)
	at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:859)
	at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:837)
	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
	at com.couchbase.client.core.msg.BaseRequest.succeed(BaseRequest.java:147)
	at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.decodeAndComplete(KeyValueMessageHandler.java:337)
	at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.decode(KeyValueMessageHandler.java:316)
	at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.channelRead(KeyValueMessageHandler.java:242)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at com.couchbase.client.core.io.netty.kv.MemcacheProtocolVerificationHandler.channelRead(MemcacheProtocolVerificationHandler.java:84)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at com.couchbase.client.core.deps.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
	at com.couchbase.client.core.deps.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at com.couchbase.client.core.deps.io.netty.handler.flush.FlushConsolidationHandler.channelRead(FlushConsolidationHandler.java:152)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at com.couchbase.client.core.deps.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at com.couchbase.client.core.deps.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at com.couchbase.client.core.deps.io.netty.channel.kqueue.AbstractKQueueStreamChannel$KQueueStreamUnsafe.readReady(AbstractKQueueStreamChannel.java:544)
	at com.couchbase.client.core.deps.io.netty.channel.kqueue.AbstractKQueueChannel$AbstractKQueueUnsafe.readReady(AbstractKQueueChannel.java:382)
	at com.couchbase.client.core.deps.io.netty.channel.kqueue.KQueueEventLoop.processReady(KQueueEventLoop.java:211)
	at com.couchbase.client.core.deps.io.netty.channel.kqueue.KQueueEventLoop.run(KQueueEventLoop.java:289)
	at com.couchbase.client.core.deps.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
	at com.couchbase.client.core.deps.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at com.couchbase.client.core.deps.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	... 1 more
Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
	at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:351)
	at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:70)
	at com.google.gson.Gson.fromJson(Gson.java:932)
	... 48 more

The body of the document I try to get, as the error log said, it isn’t json array but object.

{
    "result": [
        {
            "track_id": 580,
            "track_title": "Blue"
        }
    ]
}

Does it mean the document retrieved by get method in AttemptContext should be json array?

Hi @hayden
No you can retrieve any JSON document, that should be fine.

The transactions library itself, and the underlying Java SDK, don’t use Google GSON anywhere. I think what’s happened here is that you’re using a custom JSON serializer with the Java SDK, specifying Google GSON. And that the transactions library is using that serializer to decode the object here. I’m not sure why Google GSON is raising the error about the array vs object, it’s unclear why it would expect a JSON array here, but the broader issue is that the transactions library perhaps shouldn’t be using the Java SDK’s serializer in the first place here. Let me file an issue for that and investigate further.

As a temporary workaround, is it a possibility to remove the custom Google JSON custom JSON serializer from the Java SDK’s configuration?

@hayden

Java transactions library 1.1.5, released on Monday, no longer uses the Java SDK’s configured JSON serializer for any internal JSON serialization/deserialization tasks. This should resolve the issue you saw there.