2009-08-27 40 views
2

我有有組成與定位實體更新的實體組的失敗

@ManyToOne(fetch = FetchType.EAGER, cascade = 
{ CascadeType.PERSIST, CascadeType.MERGE }) 
@Cascade(
{org.hibernate.annotations.CascadeType.SAVE_UPDATE }) 
public Location getLocation() 
{ 
    return location; 
} 

Person實體和定位實體名稱爲ID

@Id 
public String getName() 
{ 
    return name; 
} 

當人的位置有所改變我得到以下異常從Spring到MVC中的L1到L2這個Person實體是formAttribute的形式。

org.springframework.orm.hibernate3.HibernateSystemException:com.x.y.z.Location實例的標識符已從L2更改爲L1;嵌套的例外是org.hibernate.HibernateException:com.x.y.z.Location實例的標識從L2變更爲L1

回答

3

你混淆CompositionAssociation

你映射的是一個關聯; Hibernate(JPA)中的組合映射通過@Embeddable/@Embedded註釋。關聯是不同實體之間的關係;它們通常通過實體標識符(數據庫中的外鍵)連接。

你的具體情況,Person實體點Location實體,這意味着在數據庫PERSONS表有LOCATION_ID外鍵(名稱可能不同),以LOCATIONS表。你要做的是在Location端更新這個密鑰,這是非法的,因爲它會切斷Hibernate的關係(另一端仍然保留以前的內部密鑰值)。

主鍵通常應該是替代的,不可更新以開始;如果您確實需要「更新」,則必須取消關聯LocationPerson,更新Location並將其重新分配給Person,或者創建一個全新的Location實例並將其分配給您的Person。所有這一切說,如果你真的想模擬組合關係,你需要用@Embedded替換@ManyToOne並相應地改變你的表模式。這裏有一個鏈接到 關於mapping components的Hibernate Annotations文檔。

此外,在兩個單獨的註釋(JPA vs Hibernate擴展)中指定級聯類型並不是一件好事。如果你真的需要Hibernate擴展名(在這種情況下你不這樣做),只需使用它並將JPA註釋中的cascade屬性留空即可。

+0

謝謝。它幫助。 – 2009-08-28 11:14:24

0

我在獨立應用程序中做了同樣的事情。事情起作用。我認爲它應該是@modelAttribute的一些問題。

0

您所在地區的實體屬性ID 類型在模型類被改變。請參閱ID和映射屬性ID類型相同。使確保id屬性getter和setter函數的返回類型。