尝试使用React流查询和更新mongodb的某些记录时,我看到以下错误:
org.springframework.dao.DuplicateKeyException: E11000 duplicate key error collection: testtrans.submission index: _id_ dup key: { _id: ObjectId('600b10b2fbac4f4483af3e67') }; nested exception is com.mongodb.MongoWriteException
我不确定我做错了什么;如何在单个事务中使用reactive mongo查询结果并将结果保存到数据库中?
我的服务级别:
package com.example.reactivemongotransaction.service;
import com.example.reactivemongotransaction.dto.Submission;
import com.example.reactivemongotransaction.repository.SubmissionRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Slf4j
@Service
public class SubmissionService {
@Autowired
private SubmissionRepository submissionRepository;
public Mono<Submission> saveSubmission(Submission submission) {
log.debug("saving {}", submission);
return submissionRepository.save(submission);
}
@Transactional
public Flux<Submission> lockSubmissions() {
log.debug("setting all locked");
Flux<Submission> submissionFlux = submissionRepository.findAllByLockedFalse();
return submissionFlux
.map(submission -> submission.setLocked(true))
.flatMap(submission -> submissionRepository.save(submission));
}
}
我的配置:
@Configuration
@EnableMongoAuditing
@EnableTransactionManagement
public class MongoConfiguration {
@Bean
public ReactiveTransactionManager transactionManager(ReactiveMongoDatabaseFactory dbFactory) {
return new ReactiveMongoTransactionManager(dbFactory);
}
}
控制器:
@RestController
@RequestMapping("/submissions")
public class SubmissionController {
@Autowired
private SubmissionService submissionService;
@PostMapping
public Mono<Submission> saveSubmission(final @RequestBody Submission submission) {
return submissionService.saveSubmission(submission);
}
@GetMapping("/lockall")
public Flux<Submission> lockAll() {
return submissionService.lockSubmissions();
}
}
型号:
@ToString
@Getter
@Setter
@Accessors(chain = true)
@Document(collection = "submission")
@TypeAlias("payload")
public class Submission implements Persistable<String> {
@Id
private String id;
@Field("role_name")
@Indexed(unique = true)
private String role;
@CreatedDate
private ZonedDateTime created;
@LastModifiedDate
private ZonedDateTime updated;
private Boolean deleted;
private Boolean enabled;
private boolean locked;
@Override
@JsonIgnore
public boolean isNew() {
if(getCreated() == null)
return true;
else
return false;
}
}
存储库:
public interface SubmissionRepository extends ReactiveMongoRepository<Submission, String> {
Flux<Submission> findAllByLockedFalse();
}
主要类别:
@EnableReactiveMongoRepositories
@SpringBootApplication
public class ReactivemongotransactionApplication {
public static void main(String[] args) {
SpringApplication.run(ReactivemongotransactionApplication.class, args);
}
}
应用程序.yml:
spring:
data:
mongodb:
uri: 'mongodb://localhost:27017/testtrans'
server:
port: 8280
Mavenpom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>reactivemongotransaction</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>reactivemongotransaction</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<lombok.version>1.18.6</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
我的要求是 GET http://localhost:8280/submissions/lockall
返回500。日志显示错误,例如:
com.mongodb.MongoWriteException: E11000 duplicate key error collection: testtrans.submission index: _id_ dup key: { _id: ObjectId('600b10b2fbac4f4483af3e67') }
at com.mongodb.internal.async.client.AsyncMongoCollectionImpl.lambda$executeSingleWriteRequest$9(AsyncMongoCollectionImpl.java:1075) ~[mongodb-driver-core-4.1.1.jar:na]
1条答案
按热度按时间ufj5ltwl1#
这个问题与
@CreatedDate
未设置(请参阅SpringBoot2.4.3中的@enablemongoauditing和@createddate auditing not working)。通过还原解决
spring-boot-starter-parent
至2.3.5.版本。