JPA中如何处理懒加载?代码举例讲解

在JPA中可以通过以下方式处理懒加载:

  1. 在关系映射上使用@Lazy注解配置懒加载,默认为立即加载。
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id") 
@Lazy
private Department department; 
  1. 在查询时使用setFetchGraph指定需要加载的对象或集合,实现按需加载。
String jpql = "SELECT e FROM Employee e";    
Query query = em.createQuery(jpql);
FetchJoin<Employee, Department> fetch = query.fetch("department"); 
List<Employee> employees = query.getResultList(); 
  1. 调用EntityManager.refresh()方法手动刷新实体,触发懒加载关系的加载。
Employee emp = em.find(Employee.class, 1);  
// 第一次读取不会加载department    
Department dept = emp.getDepartment();

em.refresh(emp);  
// 刷新实体,会加载department
Department dept = emp.getDepartment();  
  1. 二级缓存要求设置cascade属性为CascadeType.ALL,否者无法支持懒加载关系数据的缓存。
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "department_id")  
private Department department;

开启懒加载可以提高初始查询的性能,但如果没有及时加载,事务提交时会产生额外的SQL语句加载数据。理解何时开启懒加载及何时使用setFetchGraph或refresh()刷新数据,有助于找到性能的平衡点。