Field Level Encryption with Spring Boot

I have followed the documentation and I cannot get FLE to work in my SpringBoot Java application…

Whenever I attempt to use an @Encrypted annotation, it responds with the following Exception:

Request processing failed: java.lang.IllegalArgumentException: cryptoManager needed to encrypt/decrypt but it is null. Override needed for cryptoManager() method of org.springframework.data.couchbase.core.convert.AbstractCouchbaseConverter

Code is shown below:

@Configuration
@EnableCouchbaseRepositories("my.repo.under.here")
public class EncryptionConfig extends AbstractCouchbaseConfiguration {

        // Usual Setup
        @Override public String getConnectionString() { return "localhost"; }
        @Override public String getUserName() { return "Administrator"; }
        @Override public String getPassword() { return "admin123"; }
        @Override public String getBucketName() { return "my_bucket"; }

        /* provide a cryptoManager */
        @Override
        protected CryptoManager cryptoManager() {
            try {
                // Load the Java KeyStore
                KeyStore keyStore = KeyStore.getInstance("JCEKS");
                FileInputStream keyStoreStream = new FileInputStream("/Users/asd1983/my-keystore.jceks");
                keyStore.load(keyStoreStream, "test123".toCharArray());

                // Initialize the Keyring with the KeyStore
                Keyring keyring = new KeyStoreKeyring(keyStore, alias -> "keypassword");

                // AES-256 authenticated with HMAC SHA-512. Requires a 64-byte key.
                AeadAes256CbcHmacSha512Provider provider = AeadAes256CbcHmacSha512Provider.builder().keyring(keyring).build();

                CryptoManager cryptoManager = DefaultCryptoManager.builder().decrypter(provider.decrypter())
                        .defaultEncrypter(provider.encrypterForKey("my-key")).build();

                return cryptoManager;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
    }
}
@Document
public class Data {
  @Id
  private String id;
  @Encrypted
  private String password;
}
package my.repo.under.here;

@Repository
public interface DataRepository extends CouchbaseRepository<Data, String> { }

Hi @colin_sch - your definition looks correct. Do you have any other overrides in EncryptionConfig? Do you have a github repo you could share?

  • Mike

Hi @mreiche , I had a bit more of a play and it works well now!

One question, though, I have this kind of structure here:

@Document
public class Data {
  @Id
  private String id;
  private String password;
  @Encrypted
  private Person person;
}

public static class Person {
  private String name;
  private String phone;
}

So when I save this to the DB, it works fine (including the encrypted Person structure up in the DB). Then, when I attempt to read it again, it throws an Exception and says:

java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "value" is null] with root cause

Do I need to do anything special with the definition here, or what?

Thanks for your help!
Colin

Can you post the stack trace?
How do you read it? What method?

Hi @mreiche , Here is the entire strackTrace (at the bottom).

Before I get to that, I see what may be the potential problem. This is stored as the encrypted value, taken from the Couchbase DB:

"encrypted$person": {
    "alg": "AEAD_AES_256_CBC_HMAC_SHA512",
    "ciphertext": "sNtxPqZoaAmLRdWOXdEksebWzps+O9yzQtSAymnivAVLYBUjAQCLSBHA6I8nnMGYTzqYPPQEG3oM7N6vqsHNC4KjSitj869CAzUbKmuivwe5/0Kjg0ne6xAsLllAxP/y5eIT9AYGQ+wE8BetJe1gjFecCro0DuQdtp1rP6yRW4Y=",
    "kid": "my-key"
  },

Note: there is no "_class" defined for this (!)

2025-02-22T16:08:41.099+10:00 ERROR 33264 --- [m102-svc-omega] [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "value" is null] with root cause

java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "value" is null
	at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.readValue(MappingCouchbaseConverter.java:950) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
	Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Assembly trace from producer [reactor.core.publisher.MonoFlatMap] :
	reactor.core.publisher.Mono.flatMap(Mono.java:3179)
	org.springframework.data.couchbase.core.ReactiveFindByIdOperationSupport$ReactiveFindByIdSupport.lambda$one$4(ReactiveFindByIdOperationSupport.java:118)
