We have a document that we save to a Couchbase DB. It has a timestamp field:
@Document
class Cat{
@Id
@GeneratedValue(strategy = GenerationStrategy.UNIQUE)
private String id;
@Field
Timestamp birthdateTimestamp;
We are able to save data into the field when creating the Cat:
Timestamp currentTimestamp = new Timestamp(new Date().getTime());
Cat cat = Cat.builder().birthdateTimestamp(currentTimestamp).build();
catRepository.save(cat); // extends CouchbaseRepository<Cat, String>
And the field can be seen in the DB correctly - "birthdateTimestamp": 1564570366644
However, when trying to read the Cat
from the DB, we get this error:
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.Long] to type [java.sql.Timestamp]] with root cause org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.Long] to type [java.sql.Timestamp] at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174) at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.readValue(MappingCouchbaseConverter.java:804) at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.access$400(MappingCouchbaseConverter.java:77) at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter$CouchbasePropertyValueProvider.getPropertyValue(MappingCouchbaseConverter.java:869) at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter$CouchbasePropertyValueProvider.getPropertyValue(MappingCouchbaseConverter.java:824) at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:71) at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:49) at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.extractInvocationArguments(ClassGeneratingEntityInstantiator.java:248) at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:221) at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:86) at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:236) at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:213) at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:171) at org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter.read(MappingCouchbaseConverter.java:77) at org.springframework.data.couchbase.core.CouchbaseTemplate.mapToEntity(CouchbaseTemplate.java:700) at org.springframework.data.couchbase.core.CouchbaseTemplate.findByN1QL(CouchbaseTemplate.java:448) at org.springframework.data.couchbase.repository.query.AbstractN1qlBasedQuery.executeCollection(AbstractN1qlBasedQuery.java:156) at org.springframework.data.couchbase.repository.query.AbstractN1qlBasedQuery.executeEntity(AbstractN1qlBasedQuery.java:162) at org.springframework.data.couchbase.repository.query.AbstractN1qlBasedQuery.executeDependingOnType(AbstractN1qlBasedQuery.java:135) at org.springframework.data.couchbase.repository.query.AbstractN1qlBasedQuery.execute(AbstractN1qlBasedQuery.java:106) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:590) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.data.couchbase.repository.support.ViewPostProcessor$ViewInterceptor.invoke(ViewPostProcessor.java:87) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) at com.sun.proxy.$Proxy130.findByCustomerNameAndProjectName(Unknown Source)
What are we doing wrong?
It looks like the value is being stored in the DB in an Epoch format.
Instead of trying to convert the epoch directly to a sql Timestamp, you can stored it as a long instead, i.e.
@Field
long birthdateTimestamp;
Then to convert from the epoch format to a sql Timestamp, you can use something like the following.
new Timestamp(object.getBirthdateTimestamp())