Hibernate Criteria获取关联对象以进行收集

时间:2012-12-07 09:56:33

标签: hibernate criteria-api hibernate-criteria lazy-initialization

我有以下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。

由于

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.