首页 > 解决方案 > Spring @PreAuthorize 抛出 LazyInitializationException 从 Hibernate 访问惰性数据

问题描述

出于安全原因,我需要检查用户是否是特定组的成员。但是,我一直收到 LazyInitializationException 并且找不到解决方案。

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: User.groups, could not initialize proxy - no Session

我尝试在任何可能的地方使用 @Transactional 注释,但这没有帮助。它肯定适用于 Eager 初始化,但我不想使用它。

控制器:

    @MessageMapping("/group/chat")
    @PreAuthorize("@decider.checkIfGroupMember(#user, #chatMessageRequest.getGroupId())") 
    public ChatMessageRequest processMessage(
            @Payload ChatMessageRequest chatMessageRequest,
            @AuthenticationPrincipal User user) {

        return chatMessageService.processMessage(chatMessageRequest, user);
    }

决策者类:

@Component
public class Decider {

    @Transactional
    public boolean checkIfGroupMember(Object principal, Integer groupId) {
        User user = (User) principal;
        Set<Group> groups = user.getGroups();
        for (Group group : groups) {
            if(group.getId().equals(groupId)) {
                return true;
            }
        }
        return false;
    }
}

这对用户来说很重要:

@Data
@Builder
@Accessors(chain = true)
@Table(name = "users")
public class User extends BasicEntity {

    @Column(nullable = false)
    private String name;

    @Column(nullable = false, unique = true)
    private String email;

    @Column
    private String password;

    @ManyToMany(mappedBy = "users", fetch = FetchType.LAZY)
    @JsonIgnore
    private Set<Group> groups = new HashSet<>();

}

有人可以帮助我吗?提前致谢!

UPD:事务在应用程序的其他部分工作正常,所以我认为这不是配置问题,也可能是。此外,即使在决策程序方法中直接使用 Hibernate.initialize() 进行初始化仍然失败。

我想,这是因为 @PreAuthorize 不直接访问该方法,所以 Spring 无法创建代理。但是,我仍然不知道如何解决它,甚至不确定我是否在这里。

标签: springspring-boothibernatespring-securityspring-data

解决方案


使用fetch = FetchType.EAGER而不是FetchType.LAZY.


推荐阅读