2010-10-08 82 views
0

我在Oracle数据库有一个表CompanyList:春/休眠 - 过滤器由当前用户ID

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

我有我的春天3 MVC应用程序都使用注释,我的POJO和配置,我的DAO对象( CompanyDao)使用hibernate检索公司列表。

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 { 
... 

然后我设置春天的安全性,所以我所有的页面需要鉴定。

使用当前登录的用户会话的用户ID过滤由CompanyDao返回的行的最佳方式是什么?

回答

2

简短回答:SecurityContextHolder。

稍长的答案: 如果是这样的USER_ID外键关系的父方的用户实体也实现了的UserDetails接口,那么用户实体可以直接在Spring的安全上下文中使用。

您可以从DAO图层或其上面的图层调用SecurityContextHolder.getContext()方法...并不重要,因为返回的实例将被限定到请求的本地线程。

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

作为一个快速跟进,我意识到你的原始问题意味着你会运行命名查询,因为它目前存在,然后过滤掉不匹配的公司。您仍然可以通过将安全上下文中与贵公司相关的用户与用户进行比较来使用该方法,但通常我不会推荐这种方法;询问数据库,确切地说你需要什么。

1

实际上,Spring Security 3可以使用@PostFilter注释来过滤返回的集合,请参阅15.3.1 @Pre and @Post Annotations

但我认为你的情况,当Company有很多一对一关系User,杰夫的建议是比较合适的 - 你应该添加一个条件查询,即通过findAllCompaniesForUser()更换findAllCompanies(),并通过userIdSecurityContextHolder提取在演示或服务层作为参数。