Hibernate Criteria加载问题:如何仅获取员工关联的RestTO列表(不含Employee)
你好~ 从你的描述来看,虽然已经把RestTO里的employeeTO设置为FetchType.LAZY,但查询指定员工的RestTO列表时,每个RestTO还是带上了关联的EmployeeTO对象。这里给你几个实用的解决思路:
1. 排查是否意外触发了懒加载初始化
FetchType.LAZY本质是生成代理对象,只有当你主动访问该对象的属性或方法时,Hibernate才会去数据库查询初始化它。比如你在拿到RestTO列表后,不小心调用了restTO.getEmployeeTO().getId(),就会触发懒加载,导致EmployeeTO被加载出来。
解决办法很简单:确保业务代码里不要去访问RestTO的employeeTO属性就好。
2. 用DTO投影获取需要的字段(最推荐)
如果你的需求只是获取RestTO本身的数据,完全不需要关联的EmployeeTO,那直接定义一个只包含你所需字段的DTO类,通过HQL查询直接投影到DTO上,就能彻底避免加载EmployeeTO。
举个例子:
// 先定义RestDTO,只保留你需要的字段 public class RestDTO { private Long id; private String restType; // 其他你需要的字段,记得加对应的构造方法和getter public RestDTO(Long id, String restType) { this.id = id; this.restType = restType; } } // 然后写查询代码 Session session = HibernateUtil.getSessionFactory().openSession(); try { List<RestDTO> restList = session.createQuery( "SELECT new com.your.package.RestDTO(r.id, r.restType) FROM RestTO r WHERE r.employeeTO.id = :empId", RestDTO.class ) .setParameter("empId", 你的员工ID) .list(); } finally { session.close(); }
3. 序列化时忽略EmployeeTO(如果是接口返回问题)
如果是在把RestTO序列化成JSON返回给前端时,发现带上了EmployeeTO,那大概率是Jackson这类序列化框架触发了懒加载(序列化时会调用对象的getter方法)。这种情况下,直接在RestTO的employeeTO字段上加@JsonIgnore注解,让序列化框架忽略这个属性就行:
@ManyToOne(fetch = FetchType.LAZY) @JsonIgnore private EmployeeTO employeeTO;
注意:这个方法只是让EmployeeTO不被序列化输出,对象本身还是持有懒加载的代理对象,适合只是不想返回给前端的场景。
4. 检查查询语句是否强制加载了关联
Hibernate默认对@ManyToOne(fetch=LAZY)是懒加载,但如果你的查询语句里写了JOIN FETCH r.employeeTO,就会强制加载关联的EmployeeTO。检查一下你的查询代码,如果有这类语句,去掉就能恢复懒加载的行为。
内容的提问来源于stack exchange,提问作者jamal mousavi

