无法初始化代理 - 没有会话,在 Spring 拦截器内

Could not initialize proxy - no Session, inside Spring interceptor

我的配置中有一个拦截器,我想禁止访问其他用户的资源。在 WebMvcConfig(实现 WebMvcConfigurer)中,我有:

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new FolderInterceptor(userService, folderService))
            .addPathPatterns(Mapping.FOLDER_MAPPING + "/{id}",
                    Mapping.UPDATE_FOLDER_MAPPING + "/{id}",
                    Mapping.DELETE_FOLDER_MAPPING + "/{id}",
                    Mapping.DOWNLOAD_FOLDER_MAPPING + "/{id}");

}

在我的 FolderInterceptor 中,我有一个 preHandle 方法获取访问的文件夹并检查其所有者:

Map pathVariables = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
Long id = Long.valueOf((String) pathVariables.get("id"));

User user = userService.getLoggedAccount();

if (folderService.existsById(id)) {
    Folder folder = folderService.findById(id);

    if (folder.getOwner().getId().equals(user.getId())) {
        return true;
    }
    else {
        response.sendError(403, "Unauthorized");
        return false;
    }
}
else {
    response.sendError(404, "Folder does not exist");
    return false;
}

如果我打印文件夹对象,那一行也会出现同样的错误。

org.hibernate.LazyInitializationException: could not initialize proxy.

感谢您的帮助。

您正在检索一个 Folder 实体,很可能在此处的一个事务下没有任何依赖项提取:

Folder folder = folderService.findById(id);

然后,当您尝试访问 folder.getOwner() 时,未获取所有者依赖项,持久性提供程序尝试从数据库中延迟加载它:

if (folder.getOwner().getId().equals(user.getId())) {
    return true;
}

问题是 folder 超出了事务范围并且是一个分离的实体。

我建议在 folderService.findById(id) 方法中获取 Owner 或将查询和条件放在相同的事务方法下。

我在我的服务中使用 getOne 方法通过 id 检索我的文件夹。现在使用 folderRepository.findById(id) 并且现在有效:

public Folder findById(Long id) {

    Optional<Folder> folder = folderRepository.findById(id);

    if (!folder.isPresent())
        return null;

    return folder.get();
}