spring/hibernate-按当前用户ID过滤


问题内容

我的Oracle数据库中有一个表CompanyList:

CMP_ID INTEGER -- ID of company
CMP_NAME VARCHAR2 -- name of company
USR_ID INTEGER -- Foreign key to the USERS table

我的Spring 3 MVC应用程序全部使用注释进行配置,我的POJO以及使用hibernate方式检索DAO对象(CompanyDao)的公司列表为例。

公司名称:

@Transactional
    public Set<Company> findAllCompanys() throws DataAccessException {

        return findAllCompanies(-1, -1);
    }

    @SuppressWarnings("unchecked")
    @Transactional
    public Set<Company> findAllCompanies(int startResult, int maxRows) throws DataAccessException {
        Query query = createNamedQuery("findAllCompanies", startResult, maxRows);
        return new LinkedHashSet<Company>(query.getResultList());
    }

而我的公司域名:

@Entity
@NamedQueries( {
        @NamedQuery(name = "findAllCompanies", query = "select myCompany from Company myCompany")})
...
public class Company implements Serializable {
...

然后,我设置了spring安全性,因此我的所有页面都需要标识。

使用当前已登录用户会话的USER ID筛选CompanyDao返回的行的最佳方法是什么?


问题答案:

简短答案:SecurityContextHolder。

稍长一点的答案:如果作为user_id外键关系的父级的User实体也实现了UserDetails接口,则可以在Spring的安全上下文中直接使用User实体。

您可以从DAO层或它的上一层调用SecurityContextHolder.getContext()方法,这没关系……因为返回的实例将范围限定在请求的本地线程。

然后,您可以从上下文实例获取UserDetails,将其强制转换为User实体,并将其作为命名参数传递给DAO调用。

作为快速跟进,我意识到您的原始问题暗示您将运行命名查询(因为它当前存在),然后过滤掉不匹配的公司。您仍然可以通过将与您公司关联的用户与安全上下文中的用户进行比较来使用该方法,但是通常我不建议使用该方法。询问数据库到底需要什么。