Spring Boot @Reference注解致MongoDB嵌入类数据无法保存问题
问题:使用@Reference关联MongoDB文档时,关联字段保存为null的解决办法
我在保存包含关联文档的MongoDB主文档(grp)时,为了避免嵌入文档的唯一约束影响主文档,使用了@Reference注解关联Z集合,但保存grp时,其中的关联字段y被存为null,原因是y中的Z对象没有对应的已持久化引用记录。
相关代码如下:
Grp实体类
@Data @EqualsAndHashCode(callSuper=false) @Document(collection = "grp") @AllArgsConstructor @NoArgsConstructor public class grp extends BaseEntity implements Serializable { @Indexed(unique = true) private String x; @Reference private List<Z> y; }
Z实体类
@Data @EqualsAndHashCode(callSuper = false) @Document(collection = "Z") @Builder @AllArgsConstructor @NoArgsConstructor @ToString @CompoundIndex(name = "unique_index", def = "{'aaa': 1, 'zzz' : 1}", unique = true) public class Z extends BaseEntity implements Serializable { private String aaa; private String bbb; private Zzz zzz; private Ixxx xxx; }
解决办法
- 先持久化关联的Z对象:
@Reference的作用是存储关联文档的_id引用,所以在保存grp之前,必须先把List<Z>里的每个Z对象都存入MongoDB的Z集合,确保每个Z都有生成的有效_id。 - 检查主键生成逻辑:确认
BaseEntity中的主键字段(通常是_id)配置了正确的生成策略,比如MongoDB默认的ObjectId自动生成,如果主键没有正确生成,grp无法建立有效引用。 - 正确的保存流程示例:
// 1. 创建并保存Z对象到数据库 Z z1 = Z.builder().aaa("test1").bbb("bbb1").zzz(new Zzz()).xxx(new IxxxImpl()).build(); zRepository.save(z1); Z z2 = Z.builder().aaa("test2").bbb("bbb2").zzz(new Zzz()).xxx(new IxxxImpl()).build(); zRepository.save(z2); // 2. 创建grp并关联已保存的Z对象 grp grp = new grp(); grp.setX("unique_x_value"); grp.setY(Arrays.asList(z1, z2)); // 3. 保存grp grpRepository.save(grp);
- 禁止关联未持久化的Z对象:如果直接把未保存到数据库的
Z对象放到grp的y列表中,MongoDB找不到对应的_id,就会将y字段存为null,甚至不存储该字段。
内容的提问来源于stack exchange,提问作者NAGANATHAN
相关产品推荐
相关产品推荐

