我有以下Hibernate实体:用户,角色和团队。还有UserTeamRole实体,它基本上是用户,他的角色和他所在团队之间的连接:
@Entity
@Table(name = "user_team_role")
public class UserTeamRole {
private Long id;
private User user;
private Role role;
private Team team;
[...]
}
在我的JSF托管bean中,我需要获取User和所有UserTeamRoles,以获取我在表单中获得的特定用户指定名称。我在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;
}
我使用了FetchMode,否则我会在bean中得到一个LazyInitializationException,因为会话在我需要访问该集合时被关闭。
但是,在此之后我还需要遍历这个User.userTeamRoles集合并获取每个角色的名称。
当我这样做时:
if (null != u.getUserTeamRoles()) {
for (UserTeamRole urt : u.getUserTeamRoles()) {
// here get role for every UserTeamRole
grAuth.add(new SimpleGrantedAuthority(urt.getRole().getName()));
}
}
我得到一个例外:
引起:org.hibernate.LazyInitializationException:无法为Role实体初始化代理 - 无会话。
所以我的问题是如何在getUserByDn
中获得每个UserTeamRole的角色,就像我在这里.setFetchMode(“userTeamRoles”,FetchMode.JOIN)。
我尝试“链接”对FetchMode的调用,但它不起作用。我看到你可以对关联成员链接查询,但我不需要查询,我只需要初始化角色,这样我就可以进一步使用它。
我正在使用Hibernate 4,Spring 3,JSF 2。
由于
答案 0 :(得分:3)
您需要创建一个别名:
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));
相应的HQL查询非常相似,但更容易阅读和理解IMO:
select distinct user from User user
left join fetch user.userTeamRoles utr
left join fetch utr.role
where user.dn like :dn
答案 1 :(得分:0)
现在发布答案,以便有人可以获取与Criteria api相关的懒人收集相关的帮助。 我正在使用hibernate-4.3.11.Final
以下条件查询有效:
Criteria c = getSessionFactory().getCurrentSession().createCriteria(User.class, "user");
c.setFetchMode("user.userTeamRoles", FetchMode.JOIN);
c.createAlias("user.userTeamRoles", "utr", JoinType.LEFT_OUTER_JOIN);
c.setFetchMode("utr.role", FetchMode.JOIN);
c.createAlias("utr.role", "role", JoinType.LEFT_OUTER_JOIN);
c.add(Restrictions.like("dn", dn));
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // optional.