2012-03-06 16 views
2

這可能是一個非常愚蠢的問題,但...爲什麼JPA生成的更新查詢包含比必要的字段更多的字段?

我使用JPA 2.0與Hibernate 4.我有一個持久對象,有很多領域。

我創建並在一次事務中堅持它。然後,在另一個,我期待該對象並改變其一個字段的值:當事務提交

try{ 
    tx.begin(); 
    MyObj object = myObjDAO.findById(objectId); 
    object.setFieldA("Different value"); 
} finally { 
    tx.commit(); 
} 

JPA持續這種變化,但我可以從我的MySQL看到genquery.log的更新語句它生成涉及該對象上的所有字段:

439查詢
/*更新uk.co.core.objects.MyObj * /更新MyObj中集創建= '2012-03-06 13時39分37秒' ,modified ='2012-03-06 13:39:37',version = 1,fieldA ='Different value',fieldB ='originalValue',fieldC ='originalValue'其中id ='objectId'和版本= 0; 439查詢提交

爲什麼它包括所有不變字段及其現有值查詢,而不僅僅是:

更新MyObj中設置FIELDA =「不同的價值」,版本= 1, modified ='somedate'其中id ='objectId'和version = 0;

這個例子看起來可能沒有太大區別,但我有一些對象具有更多字段,所有這些對象都包含在它們的更新語句中。

即使純粹從字符串數據的角度來看,更新查詢中只包含更改的字段,它會不會更快/更高效?如果是這樣,是否有一個配置選項可以讓它這樣做?

希望你能幫忙,謝謝!

回答

1

您可以配置休眠到排除更新查詢中的未修改字段,如article中所述。

這是通過在您的類映射中添加dynamic-update="true"來完成的。

<class ... table="your_table" .... dynamic-update="true"> 

在包含許多列(傳統設計)或包含大量數據的大型表中,這會對系統性能產生很大影響。

它可以有一些性能影響,如告訴here。因此,在實現代碼之前,請測量代碼的性能。

閱讀API here瞭解更多信息。

1

要堅持只是差異的你的ORM必須:

  1. 閱讀你的對象的當前版本,與數據庫中的所有它的子實體, 。
  2. 迭代每個屬性並比較它們的值,看它是否有 已更改。
  3. 生成專門的查詢,僅用於更新 已更改的屬性。

這顯著不僅僅是發放所有列的標準更新更加複雜,而且也將是顯著高性能,由於增加了複雜性。

+0

一個專門的** HQL **是一個好主意,當你確切知道要更新什麼時,無論版本。但是恐怕你的解決方案可能是**性能開銷,因爲對象必須加載到內存中,然後應該進行比較**。 – ManuPK 2012-03-06 14:37:59

0

現在發現在同一問題中提出2個問題的危險。 ManuPK和Perception都給出了很好的,有用的,正確的答案。不過,我從ManuPk獲得了更多的信息和理解,因此我接受了它。

肯定與他同意 - 設置屬性應該只對某些表格進行設置,並且性能應該在測試前後進行測試。

未來,我會盡量讓我的問題更有針對性。

相關問題