2014-03-25 42 views
3

我有一個JavaEE 6,JPA 2.1應用程序,我需要管理 用戶屬於多個租戶。這是必需的,因此它們是 ,例如可以將一個承租人的數據所有權更改爲另一個承租人 。如何使用JPA/EclipseLink實現動態多租戶或動態表過濾?

租戶結構分層方式設置,下面一棵樹 像執行這樣的(格式爲[Role:Tenant-ID]爲 參考):

   [SysAdmin:1] 
       / \ 
       / \ 
       /  \ 
       /  \ 
      /   \ 
    [Admin Tenant A:2] [Admin Tenant B:3] 
     /\    \ 
     / \    \ 
[User TA:4] [Manager TA:5] [User TB:6] 
       \ 
       \ 
      [User TA:7] 

現在,當我與活動用戶[User TA:4]查詢數據庫我 與'tenant-id'預期結果4.當我查詢與活動用戶 [Admin Tenant B:3]我期望結果來自租戶3和6和 當我查詢爲[SysAdmin:1]我只想要返回所有數據 基本上沒有過濾器。

由於我有作爲JPA實現我試圖利用 在@Multitenant實現首先,這顯然不 似乎因爲預計在同一時間只 ,這使得單個租戶上班工作的EclipseLink 2.5.1完美的意義,因爲它正在使用該信息,以及 actualy寫入數據庫。

對於來,我想我可以設法相處的定製@Produces @MultitenantWriteAware EntityManager方法去的東西,在這裏我分配 eclipselink.tenant-id到目標租戶寫 操作線的東西 數據庫。用這種方法,你會丟失漂亮的容器 託管@PersistenceContext(CMT)@Inject你的 EntityManager然後。

當試圖用一個自定義PersistenceProvider是 捎帶上一個的EclipseLink提供我所面臨的問題,因爲我可以 沒有從任何地方獲取活躍用戶實現這一點。只有這樣,才能傳遞 信息似乎是通過提供Map

public 
EntityManagerFactory 
createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) 

我也看了成QueryRedirector S的似乎讓我定製 查詢並追加像「條件,並tenant_id IN(2, 3,4)'變成 積極的查詢,這是實施 (多)@Multitenant的某種手動方式,但我不能得到那個工作,因爲我 沒有得到與那ExpressionBuilder和另外似乎 無法從某處查詢該活動用戶。

我覺得我忽略的東西,我想一定是通用的,自動的方式排序 實現這個,而不是手動 使用 CriteriaBuilder

附加額外條件,查詢是否有任何建議/提示/鏈接/最佳做法如何實現這種 種類的設置?

回答

1

我相信這是迄今爲止的一個懸而未決的問題。我已發佈類似question。一個答案包含了一個link日食臭蟲跟蹤器也提高了這一點。此處描述的解決方法是使用具有不同多租戶設置的相同表的多個持久性單元。根據您使用的EntityManagerFactory,數據庫查詢具有不同的作用域。我在實踐中並沒有這樣做(我害怕這兩個持久單元中存在潛在的不一致)。

我想用@AdditionalCriteria使用不同的方法描述here。我是註釋到,應該由房客來過濾所有的實體,但也應該是訪問被管理員:

@AdditionalCriteria(":ADMINACCESS = 1 or this.tenant=:TENANT") 

標誌ADMINACCESS決定租戶是否應用濾波器,或沒有。我想你可以很容易地將它擴展到你的場景。這樣就保證了這個動態過濾器始終得到應用。但是你需要自己照顧租戶屬性。對我來說這是一個很好的妥協。我將所有數據庫操作封裝在一個點上。以統一的方式實現這一點的一種方式是記住ThreadLocal EntityManager中的當前租戶,並確保所有租戶相關實體實現定義方法setTenant(字符串租戶)的接口TenantSpecific。如果你堅持新的對象,這將始終被設置。

+0

這樣,當您使用此批註連接表時,可以禁用共享高速緩存。當JPA查詢緩存時,您是否知道如何設置附加條件? – Orbita