Spring Data Elasticsearch Repository deleteBy方法单元测试失效问题
首先,我注意到你的测试方法上加了@Transactional注解,这很可能就是导致删除操作不生效的核心原因——Elasticsearch本身并不支持Spring的声明式事务模型。当测试方法带有这个注解时,Spring会尝试对ES操作进行事务管理,但ES的写入/删除操作并不会真正提交到集群,或者Spring Data Elasticsearch在事务上下文下会延迟执行操作,导致你的删除请求根本没有实际作用到ES中,而查询操作读取的还是事务内暂存的数据。
快速解决方案:移除@Transactional注解
直接删掉测试方法上的@Transactional,然后重新运行测试:
@Test // 去掉@Transactional public void deleteByOwningFacilityId() { // 原有测试代码不变 }
如果需要清理测试数据,避免不同测试用例之间的干扰,可以用@AfterEach注解来手动清理:
@AfterEach void cleanUp() { searchEntityRepository.deleteAll(); }
额外排查点:处理ES的近实时特性
如果移除事务注解后还是有问题,那可能是ES的近实时搜索机制导致的——写入/删除操作后,默认需要等待约1秒才能被查询到。在测试环境中,你可以手动触发索引刷新,确保数据立即可见:
- 注入
ElasticsearchOperations(或RestHighLevelClient):
@Autowired private ElasticsearchOperations elasticsearchOperations;
- 在保存和删除操作后调用刷新:
// 保存数据后刷新 for (SearchEntityType type : SearchEntityType.values()) { searchEntityService.save(/* ... */); } elasticsearchOperations.refresh("search-object"); // 刷新指定索引 // 删除数据后刷新 searchEntityService.deleteByOwningFacilityId(5l); elasticsearchOperations.refresh("search-object");
其他建议
替换Jest客户端:Jest已经停止维护,新版本的Spring Data Elasticsearch默认使用官方的
RestHighLevelClient,兼容性和稳定性更好。你可以移除spring-boot-starter-data-jest依赖,直接使用spring-boot-starter-data-elasticsearch自带的客户端。开启调试日志:如果问题还存在,可以开启ES相关的调试日志,确认删除请求是否真的发送到了ES集群:
在application-test.properties中添加:logging.level.org.springframework.data.elasticsearch=DEBUG logging.level.io.searchbox.client.JestClient=DEBUG查看日志是否有删除请求的记录,以及ES返回的响应是否正常。
用count方法验证:在测试中添加count查询,确认删除前后数据量的变化,比如:
long countBefore = searchEntityRepository.count(); searchEntityService.deleteByOwningFacilityId(5l); long countAfter = searchEntityRepository.count(); Assert.assertEquals(0, countAfter);
内容的提问来源于stack exchange,提问作者SimonH

