使用@DBRef关联MongoDB集合时嵌套对象引用值为null问题排查
排查MongoDB @DBRef在嵌套DTO列表中关联数据为null的问题
以下是针对问题的排查方向和解决方法:
1. 检查MongoDB中手动输入的引用格式是否正确
@DBRef要求存储标准MongoDB DBRef格式,而非单纯的字符串ID。手动输入时若直接写字符串ID,Spring Data MongoDB无法解析,会返回null。
- 检查步骤:进入MongoDB Shell,执行查询查看assessmentTemplate文档的关联字段:
db.assessmentTemplate.findOne({"_id": "你的模板ID"}, {"baseQuestions": 1, "coreQuestions": 1}) - 正确格式示例:
若Question的_id是字符串类型,关联字段应是:
若Question的"questionsId": {"$ref": "question", "$id": "q123"}_id是ObjectId类型,关联字段应是:
注意"questionsId": {"$ref": "question", "$id": ObjectId("60d21b4667d0d8992e610c85")}$ref的值必须和Question对应的MongoDB集合名完全一致(你这里是question)。
2. 确认实体类与MongoDB集合名匹配
Spring Data MongoDB默认会将实体类名转为小写复数作为集合名(比如Question对应questions),但你手动创建的集合是question(单数),这会导致@DBRef找不到对应集合。
- 解决方法:在
Question类上添加@Document注解指定集合名:@Document(collection = "question") public class Question { @Id private String id; private String name; @DBRef private List<Option> options; }
3. 检查嵌套类字段与MongoDB字段名匹配
确保QuestionsTemplate类的字段名和MongoDB文档中的字段名完全一致:
- 比如
QuestionsTemplate里的字段是questionsId,那MongoDB中assessmentTemplate文档的baseQuestions/coreQuestions数组元素里,对应的字段名也必须是questionsId。 - 如果字段名不匹配,要么修改MongoDB数据,要么在字段上添加
@Field注解指定映射名:public class QuestionsTemplate { @DBRef @Field("questionId") // 若MongoDB中字段名为questionId private Question questionsId; private int score; }
4. 验证ID类型一致性
检查Question的@Id类型与MongoDB中存储的_id类型是否一致:
- 若
Question的@Id是String类型,那么MongoDB中question集合的文档_id必须是字符串,同时assessmentTemplate中的DBRef的$id也必须是字符串。 - 若
Question的@Id是ObjectId类型,那么MongoDB中对应的_id和DBRef的$id都必须是ObjectId类型。
额外提示
单独查询Question时Option能正常加载,说明Question与Option的@DBRef配置和数据格式是正确的,问题大概率出在AssessmentTemplate与Question之间的关联数据或配置上,优先检查上述前三点。
内容的提问来源于stack exchange,提问作者Rajat Sahu
相关产品推荐
相关产品推荐

