0

我有以下 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 中,我需要为我在表单中获得的特定用户指定名称获取用户和所有 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:无法初始化代理 -角色实体没有会话。

所以我的问题是我怎样才能像我在 .setFetchMode("userTeamRoles", FetchMode.JOIN) 中所做的那样获得每个 UserTeamRole 的角色getUserByDn

我尝试“链接”对 FetchMode 的调用,但它不起作用。我看到您可以对关联成员进行链接查询,但我不需要查询,我只需要初始化角色,以便进一步使用它。

我正在使用 Hibernate 4、Spring 3、JSF 2。

谢谢

4

2 回答 2

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
于 2012-12-07T10:27:19.357 回答
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.
于 2016-02-04T07:44:40.060 回答