Error has been observed at the following site(s):
	*________Mono.flatMap ⇢ at org.springframework.data.couchbase.core.ReactiveFindByIdOperationSupport$ReactiveFindByIdSupport.lambda$one$4(ReactiveFindByIdOperationSupport.java:118)
	*________Mono.flatMap ⇢ at org.springframework.data.couchbase.core.ReactiveFindByIdOperationSupport$ReactiveFindByIdSupport.one(ReactiveFindByIdOperationSupport.java:106)
	|_ Mono.onErrorResume ⇢ at org.springframework.data.couchbase.core.ReactiveFindByIdOperationSupport$ReactiveFindByIdSupport.one(ReactiveFindByIdOperationSupport.java:129)
	|_    Mono.onErrorMap ⇢ at org.springframework.data.couchbase.core.ReactiveFindByIdOperationSupport$ReactiveFindByIdSupport.one(ReactiveFindByIdOperationSupport.java:134)
	*__________Mono.error ⇢ at org.springframework.data.couchbase.core.ReactiveFindByIdOperationSupport$ReactiveFindByIdSupport.lambda$one$5(ReactiveFindByIdOperationSupport.java:133)
Original Stack Trace:
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.readValue(MappingCouchbaseConverter.java:950) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter$CouchbasePropertyValueProvider.getPropertyValue(MappingCouchbaseConverter.java:1124) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter$CouchbasePropertyValueProvider.getPropertyValue(MappingCouchbaseConverter.java:1063) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:72) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.mapping.model.ValueExpressionParameterValueProvider.getParameterValue(ValueExpressionParameterValueProvider.java:56) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.extractInvocationArguments(ClassGeneratingEntityInstantiator.java:301) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:273) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:98) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:281) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:263) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:232) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.CryptoConverter.coerceToValueRead(CryptoConverter.java:95) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.CryptoConverter.read(CryptoConverter.java:68) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.CryptoConverter.read(CryptoConverter.java:50) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.readValue(MappingCouchbaseConverter.java:975) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter$CouchbasePropertyValueProvider.getPropertyValue(MappingCouchbaseConverter.java:1129) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter$CouchbasePropertyValueProvider.getPropertyValue(MappingCouchbaseConverter.java:1063) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:72) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.mapping.model.ValueExpressionParameterValueProvider.getParameterValue(ValueExpressionParameterValueProvider.java:56) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.extractInvocationArguments(ClassGeneratingEntityInstantiator.java:301) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:273) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:98) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:281) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:263) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:220) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:95) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.AbstractTemplateSupport.decodeEntityBase(AbstractTemplateSupport.java:122) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.CouchbaseTemplateSupport.decodeEntity(CouchbaseTemplateSupport.java:67) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.core.NonReactiveSupportWrapper.lambda$decodeEntity$1(NonReactiveSupportWrapper.java:47) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at reactor.core.publisher.MonoSupplier.call(MonoSupplier.java:67) ~[reactor-core-3.7.2.jar:3.7.2]
		at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:146) ~[reactor-core-3.7.2.jar:3.7.2]
		at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.7.2.jar:3.7.2]
		at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.7.2.jar:3.7.2]
		at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:113) ~[reactor-core-3.7.2.jar:3.7.2]
		at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1865) ~[reactor-core-3.7.2.jar:3.7.2]
		at com.couchbase.client.core.Reactor$SilentMonoCompletionStage.lambda$subscribe$0(Reactor.java:213) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) ~[na:na]
		at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841) ~[na:na]
		at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na]
		at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147) ~[na:na]
		at com.couchbase.client.core.msg.BaseRequest.succeed(BaseRequest.java:155) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.decodeAndComplete(KeyValueMessageHandler.java:423) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.retryOrComplete(KeyValueMessageHandler.java:376) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.decode(KeyValueMessageHandler.java:355) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.channelRead(KeyValueMessageHandler.java:279) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.io.netty.kv.ServerPushHandler.channelRead(ServerPushHandler.java:60) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.io.netty.kv.MemcacheProtocolVerificationHandler.channelRead(MemcacheProtocolVerificationHandler.java:85) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.handler.flush.FlushConsolidationHandler.channelRead(FlushConsolidationHandler.java:152) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1357) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:868) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at com.couchbase.client.core.deps.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[core-io-3.7.7.jar:3.7.7+185e8ddc]
		at java.base/java.lang.Thread.run(Thread.java:842) ~[na:na]
	Suppressed: java.lang.Exception: #block terminated with an error
		at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:104) ~[reactor-core-3.7.2.jar:3.7.2]
		at reactor.core.publisher.Mono.block(Mono.java:1779) ~[reactor-core-3.7.2.jar:3.7.2]
		at org.springframework.data.couchbase.core.ExecutableFindByIdOperationSupport$ExecutableFindByIdSupport.one(ExecutableFindByIdOperationSupport.java:71) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.data.couchbase.repository.support.SimpleCouchbaseRepository.findById(SimpleCouchbaseRepository.java:98) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
		at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
		at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359) ~[spring-aop-6.2.2.jar:6.2.2]
		at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:277) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:515) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:284) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:752) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.2.jar:6.2.2]
		at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:174) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:149) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.2.jar:6.2.2]
		at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:69) ~[spring-data-commons-3.4.2.jar:3.4.2]
		at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.2.jar:6.2.2]
		at org.springframework.data.couchbase.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:173) ~[spring-data-couchbase-5.4.2.jar:5.4.2]
		at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.2.jar:6.2.2]
		at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.2.2.jar:6.2.2]
		at jdk.proxy2/jdk.proxy2.$Proxy120.findById(Unknown Source) ~[na:na]
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
		at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
		at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359) ~[spring-aop-6.2.2.jar:6.2.2]
		at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.2.2.jar:6.2.2]
		at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.2.2.jar:6.2.2]
		at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138) ~[spring-tx-6.2.2.jar:6.2.2]
		at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.2.jar:6.2.2]
		at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.2.2.jar:6.2.2]
		at jdk.proxy2/jdk.proxy2.$Proxy120.findById(Unknown Source) ~[na:na]
		at mine.me.it.service.CommsRequestService.createCommsRequest(CommsRequestService.java:33) ~[classes/:na]
		at mine.me.it.controller.CommsRequestController.createCommsRequest(CommsRequestController.java:23) ~[classes/:na]
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
		at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
		at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:257) ~[spring-web-6.2.2.jar:6.2.2]
		at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:190) ~[spring-web-6.2.2.jar:6.2.2]
		at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.2.2.jar:6.2.2]
		at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986) ~[spring-webmvc-6.2.2.jar:6.2.2]
		at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891) ~[spring-webmvc-6.2.2.jar:6.2.2]
		at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.2.2.jar:6.2.2]
		at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088) ~[spring-webmvc-6.2.2.jar:6.2.2]
		at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978) ~[spring-webmvc-6.2.2.jar:6.2.2]
		at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.2.jar:6.2.2]
		at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.2.2.jar:6.2.2]
		at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.34.jar:6.0]
		at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.2.jar:6.2.2]
		at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.34.jar:6.0]
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.2.2.jar:6.2.2]
		at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.2.jar:6.2.2]
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.2.2.jar:6.2.2]
		at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.2.jar:6.2.2]
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:114) ~[spring-web-6.2.2.jar:6.2.2]
		at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.2.jar:6.2.2]
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.2.2.jar:6.2.2]
		at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.2.jar:6.2.2]
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.34.jar:10.1.34]
		at java.base/java.lang.Thread.run(Thread.java:842) ~[na:na]

It shouldn’t need _class as it can get the type (Person) from Data. Do you have a repository that you can share?