I'm getting a LazyInitializationException when I'm trying to access the permissions
collection of my User
object. Exception message:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: dev.teamnight.nightweb.core.entities.User.permissions, could not initialize proxy - no Session
This are the important parts of the User class:
@Entity
@Table(name = "users")
@Inheritance(strategy = InheritanceType.JOINED)
public class User {
// [...] Other variables
@OneToMany
@JoinTable(
name = "user_groups",
joinColumns = @JoinColumn(name = "groupId"),
inverseJoinColumns = @JoinColumn(name = "userId")
)
private List<Group> groups = new ArrayList<Group>();
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
@OrderBy("name ASC")
private List<UserPermission> permissions;
// [...] Getter Setter
@Override
public boolean hasPermission(String permission) {
/**
* Check for User
* UserPermission has yes or no/neutral, no resolves to true, no/neutral to no, UserPermissions override all GroupPermissions, if no go to GroupPerms
* (Groups are sorted by priority, highest priority first, all permissions to one ArrayList)
* GroupPermission true allows, neutral ignores, false denies
*/
UserPermission userPerm = this.permissions.stream()
.filter(perm -> perm.getName().equals(permission))
.filter(perm -> perm.getType() == Permission.Type.FLAG)
.filter(perm -> perm.getAsBoolean())
.findFirst()
.orElse(null);
if(userPerm != null) {
return true;
}
boolean allow = false;
List<GroupPermission> groupPermissions = new ArrayList<GroupPermission>();
this.groups.forEach(group -> {
groupPermissions.addAll(group.getPermissions().stream().filter(perm -> perm.getType() == Permission.Type.FLAG).collect(Collectors.toList()));
});
for(GroupPermission perm : groupPermissions) {
Tribool bool = perm.getAsTribool();
if(bool == Tribool.TRUE) {
allow = true;
} else if(bool == Tribool.FALSE) {
return false;
}
}
return allow;
}
UserPermission.java:
@Entity
@Table(name = "user_permissions", uniqueConstraints = @UniqueConstraint(columnNames = {"userId", "name"}))
public class UserPermission extends Permission {
@ManyToOne
@JoinColumn(name = "userId", nullable = false)
private User user;
}
UserHelper.java:
public <T extends User> T getByUsername(String username, Class<T> type) {
Session session = this.factory().getCurrentSession();
session.beginTransaction();
Query<T> query = session.createQuery("FROM " + type.getCanonicalName() + " U WHERE U.username = :username", type);
query.setParameter("username", username);
T user = query.uniqueResult();
session.getTransaction().commit();
return user;
}
I'm calling getByUsername() to receive the user from the database and then later I try to access the permissions using User.hasPermission("testperm") and then the exception above happens.
EDIT: Mention there is another association, so FetchType.EAGER or @Fetch(FetchMode.join) lead to another exception.