休眠标准获取关联的对象进行收集

问题描述 投票:0回答:2

我有以下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:无法初始化代理-没有会话角色实体。

所以我的问题是,我如何也可以像getUserByDn中的.setFetchMode(“ userTeamRoles”,FetchMode.JOIN)一样获得每个UserTeamRole的角色。

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

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

谢谢

hibernate hibernate-criteria lazy-initialization
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

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.
© www.soinside.com 2019 - 2024. All rights reserved.