2010-10-08 81 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提取在演示或服務層作爲參數。