Spring Data MongoDB 3.4.12:解决@DBRef列表添加对象时为空的问题
问题:MongoDB中无法向Curso对象的Student列表添加元素及@DBRef相关疑问
在Postman测试REST API时,尝试通过Spring Data MongoDB将Student对象添加到Curso的列表属性中,但发现该列表为null,无法添加值。同时疑问使用@DBRef注解时是否无法访问Student的持久化元素。
相关代码
@Document public class Student { @Id private String id; @Getter @Setter private String primer_nombre; @Getter @Setter private String segundo_nombre; @Getter @Setter private String primer_apellido; @Getter @Setter private String segundo_apellido; @Getter @Setter private String numero_documento; @Getter @Setter private documentType tipo_documento; @Getter @Setter private int nota; @Getter @Setter private String estado; public void calificarEstudiante(){ if(this.getNota() < 3){ this.setEstado("reprobado"); }else{ this.setEstado("aprobado"); } } } @Data @Document public class Curso { @Id @Getter @Setter private String id; @Getter @Setter private String nombre_curso; @Getter @Setter private String descripcion; @Getter @Setter private String maestro; @DBRef @Field("estudiantes") public List<Student> estudiantes; public void addStudentsInCourse(Student student){ System.out.println("estudiantes = " + estudiantes); //students is null this.estudiantes.add(student); } } // Controller @RestController @RequestMapping("/endpoints") public class QualificationsController { @PutMapping("/inscribir/{studentID}/in/{cursoID}") public Curso agregarEstudianteACurso( @PathVariable(value="studentID") String studentID, @PathVariable(value="cursoID") String cursoID) { Curso currentCurso = cursosServices.findById(cursoID); Student currentStudent = studentsServices.findById(studentID); currentCurso.addStudentsInCourse(currentStudent); return this.cursosServices.save(currentCurso); } }
解决方案及说明
1. 解决列表为null的问题
Curso类中的estudiantes列表未初始化,从MongoDB查询时如果该字段不存在,会返回null,导致调用add()方法时抛出NullPointerException。有两种修复方式:
- 方式一:声明字段时直接初始化
修改Curso类的列表字段(建议改为private,利用@Data自动生成getter/setter,符合封装原则):
@DBRef @Field("estudiantes") private List<Student> estudiantes = new ArrayList<>();
- 方式二:在add方法中做null判断
如果不想提前初始化,可在添加元素前先检查并初始化:
public void addStudentsInCourse(Student student){ if(this.estudiantes == null){ this.estudiantes = new ArrayList<>(); } this.estudiantes.add(student); }
2. @DBRef注解的说明
使用@DBRef时可以正常访问Student对象的持久化元素,它的核心作用是存储关联文档的_id引用,而非嵌入整个Student文档:
- 关联的Student必须已持久化到MongoDB中(即先调用
studentsServices.save()保存Student,再关联到Curso),否则Spring Data MongoDB无法找到对应的引用文档。 - 查询Curso时,Spring会自动根据@DBRef加载关联的Student对象(默认立即加载,可通过配置调整为懒加载)。
- 持久化Curso时,Spring会自动将Student的
_id作为引用存储到Curso的estudiantes字段中。
3. 增强接口健壮性
建议在控制器中添加空判断,避免因Curso或Student不存在导致的异常:
@PutMapping("/inscribir/{studentID}/in/{cursoID}") public Curso agregarEstudianteACurso( @PathVariable(value="studentID") String studentID, @PathVariable(value="cursoID") String cursoID) { Curso currentCurso = cursosServices.findById(cursoID); if(currentCurso == null){ throw new RuntimeException("Curso no encontrado con ID: " + cursoID); } Student currentStudent = studentsServices.findById(studentID); if(currentStudent == null){ throw new RuntimeException("Estudiante no encontrado con ID: " + studentID); } currentCurso.addStudentsInCourse(currentStudent); return this.cursosServices.save(currentCurso); }
内容的提问来源于stack exchange,提问作者Toms_Hd3z
相关产品推荐
相关产品推荐

