当前位置: 首页 > 知识库问答 >
问题:

Spring JPA,Lazy初始化和Dto[复制]

农均
2023-03-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);
    }
}

用户登录响应to.java

public class UserLoginResponseDto {

    private UUID id;
    private String email;
    private List<RoleModel> roles;

}

当在AuthenticationSuccessHandler中序列化UserLoginResponseDto类型的对象时,我会看到以下错误消息-

org.hibernate.懒惰初始化角色集合失败:UserModel.role模型,无法初始化代理-无会话

QQ-如何在不使用以下任何技术的情况下正确解决此问题?

  • [反模式]在视图中打开

共有1个答案

尚嘉庆
2023-03-14

您的问题是,您正在将实际的惰性List传递到setRoles,这不会触发完全加载。这(立即)表明,虽然您已经将顶级数据库类与顶级DTO分离,但这是一种“浅”分离,不会完全实现这些值。您还没有显示RoleModel是实体还是可嵌入的,这很重要。

因此,第一步是将项目复制到非JPA表单中。如果RoleModelembedded(本质上是一个POJO),这可以像setRoles(新的ArrayList)一样简单

不过,无论哪种情况,您都可能遇到n1问题。事实上,在这种情况下,您确实需要一个急切的获取,这就是JPA实体图的用途。您可以告诉Spring数据只有在您需要的时候才急切地获取列表,这是一个关于何时这样做的完美示例。

 类似资料:
  • 在Microservice中,我们将多个DTO数据作为字符串json发布。 控制器: 发布Json: DTO: Dto1和Dto2是java DTO对象名称.如何将字符串json转换为java对象?

  • 今天我学习了一个教程,作者在其中解释了hibernate关联一对多/多对一。我不想把他所有的代码都写在这里。所以,我试着把重点放在。。。 我们有两个实体:“团队”和“球员” 在代码中,我们有: 和 我最感兴趣的是回迁的类型。所以,我们加入了一支球队和一些属于这支球队的球员。我的DAO类标记为 现在我想从数据库中加载充满玩家集合的团队实体。 结果是,我将得到LazyInitializationExc

  • 我有这样的代码: 当我们没有任何其他getInstance的静态方法时,是否初始化了此单例惰性?据我所知,类只在某些情况下初始化,比如: 类的实例是使用new()关键字或使用类的反射创建的。forName(),它可能在Java中引发ClassNotFoundException (Surce:http://javarevisited.blogspot.com/2012/07/when-class-l

  • 惰性初始化 是一个接受lambda并返回实例的函数,该实例可以作为实现lazy属性的委托:对的第一次调用执行传递给的lambda并记住结果,随后对的调用只返回记住的结果。 例 修饰符只能用于在类主体中声明的var属性(而不是在主构造函数中),并且只能在属性没有自定义getter或setter时使用。属性的类型必须是非空的,并且不能是基元类型。 那么,既然这两个选项都能解决同样的问题,如何在这两个选

  • 在kotlin中,我们可以使用以下两种方法和 什么时候使用哪种方法,这两种方法实际上是在下面进行的。哪一种方法是最好的?