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.