0

I need to check whether user is a member of specific group for security reasons. However, I'm getting LazyInitializationException all the time and can't find a solution.

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

I've tried to use @Transactional annotation everywhere it is possible, that doesn't help. It works fine with Eager initialization for sure, but I would prefer not to use it.

Controller:

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

        return chatMessageService.processMessage(chatMessageRequest, user);
    }

Decider class:

@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;
    }
}

That's what is important about user:

@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<>();

}

Somebody could help me? Thanks in advance!

UPD: Transactional works fine in other parts of application, so I don't think this is configuration issue or it might be. Also, even initializing directly with Hibernate.initialize() inside decider method still fails.

I guess, this happening because @PreAuthorize doesn't access the method directly, so Spring is not able to create proxy. However, I still don't know how to fix it and even not sure if I am right here.

Andrew
  • 1
  • 1

1 Answers1

0

Use fetch = FetchType.EAGER instead of FetchType.LAZY.

Adrian Mole
  • 30,672
  • 69
  • 32
  • 52
Ati
  • 11
  • 1