这个问题在这里已经有答案了:
如何修复hibernate lazyinitializationexception:未能延迟初始化角色集合,无法初始化代理-无会话(13个答案)
14天前关门了。
我试图获取用户的配置文件数据后登录(从登录成功过滤器),但我看到了一个例外,延迟加载数据。请参见以下示例代码:
authenticationsuccesshandler.java验证
@Component
public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Autowired
private UserService userService;
@Autowired
private Gson gson;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
User user = (User) authentication.getPrincipal();
UserLoginResponseDto userLoginResponseDto = userService.login(user.getUsername());
response.setStatus(HttpStatus.OK.value());
response.setContentType("application/json; charset=UTF-8");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.getWriter().println(gson.toJson(userLoginResponseDto));
response.getWriter().flush();
clearAuthenticationAttributes(request);
}
}
用户服务.java
public class UserService implements UserDetailsService, TokenService {
@Autowired
private UserRepository userRepository;
@Transactional(readOnly = true)
public UserLoginResponseDto login(String email) {
Optional<UserModel> userOptional = userRepository.findByEmailIgnoreCase(email);
UserModel userModel = userOptional.get();
UserLoginResponseDto userLoginResponseDto = userModel.toUserLoginResponseDto();
return userLoginResponseDto;
}
}
用户模型.java
public class UserModel {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(nullable = false, unique = true, updatable = false)
private UUID id;
[A FEW MORE FIELDS]
@Column(length = 256, nullable = false, unique = true, updatable = false)
private String email;
@OneToMany(cascade = { CascadeType.ALL })
private List<RoleModel> roleModels;
public UserLoginResponseDto toUserLoginResponseDto() {
return new UserLoginResponseDto().setId(id).setEmail(email).setRoles(roleModels);
}
}
userloginresponsedto.java
public class UserLoginResponseDto {
private UUID id;
private String email;
private List<RoleModel> roles;
}
在中序列化userloginresponsedto类型的对象时 AuthenticationSuccessHandler
,我看到以下错误消息-
org.hibernate.lazyinitializationexception:未能延迟初始化角色集合:usermodel.rolemodels,无法初始化代理-无会话
我如何正确解决这个问题而不采用以下任何技术?
[反模式]在视图中打开
[反模式]hibernate.enable\u lazy\u load\u no\u trans
fetchtype.eager文件
1条答案
按热度按时间lyfkaqu11#
你的问题是你通过了真正的懒惰
List
进入setRoles
,不会触发满载。这表明(立即)虽然您已经将顶级数据库类与顶级dto分离,但这是一种“浅层”分离,不能完全实现值。你还没有证明RoleModel
是实体还是可嵌入的,这很重要。因此,第一步是将这些项复制到非jpa表单中。如果
RoleModel
可嵌入(本质上是一个pojo),这可以简单到setRoles(new ArrayList<>(roles))
. 否则,您需要一个嵌套的dto,此时可以考虑mapstruct之类的东西。不过,无论哪种情况,您都可能遇到n+1问题。实际上,在这种情况下,您确实需要一个急切的获取,这就是jpa实体图的用途。您可以告诉spring数据只有在需要时才急切地获取列表,这是一个很好的例子。