2014-03-13 53 views
0

我有一個數據庫有3個表。主表是Contract,它與來自兩個表的鍵對配對:LanguagesRegions。 每一對都是獨一無二的,但它是可能的一個合約將有以下對IDS:休眠三表很多很多

{ (1,1), (1,2), (2,1), (2,2) } 

今天,三個表經由連接實體鏈接稱爲ContractLanguages。它包含一個序列ID,以及來自三個表的id的三元組。 但是,在足夠大的合同中,這會導致嚴重的性能問題,因爲休眠環境會產生數量驚人的對象。 因此,我們想刪除這個連接實體,以便合約將保存這些對的一些集合。

我們建議的解決方案:創建一個包含Language和Region id的@embeddable類,並將它們存儲在Contract實體中。 這個背後的想法是,有相對少數的語言和地區。 我們假設hibernate管理這些對的列表並且不會創建重複項,因此大大減少了創建的對象的數量。

但是,我們有以下問題:

  1. 請問這個解決方案的工作?冬眠會知道創建正確的對象嗎?
  2. 假設解決方案有效(鏈接已正確創建),hibernate會優化對象創建以停止創建重複對象嗎?
  3. 如果此解決方案不起作用,我們如何解決上述問題而無需連接實體?
+0

是否可以保持連接實體,但採用延遲加載?如果我正確地理解你,每個合同可能只有有限數量的這種連接實體 - 你在使用時是否需要這些實體?多個合同?除此之外,您可以使用查詢來僅從連接表中加載id(例如'SELECT connection.region.id,connection.language.id,... FROM ContractLanguages connection ...')並手動創建對象需要。 – Thomas

+0

看看我的網站上的帖子,也許它會很有用:http://itmuslim.org/blog/2014-03-13-629 – DmitryKanunnikoff

+0

@Thomas我確實需要他們,因爲我在我的系統中持有很多合同一次,他們每個人可以有完全相同的對,所以我試圖實現的是隻持有一對實體,所有的合同都會有一套對這個實體的引用。我不確定我是否理解你的第二個建議,請你詳細介紹一下。 – DiSol

回答

0

從您的文章和評論我假設以下情況,請糾正我,如果我錯了:

  • 你有一組有限的Languages + Regions組合(目前建模爲ContractLanguages實體)
  • 你有一個巨大的Contract實體
  • 量每手合約可以引用多個LanguagesRegions
  • 你必須加載所有合同語言問題,因爲目前的組合是由合同+語言+基於這些假設區域

的,有幾個可能的優化來我的腦海:

  • 您可以創建一個LanguageRegion實體,它具有唯一的id,每個合約引用一組這些實體。這樣你會得到更多的表,但是Hibernate只會根據LanguageRegion創建一個實體,並在每個會話中加載一次,即使多個合約都會引用它。爲了正常工作,您應該使用延遲加載,並可能在加載合同之前將這些實體加載到第一級緩存中。

  • 或者,您可以只加載所需的列,即只加載實體的一部分。您也可以使用延遲加載,但不會直接訪問合約語言,而是在單獨的查詢中加載它們,例如(名猜)

    SELECT c.id, lang.id, lang.name, region.id, region.name FROM Contract c 
    JOIN c.contractlangues cl 
    JOIN cl.language lang 
    JOIN cl.region region 
    WHERE c.id in (:contractIds) 
    

    然後你載入合同,獲得它們的ID,使用查詢負載的語言和區域具體情況選擇(它返回一個包含列值的對象數組List<Object[]>。你把那些到一個合適的數據結構,並根據需要訪問它們。這樣,你會分流實體的創建和剛剛獲得所需要的數據。

+0

您的假設是正確的,我們已經開始實施我們的@embeddable想法,看看它是否會像我們預期的那樣工作(實際上它爲每個可能的配對創建一個且只有一個實體,並且我們期望所有合約lang + reg集合都能成立參考相同的實體),但如果它不起作用,我們會按照我們的計劃進行操作,而這正是您在第一點中所寫的內容(我們儘可能避免數據庫更改)。關於第二個解決方案,我不確定我明白這個後續查詢應該放在哪裏?它是否在hibernate表def之外? – DiSol