Spring boot Mongo 更新:E11000 @Version 注释重复键错误

use*_*453 5 spring spring-data-jpa spring-data-mongodb spring-boot spring-mongodb

我有一个带有 spring-data-mongodb (v3.0.0) 的 Spring boot (v2.3.0.RELEASE) 应用程序。

基本上,当我在文档中添加@Version注释时,当我尝试更新现有文档时应用程序会失败,代码如下:

我的文档如下:

    @Id
    private String paymentId;
    private String transactionId;
    private String transactionTypeCode;
    @Version
    private Integer version;
Run Code Online (Sandbox Code Playgroud)

我的存储库如下:

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

       


}
Run Code Online (Sandbox Code Playgroud)

更新失败的情况如下:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

应用程序在paymentRepository.save(payment)方法上失败,但出现以下异常:

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
    
Run Code Online (Sandbox Code Playgroud)

当我添加@Version注释时,它似乎正在尝试执行插入而不是更新,请问我如何解决此问题?

但是,我无法删除@Version注释。

use*_*453 3

我发现问题基本上在更新时版本为空,这就是为什么它试图创建新的付款而不是更新。我已经从数据库检索了版本,现在更新工作正常。