2014-04-28 37 views
1

我正在使用Spring 4和休眠4. 我有一個問題,它似乎有很多其他人擁有。我希望我的Spring表單只編輯實體的某些屬性,而不是整個事物。如何加載一個持久化的Hibernate實體進行綁定,所以非表單屬性不會丟失?

默認情況下,如果我加載持久實體,在窗體中顯示一些屬性以進行編輯,將其發佈到我的控制器並保存它...任何未包含在窗體中的屬性值都將丟失。我明白爲什麼會發生這種情況,並且我知道有一些解決方案在那裏浮動。

1)在保存時間,從數據庫加載實體,只複製你想要從模型中的屬性,保存。

2)表單開始時,加載實體並使用@SessionAttributes功能將其存儲在請求之間的會話中。

但我不喜歡這些中的任何一個。也許我錯過了一些東西,但解決方案看起來相當簡單。 某處,默認的Spring Web活頁夾正在創建實體的實例以將表單屬性複製到其中。如果我可以重寫它並使用ID從數據庫中加載持久化實體,那麼Spring的綁定就會使用它作爲目標實體(只複製與表單一起提交的屬性,而不改變其他屬性)...然後我認爲會解決我的問題。

我一直在尋找/如何使用自定義WebDataBinder類。我不明白......我甚至不確定這是我應該尋找的地方。

有什麼建議嗎?

謝謝!

編輯:
我給一個假設的例子,試圖更好地解釋我的問題。 假設我有一個實體類Customer,它有50個屬性。我只有一個更新聯繫信息的表單。這僅僅是5個屬性出50

街道
城市
狀態
拉鍊
電話

如果我這樣做是在春天的形式,當表單提交爲了保存,Spring創建一個新的「空白」實體,用表單中的值填充它並將其傳遞給我的控制器...這就是保存的內容。問題在於,由於其他屬性(如firstName,lastName,customerType等)未包含在窗體中,因此Spring將它們保留爲空,並且它們保持爲空。當我告訴Hibernate使用Spring提供的這個實體來更新實體時,Hibernate相信我希望firstName,lastName等爲null,因爲這些是我在bean中提供的值。它不知道我只改變了其中的一些。
那麼會發生什麼?我的50個屬性值中有45個會被吹走。

在下面的評論中,Sp00m提出了一個可行的解決方案......將所有其他屬性包含在隱藏字段中。但由於各種原因,這個解決方案對我來說是一個非常頭痛的問題。

如果我可以讓Spring從數據庫加載實體(而不是創建一個新的/空白實體),然後只填充那些與表單一起提交的字段。我相信這會解決我的問題。

類似的討論(但與隱場解決方案)可以在這裏找到.. http://www.coderanch.com/t/529490/Spring/Spring-MVC-Hibernate-Update-column

+0

另一個簡單的解決方案是將*非表單屬性*綁定到''標籤。 – sp00m

+0

感謝您的回覆。你是對的,但我有很多不同的實體類,有很多屬性。我有不同的形式,根據各種條件編輯不同的屬性。就我而言,該解決方案太乏味且容易出錯。 – user3311662

+1

我會建議添加代碼和配置示例,否則其猜測遊戲。我不能相信這是框架的默認行爲(我也沒有記得Spring MVC存在這個問題,但是當Spring 2仍然是最新的時候,我最後使用了它)。我寧願懷疑這個框架沒有被正確應用。但是沒有什麼可看的,那就是我猜測。 – Gimby

回答

1

所以這裏是爲我工作的解決方案。 通過在控制器中添加以下方法和註釋,Spring使用它來實例化綁定實體。正是我需要的。

(我實際上已經試過這一點以前,但我沒有具體說明這些模型在註釋,這顯然是沒有好處的屬性名。)

感謝所有那些誰與建議評論。

@ModelAttribute("entity") 
public MyEntity getEntity(@RequestParam(required=false) Integer id) 
{ 
    if (id == null) 
    { 
     return myEntityManager.createEntity(entityClass); 
    } 
    else 
    { 
     return myEntityManager.find(entityClass, id); 
    } 
} 
相關問題