已配置@Transactional与JOIN FETCH仍报JSON懒加载初始化错误如何解决
问题根因
你本地调用不报错但接口调用报错的核心原因是双向多对多关联的反向字段触发了额外的懒加载,和Users的roles配置无关:
- 你写的
JOIN FETCH已经正确加载了Users的roles集合,本地调用System.out.println不报错是因为你Roles类的toString方法只输出了id和role字段,没有访问反向关联的users集合,不会触发额外懒加载。 - 接口返回时Jackson会遍历实体所有getter方法做序列化,当序列化到
Roles对象时,会自动调用getUsers()方法,这个Set<Users> users是默认懒加载的,此时findAllUsers的事务已经提交,Session已经关闭,就会抛出懒加载初始化失败的报错。
排查验证方法
在controller调用完userService.findAllUsers()之后加一行测试代码:users.get(0).getRoles().iterator().next().getUsers().size(),如果这段代码直接抛出懒加载报错,就可以确认是上述问题。
额外检查:你贴出的findAllUsers代码只创建了Query对象,没有返回query.getResultList(),如果你实际代码也是这么写的,就是直接返回了持久态对象的代理,也会导致问题,先确认这行代码是否补全。
解决方案(按优先级排序)
- 方案1(最推荐):不需要在角色信息中返回关联用户列表,直接在
Roles类的users属性上添加@JsonIgnore注解,阻止Jackson序列化该字段即可:
@ManyToMany(mappedBy = "roles") @JsonIgnore private Set<Users> users;
- 方案2:如果需要保留双向关联的序列化,使用Jackson的双向引用注解避免循环+懒加载问题,在
Users类的roles属性上加@JsonManagedReference,在Roles类的users属性上加@JsonBackReference,同时可以在HQL中关联FETCHroles的users属性避免懒加载。 - 方案3(兜底):配置Hibernate序列化兼容模块,引入
jackson-datatype-hibernate5依赖,配置ObjectMapper注册Hibernate5Module,设置忽略未初始化的懒加载对象:
@Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); Hibernate5Module module = new Hibernate5Module(); module.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION); module.enable(Hibernate5Module.Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_LOADED_OBJECTS); return mapper.registerModule(module); }
内容的提问来源于stack exchange,提问作者Alpharius
相关产品推荐
相关产品推荐

