4

I have a Spring boot (v2.3.0.RELEASE) application with spring-data-mongodb (v3.0.0).

Basically when I add @Version annotation in my document, the application fails when I am trying to update an existing document and the code is as follows:

My document is as follows:

    @Id
    private String paymentId;
    private String transactionId;
    private String transactionTypeCode;
    @Version
    private Integer version;

My repository is as follows:

public interface PaymentRepository extends MongoRepository<Payment, String>, PaymentRepositoryCustom {

       


}

The update that fails is as follows:

Optional<Payment> paymentSaved = Optional.ofNullable(paymentRepository.findMaxIdByRefer(request.getAdd().getRefer()));
populatePayment(paymentSaved, payment);
paymentRepository.save(payment);

public static void populatePayment( Optional<Payment> paymentSaved, Payment payment) {

    if (paymentSaved.isPresent() && !ObjectUtils.isEmpty(payment)) {
        payment.setTransactionId(paymentSaved.get().getTransactionId());
        payment.setCreationDate(paymentSaved.get().getCreationDate());
        payment.setPaymentId(paymentSaved.get().getPaymentId());
    }
}

The application fails on paymentRepository.save(payment) method with the following exception:

org.springframework.dao.DuplicateKeyException: E11000 duplicate key error collection: test.payment index: _id_ dup key: { _id: ObjectId('627a35b7f1ea29549008487e') }; nested exception is com.mongodb.MongoWriteException: E11000 duplicate key error collection: test.payment index: _id_ dup key: { _id: ObjectId('627a35b7f1ea29549008487e') }
at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:99)
at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2863)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:568)
at org.springframework.data.mongodb.core.MongoTemplate.insertDocument(MongoTemplate.java:1436)
at org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:1236)
at org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:1168)
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:84)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.springframework.data.repository.core.support.ImplementationInvocationMetadata.invoke(ImplementationInvocationMetadata.java:72)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:382)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:205)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:549)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:155)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke
    

It looks like it is trying to do an insert instead of update when I add the @Version annotation, any idea how i can resolve this issue please?

However, I cannot remove the @Version annotation.

user1999453
  • 1,297
  • 4
  • 29
  • 65
  • Have you tried initializing the version field with a default version? Example: `private Integer version = 0;`. This should prevent this, according to this post: https://stackoverflow.com/questions/36993477/spring-mongorepository-save-throws-duplicate-key-exception – jAC May 10 '22 at 10:17
  • Hi @jAC I tried it but get the following error:at org.springframework.data.mapping.TargetAwareIdentifierAccessor.getRequiredIdentifier(TargetAwareIdentifierAccessor.java:47) – user1999453 May 10 '22 at 10:41

1 Answers1

2

I have found the issue basically on update the version was null that is why it was trying to create a new payment instead of update.I have retrieved the version from DB and now the update works fine.

user1999453
  • 1,297
  • 4
  • 29
  • 65