Spring Boot多对多关联:关联表已填充但查询时关联数据为空
问题分析与解决方案
可能的原因及对应解决方法
1. Lombok @Data 生成的 equals/hashCode 引发关联加载异常
@Data 注解会自动生成包含所有字段(包括关联集合)的 equals 和 hashCode 方法,而 Hibernate 对关联实体使用代理对象时,这种基于集合的 equals/hashCode 逻辑会干扰关联数据的正常加载。
解决方法:
在两个实体类上分别排除关联集合生成 equals/hashCode:
- StudentEntity 添加
@EqualsAndHashCode(exclude = "courses") - CourseEntity 添加
@EqualsAndHashCode(exclude = "students")
修改后的 StudentEntity 示例:
@Entity @Table(name = "students") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(exclude = "courses") public class StudentEntity implements Serializable { // ... 原有代码不变 }
修改后的 CourseEntity 示例:
@Entity @Table(name = "courses") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(exclude = "students") public class CourseEntity implements Serializable { // ... 原有代码不变 }
2. JSON 序列化循环引用导致关联数据被过滤
双向多对关联在 JSON 序列化时会出现循环引用问题(Student 引用 Course,Course 又引用 Student),序列化框架(如 Jackson)会自动忽略其中一方的关联数据,导致返回结果中 courses 为空。
解决方法:
使用 Jackson 注解标记双向关联的主次关系:
- 在 StudentEntity 的
courses字段添加@JsonManagedReference(主方,正常序列化) - 在 CourseEntity 的
students字段添加@JsonBackReference(从方,避免循环)
示例:
// StudentEntity 中 @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinTable(name = "student_course", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "course_id")) @JsonManagedReference private Set<CourseEntity> courses = new HashSet<>(); // CourseEntity 中 @ManyToMany(mappedBy = "courses", fetch = FetchType.EAGER) @JsonBackReference private Set<StudentEntity> students = new HashSet<>();
3. 强制关联查询(确保 EAGER 加载生效)
虽然设置了 FetchType.EAGER,但部分场景下(如自定义 JPQL 查询)Hibernate 可能不会自动加载关联数据,此时需要显式使用 JOIN FETCH 强制加载关联集合。
解决方法:
在 StudentRepository 中添加自定义查询方法:
public interface StudentRepository extends JpaRepository<StudentEntity, Long> { @Query("SELECT s FROM StudentEntity s JOIN FETCH s.courses WHERE s.id = :id") StudentEntity findByIdWithCourses(@Param("id") Long id); }
使用该方法查询学生时,会同时加载关联的课程数据。
验证步骤
- 优先修改 Lombok 的 equals/hashCode 配置,这是最常见的触发原因
- 若问题仍存在,添加 JSON 序列化注解解决循环引用问题
- 最后检查查询逻辑,确保使用正确的关联加载方式
内容的提问来源于stack exchange,提问作者Tech de Enigma
相关产品推荐
相关产品推荐

