2011-05-13 71 views
2

我正在開發一個工具,它使用JPA2處理一些數據庫實體,並使用hibernate作爲持久性提供程序。該工具是通用的,與任何業務邏輯都沒有耦合,它需要一個通用的Class<? extends Task>參數來完成業務,其中Task是我創建的一個接口,用於表示實現實體對我的工具有一些有趣的行爲。該工具的工作包括從數據庫中獲取給定類的實例並操作其某些屬性。它是一個通用工具,因爲它被開發爲可重用的,並且我們有一大組實體類(但不是所有實體類)實現該接口(主要是那些模擬某些類型的正在運行的業務任務的實體)。如何獲取給定實體類的PersistenceUnit名稱?

要做這個工具的工作,我需要得到給定類的EntityManager。要獲得EntityManager,我需要一個EntityManagerFactory。要獲得EntityManagerFactory,我需要持久性單元名稱。

所以,我的問題是,給定一個實體類,獲取其持久性單元的名稱。然而,我沒有找到任何方法來做到這一點,沒有一個已經存在的持久性單元的EntityManager,它會創建一個雞或雞蛋第一,鑰匙鎖在胸前的問題。

部分解決方案是將持久單元的名稱與實體類一起傳遞,但這看起來是錯誤的,因爲應該從給定的類推斷(或至少猜測)持久單元的名稱。這可以優化爲像名稱在實體類的註釋中,但這看起來仍然不合適。搜索和分析persistence.xml文件是我們真正想要避免的。

那麼,我能做些什麼來解決這個問題?有任何想法嗎?

+0

您是否發現在此處張貼的其他選擇?我有同樣的困境。 – davidmontoyago 2011-12-15 20:49:47

+0

@davidmontoyago:我完成了基於羅賓的答案的東西。 – 2011-12-20 16:23:13

回答

2

我敢肯定,不可能確定實體類與之相關的持久性單元,因爲JPA的設計是相反的:通常爲特定的持久性單元注入一個EntityManagerFactory。

如果您至少有所有可用的持久化單元的名稱,你可以使用Persistence.createEntityManagerFactory(persistenceUnitName)創建所有可用的工廠,然後檢查某個類是否屬於一個單元使用其元模型:

for (EntityManagerFactory emf : factories) { 
    try { 
    EntityType<?> entity = emf.getMetamodel().entity(classToCheck); 
    // bingo 
    } catch (Exception e) { 
    // wrong persistence unit 
    } 
} 

或者你檢查MetaModel.getEntities()並構建單元名稱到託管實體類的映射。

+1

對不起,遲到的迴應。我忘了這個問題。我用我的問題做了一些小小的改變。我使用'getMetamodel()。getEntities()'來獲得'Set >'。然後迭代Set以填充包含所有相關類的所有映射信息的對象。這是很多工作,但你的回答讓我走了。謝謝。 – 2011-12-20 16:22:02

0

哇,我不認爲有一個完美的方式來做事情就像你描述它的方式。

有關特定持久性單元內實體關係的靜態信息的唯一來源是persistence.xml文件,前提是您在那裏聲明瞭實體類,因爲您可以省略它們並讓持久性管理器找到它們全部爲你。

也許你可以用一種方式來組織你的代碼,這樣可以明顯看出給定的類屬於哪個持久化單元。例如,您可以爲每個持久性單元組織程序包,也可以使用給定類所屬的持久性單元創建自定義Java註釋,然後在運行時讀取註釋。

這聽起來怎麼樣?

這些想法只是一種使用不同的靜態策略複製persistence.xml應該知道的內容。

+0

那麼,你提出了我做的**不**要做的確切的事情。我不想編寫我的工具來依賴任何特定的軟件包組織,因爲這往往會在依賴於我的工具的第三方項目中施加邪惡和晦澀的要求。正如你已經說過的那樣,persistence.xml文件可能沒有所需的所有東西,所以依靠它並不是一個好主意。正如我在我原來的問題中所說的那樣,註解方法是一種選擇,但仍然看起來像是一個不正確的答案。 – 2011-05-18 22:49:25

相關問題