前言
使用Jpa持久化框架级联注解@OneToOne
或者@OneToMany
等。双向关联查询时,会造成数据死循环
例子
实体类定义
1、定义一个部门实体类
less
@Data
@Entity
@Table(name = "t_department")
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Employee> employees;
}
2、定义一个销售实体类
less
@Data
@Entity
@Table(name = "t_employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
}
双向关联 3、dao层定义
kotlin
@Repository
public interface DepartmentRepository extends JpaRepository<Department, Long>,
JpaSpecificationExecutor<Department> {
}
4、
kotlin
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long>,
JpaSpecificationExecutor<Employee> {
}
5、接口定义
typescript
@RestController
public class IndexController {
@Autowired
private DepartmentRepository departmentRepository;
@GetMapping("/index")
public String index() {;
Department department = new Department();
department.setName("bbb");
Employee employee = new Employee();
employee.setName("aaa");
employee.setDepartment(department);
department.setEmployees(List.of(employee));
departmentRepository.save(department);
return "success";
}
@GetMapping("/findById")
public Department findById(@RequestParam Long id) {
return departmentRepository.findById(id).orElse(null);
}
}
6、调用
bash
http://ip:端口/index
保存数据

7、 这个时候,调用
bash
http://ip:端口/findById?id=2
会发现数据出现死循环
这个并不是bug,这个在toString()方法中,一层一层嵌套导致的,只需要中断其嵌套就行
解决方法
1、 使用@JsonIgnoreProperties
中断其死循环
less
@Data
@Entity
@Table(name = "t_department")
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@JsonIgnoreProperties({"department"})
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Employee> employees;
}
在实体类两边都加上,再次访问,数据为
2、 使用实体类dto
定义一个实体类
kotlin
@Data
public class DepartmentDto {
private Long id;
private String name;
}
less
@GetMapping("/findById1")
public DepartmentDto findById1(@RequestParam Long id) {
Department department = departmentRepository.findById(id).orElse(null);
DepartmentDto departmentDto = new DepartmentDto();
BeanUtils.copyProperties(department, departmentDto);
return departmentDto;
}
3、 使用 @JsonIgnore
注解
less
@Data
@Entity
@Table(name = "t_department")
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@JsonIgnore
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Employee> employees;
}
总结
使用Jpa自带的级联注解造成死循环问题,解决方法很多种,,开发过程中,根据自己需要解决