2014-03-19 28 views
3

eclipselink(或Hibernate)中的租戶是將數據域彼此分開的絕佳概念。我正在使用單桌戰略的eclipselink。如何訪問eclipselink中的多個租戶?

有時需要從多個租戶(例如出於管理目的)訪問數據。有沒有一個很好的方法來實現這一目標? (我不想通過所有租戶運行來收集數據...)

例子:

@Entity 
@Multitenant 
@TenantDiscriminatorColumn(name = "TENANT", contextProperty = "tenant.id") 
public class TenantEntity { 
    ... 

我可以用參數化實體管理器訪問一個特定租戶的對象:

private static EntityManager newEntityManager(String tenant) { 
    Map<String, Object> map = new HashMap<String, Object>(); 
    map.put("tenant.id", tenant); 
    return emf.createEntityManager(map); 
} 

是否有任何方便的方式來查詢所有租戶? (或者是僅在單個租戶中定義的持久對象的身份?)

回答

2

EclipseLink有一個開放功能請求,允許管理服務器訪問多租戶數據的更好方法:https://bugs.eclipse.org/bugs/show_bug.cgi?id=355458 - 如果它投票給它對你很重要。

解決方法是爲管理控制檯創建單獨的持久性單元。一種解決方法是將多租戶元數據移動到EclipseLink orm.xml文件中,並將其用於租戶persitence單元,而管理持久性單元只使用實體類。您可能需要可以映射到管理控制檯可以使用和查詢的租戶列的實體中的字段,但是對於特定於租戶的持久性單元,這些字段是隻讀或不可訪問的。

+0

偉大的提示,謝謝。所以 - 直接做這件事是一個懸而未決的問題。而接受的解決方法是使用兩個單獨的持久性單位。 這也意味着身份通過多個租戶得到保證(在所有租戶中只有一個具有特定ID的特定類的對象)。 –

+0

這種具有多個持久性單元的方法是否也可以使用註釋?你有什麼提示嗎? –

+1

註解位於共享類中,因此會被兩個持久性單元拾取。任何特定於某個持久性單元的內容都應移至僅包含在該持久性單元中的orm.xml中。 Orm.xml允許覆蓋註釋,但我不確定如何覆蓋租戶註釋,因此您可能必須將其放入租戶特定的eclipselink-orm.xml中。 – Chris

2

我發現了一種替代方法,我會嘗試:而不是使用@Multitenant註釋來過濾出屬於我的租戶的實體,我將使用@AdditionalCriteria。我從上面的問題的例子變成

@Entity 
@AdditionalCriteria(":ADMINACCESS = 1 or this.tenant=:TENANT") 
public class TenantEntity { 

    private String tenant; 
    ... 

這裏我需要照顧自己的租戶專欄。 我可以創建兩個實體管理器。一個租戶訪問:

private static EntityManager newEntityManager(String tenant) { 
    Map<String, Object> map = new HashMap<String, Object>(); 
    map.put("TENANT", tenant); 
    map.put("ADMINACCESS", 0); 
    return emf.createEntityManager(map); 
} 

,另一個用於管理員訪問權限:

private static EntityManager newEntityManager() { 
    Map<String, Object> map = new HashMap<String, Object>(); 
    map.put("TENANT", ""); 
    map.put("ADMINACCESS", 1); 
    return emf.createEntityManager(map); 
} 

查看詳情爲@AdditionalCriteria here。任何意見?

+0

您的租戶領域現在完全是應用程序的責任。雖然租戶無法通過實體讀取其他租戶數據,但應用程序邏輯本身必須確保防止租戶寫入錯誤的租戶或將租戶字段留空。您將不得不確保該實體沒有緩存在二級共享緩存中。 – Chris

+0

是的,正確的。您需要強大的機制來防止突破租戶沙箱。我還沒有完成它,但這似乎是可行的。我有一個知道租戶的線程本地實體管理器。它控制所有的行爲,例如持續設置租戶值。所以堅持的方法(以及類似的行爲)不需要租戶,並且不需要實體本身。租戶邏輯封裝得相當低。那麼,我希望那些作品。我還沒有想過通過第二次lecel緩存的影響。 –

相關問題