我有一个春季启动应用程序。我有entity:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document(COLLECTION_NAME)
public class PersonEntity {
public static final String COLLECTION_NAME = "person_info";
private static final String PERSON_NAME = "person_name";
@Id
private PersonId id;
@Field(name = PERSON_NAME)
private String personName;
@Indexed(name = "ttl_index", expireAfterSeconds=20)
private LocalDateTime date;
}
我有一个仓库接口:
public interface PersonRepository {
void saveWithTtl(PersonEntity entity);
}
存储库实现:
@Slf4j
@Repository
public class PersonRepositoryImpl implements PersonRepository {
private final int expireAfterSeconds;
private final ReactiveMongoTemplate mongoTemplate;
public PersonRepositoryImpl(@Value("${ttl.index}") int expireAfterSeconds,
ReactiveMongoTemplate mongoTemplate) {
this.expireAfterSeconds = expireAfterSeconds;
this.mongoTemplate = mongoTemplate;
}
@Override
public void saveWithTtl(PersonEntity entity) {
mongoTemplate.indexOps(PersonEntity.class)
.ensureIndex(new Index().on(PersonEntity.CREATED_AT, ASC)
.expire(expireAfterSeconds)).subscribe(result -> log.info("Ttl index has been created: {}", result));
mongoTemplate.save(entity).subscribe(result -> log.info("Entity has been saved: {}", result));
}
}
最后,我有一个不工作的测试:
@DataMongoTest
@Testcontainers
public class PersonRepositoryIT {
@Autowired
private ReactiveMongoTemplate mongoTemplate;
@Autowired
private PersonRepository repository;
@Container
private static MongoDbContainer mongoDbContainer = new MongoDbContainer();
@AfterEach
void cleanUp() {
repository.deleteAll();
}
@DynamicPropertySource
static void registerMongoProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.mongodb.uri", mongoDbContainer::getReplicaSetUrl);
}
@Test
public void shouldCreateAndDeleteRecordsAfterDelay_whenSaveWithTtl_givenDefinedTll() {
//given
PersonEntity givenEntity = PersonEntity.builder().createdAt(LocalDateTime.now())
.personName("Joe")
.id(PERSON_ID).build();
//when
repository.saveWithTtl(givenEntity);
//then
StepVerifier.create(mongoTemplate.estimatedCount(PersonEntity.COLLECTION_NAME))
.expectNext(1L)
.verifyComplete();
}
}
expectNext它失败了,因为它返回0而不是1。mongoTemplate.estimatedCount返回0
当我从Postman测试存储库时(repo正在调用内部服务),它在MongoDB中创建文档将ttl索引,如预期的那样。
在测试配置中,我设置了${ttl。
我做错了什么?
我不知道是不是太晚了,但是我今天遇到了同样的问题。我发现你的问题在寻找我的问题的答案,哈哈哈。
这个片段对我来说很有效:
@Container
public static MongoDBContainer container = new MongoDBContainer(DockerImageName.parse("mongo:6"));
@DynamicPropertySource
static void mongoDbProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.mongodb.uri", container::getReplicaSetUrl);
}
@Bean
public ReactiveMongoTemplate reactiveMongoTemplate() throws Exception {
container.start();
ConnectionString connectionString = new ConnectionString(container.getReplicaSetUrl());
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
MongoClient mongoClient = MongoClients.create(mongoClientSettings);
return new ReactiveMongoTemplate(mongoClient,"test");
}
显然ReactiveMongoTemplate默认情况下没有被注入,然后我创建了我自己的Bean,它工作了