2012-05-07 53 views
0

當我更改我網站上某條內容的「所有者」時,出現如下所示的錯誤。我很困惑,爲什麼我得到這個錯誤。看起來好像它試圖改變項目本身的ID。一切看起來都是正確的...我在尋找所有正確的地方嗎?無法保存實體更改:實例的標識已被更改

錯誤

Caused by: org.hibernate.HibernateException: identifier of an instance of com.site.model.User was altered from 13 to 72 

我的JSP

當我改變owner.idowner我得到一個字符串/整數不匹配。

 <label class="formLabel">Owner <img src="/images/s.gif" class="required"/><br/> 
      <form:select path="owner.id" id="owner"> 
       <form:options items="${owners}" itemValue="id" /> 
      </form:select> 
     </label> 

我的服務

Content cm = em.merge(content); 
    em.flush(); 

內容模型

@NotNull 
@JoinColumn(name = "owner_id", referencedColumnName = "id") 
@ManyToOne 
@IndexedEmbedded 
@JsonIgnore 
private User owner; 

用戶模式

@Id 
@Basic(optional = false) 
@Column(name = "id") 
@GeneratedValue(strategy= GenerationType.IDENTITY) 
@JsonIgnore 
private Integer id; 

回答

1

您正在告訴spring在用戶對象上覆蓋id字段,其​​中的值取自JSP中的id。如果要更改所有者,則需要獲取作爲新所有者的整個User對象,並將引用更改爲指向父記錄。您不能只更改現有對象上的ID號。

有很多方法可以實現這個目標,通常使用PropertyEditor,所以你直接將一個數字綁定到值'owner'並提供一個類,告訴spring如何將一個數字轉換爲一個User實例。

在窗體上,結合「擁有者」,而不是「ID」:

<form:select path="owner" id="owner"> 
    <form:options items="${owners}" itemValue="id" /> 
</form:select> 

在控制器中,初始化屬性編輯器:

@InitBinder 
private void registerPropertyEditor(DataBinder binder) { 
    binder.registerCustomEditor(User.class, "owner", new UserPropertyEditor(userService)); 
} 

然後你犯了一個類,告訴春如何把ID號到用戶:

public class UserPropertyEditor extends PropertyEditorSupport { 

    private UserService userService; 

    public UserPropertyEditor(UserService userService) { 
     this.userService = userService; 
    } 

    @Override 
    public String getAsText() { 
     //Handle null value, value of incorrect type, etc here 

     return String.valueOf(((User) getValue()).getId()); 
    } 

    @Override 
    public void setAsText(String id) throws IllegalArgumentException { 
     //handle empty string, number format exception, etc 

     User user = userService.getUser(integerId); 

     setValue(user); 
    } 

} 
+0

我感謝所有的努力......但看起來這應該是簡單 – Webnet

+0

還有其他的方式,他們有各種各樣的上漲和下跌。我建議這一點,因爲它很容易理解,並且在不依賴服務器端狀態的情況下展示最少的潛在漏洞。記住,你只需要定義屬性編輯器一次,然後在綁定用戶的任何控制器中作爲一個「簡單」方法。您可以在技術上將編輯器設置爲WebDataBinder的默認配置,並且絕不會向控制器添加任何內容,但我建議不要爲Entity類個人做這些。 – Affe

+0

感謝您的快速回復:) – Webnet