SpringBoot整合MongoDB时@Transient字段聚合查询返回null如何解决
问题原因
@Transient注解会标记字段为完全非持久化字段,Spring Data MongoDB的映射转换器在所有读写场景下都会跳过该字段:不仅写入集合时不会持久化该字段,读取普通查询、聚合查询返回结果时,也不会将结果集中的同名字段映射到实体属性,因此加了该注解的permissions会返回null。
解决方案
根据你使用的Spring Data MongoDB版本选择对应方案即可:
方案1:使用
@ReadOnlyProperty注解(推荐,适用于Spring Data MongoDB 3.2及以上版本)直接将
permissions字段上的@Transient替换为@ReadOnlyProperty注解:@Data @AllArgsConstructor @NoArgsConstructor public class RolePermission extends BaseEntity{ private Long roleId; private Long permissionId; // 替换@Transient为该注解 @ReadOnlyProperty private List<Permission> permissions; public RolePermission(Long roleId,Long permissionId){ this.roleId = roleId; this.permissionId = permissionId; } }该注解会明确标记字段为只读属性:写入MongoDB时自动忽略该字段,不会持久化到集合中;读取查询/聚合结果时,会正常映射返回的
permissions字段值,完全匹配需求,改动量最小。方案2:读写模型分离(全版本兼容,无版本限制)
保留原
RolePermission实体类上的@Transient注解不变,保证写入role_permission集合时不会持久化permissions字段。单独定义聚合查询专用的返回VO类接收关联结果:@Data public class RolePermissionVO extends BaseEntity{ private Long roleId; private Long permissionId; // 不加@Transient,正常参与映射 private List<Permission> permissions; }调整聚合查询的映射目标类型为该VO类即可:
// 注意这里已经修正了原代码的关联字段错误 LookupOperation lookup = Aggregation.lookup("permission", "permissionId", "_id", "permissions"); Aggregation aggregation = Aggregation.newAggregation(lookup); AggregationResults<RolePermissionVO> role_permission = mongoTemplate.aggregate(aggregation, "role_permission", RolePermissionVO.class);该方案完全隔离读写场景的字段差异,不会出现非预期字段入库的问题,适合复杂业务场景使用。
额外注意:你原代码编写的lookup关联条件有误,用
roleId去关联permission集合的_id主键无法得到正确的角色-权限对应关系,实际关联外键应该是role_permission集合中的permissionId,使用时记得修正。
内容的提问来源于stack exchange,提问作者ITKnight
相关产品推荐
相关产品推荐

