I have the following Hibernate entities: User, Role and Team. There is also the UserTeamRole entity which is basically a connection between a User, his Role and the Team he is in:
@Entity
@Table(name = "user_team_role")
public class UserTeamRole {
private Long id;
private User user;
private Role role;
private Team team;
[...]
}
In my JSF managed bean I need to get the User and all the UserTeamRoles for a particular user designated name that I get in a form. I do that in the UserDAO:
public User getUserByDn(String dn) {
User result = (User) getSessionFactory().getCurrentSession()
.createCriteria(User.class)
.setFetchMode("userTeamRoles", FetchMode.JOIN)
.add(Restrictions.like("dn", dn)).uniqueResult();
return result;
}
I used the FetchMode because otherwise I would get a LazyInitializationException in the bean because the session was closed at the point that I would need to access the collection.
But, after this I also need to loop through this User.userTeamRoles collection and get the name for each role.
When I do this:
if (null != u.getUserTeamRoles()) {
for (UserTeamRole urt : u.getUserTeamRoles()) {
// here get role for every UserTeamRole
grAuth.add(new SimpleGrantedAuthority(urt.getRole().getName()));
}
}
I get an exception:
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session for the Role entity.
So my question is how can I also get the Role for each UserTeamRole like I did here .setFetchMode("userTeamRoles", FetchMode.JOIN) in getUserByDn
.
I tried "chaining" the call to FetchMode but it does not work. I saw you can chain queries on members of associations, but I don't need to query, I just need the Role to be initialized so I can use it further.
I'm using Hibernate 4, Spring 3, JSF 2.
Thanks
You need to create an alias:
Criteria c = getSessionFactory().getCurrentSession().createCriteria(User.class, "user");
c.setFetchMode("user.userTeamRoles", FetchMode.JOIN);
c.createAlias("user.userTeamRoles", "utr", CriteriaSpecification.LEFT_JOIN);
c.setFetchMode("utr.role", FetchMode.JOIN);
c.add(Restrictions.like("dn", dn));
The corresponding HQL query is very similar, but much easier to read and understand IMO:
select distinct user from User user
left join fetch user.userTeamRoles utr
left join fetch utr.role
where user.dn like :dn