Spring Data Solr保存实体后未返回自动生成ID的问题咨询
这是Spring Data Solr的设计行为,而非Bug
先给你明确结论:这不是Bug,而是Spring Data Solr在处理Solr服务器端生成ID场景下的设计特性,我来拆解下原因和解决办法:
为什么会出现这种情况?
当你保存一个没有指定id的Shop实体时:
- Solr服务器会自动生成UUID作为文档ID(也就是你在Solr控制台看到的那些随机ID)
- Spring Data Solr的
SolrCrudRepository.save()底层调用的是SolrClient的add()方法,这个操作默认是异步提交的,不会同步返回Solr服务器生成的ID - 方法返回的
savedShop其实还是你传入的原对象的引用,框架并没有自动去Solr服务器查询最新生成的ID来更新它
而repository.findAll()能拿到正确ID,是因为这个方法会直接查询Solr服务器的索引,此时异步提交的文档已经被索引完成,自然能获取到服务器生成的ID。
怎么解决?
如果你需要在save后立即拿到生成的ID,可以试试这几种方案:
方案1:保存后手动查询实体
如果你的实体有唯一标识(比如name字段),可以在保存并提交后,通过这个唯一标识去查询:
// 先在ShopRepository里添加查询方法 @Repository interface ShopRepository extends SolrCrudRepository<Shop, String>{ Shop findByName(String name); } // 处理代码 void save() { Shop shop = new Shop() shop.name = 'shop1' log.info("before {}", shop) repository.save(shop) repository.flush() // 触发提交,确保文档被索引 Shop savedShop = repository.findByName('shop1') log.info("after {}", savedShop) }
方案2:用SolrTemplate手动处理提交和查询
直接使用SolrTemplate来操作,显式提交后立即查询:
@Autowired SolrTemplate solrTemplate void save() { Shop shop = new Shop() shop.name = 'shop1' log.info("before {}", shop) solrTemplate.saveBean(shop) solrTemplate.commit("bank") // 显式提交到指定的solr core // 按条件查询刚保存的实体 SimpleQuery query = new SimpleQuery("name:shop1") List<Shop> shops = solrTemplate.queryForList(query, Shop.class) if (!shops.isEmpty()) { log.info("after {}", shops.get(0)) } }
方案3:客户端生成ID(绕过服务器生成)
如果业务允许,你可以在客户端自己生成UUID作为ID,这样保存后返回的对象直接就有ID了:
@SolrDocument(solrCoreName = "bank") @Canonical class Shop { @Id @Field String id = UUID.randomUUID().toString() // 客户端生成UUID @Field String name }
这种方式最直接,不需要依赖Solr服务器生成ID,save后就能拿到ID值。
补充说明
Spring Data Solr的这种设计是出于性能考量——避免每次save都额外发起一次查询请求。如果你的业务场景必须立即获取服务器生成的ID,上面的方案都能解决问题。
内容的提问来源于stack exchange,提问作者Dmitrii Borovoi
相关产品推荐
相关产品推荐

