2012-05-07 16 views
0

サイトのコンテンツの「オーナー」を変更すると、次のようなエラーが表示されます。なぜこのエラーが出るのか、私は非常に混乱しています。あたかもアイテム自体のIDを変更しようとしているようです。すべてが正しいように見える...私はすべての適切な場所で探していますか?エンティティの変更を保存できません:インスタンスの識別子が変更されました

エラー

私は、文字列/整数のミスマッチを取得owner.idownerに変更

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

私のJSP。

 <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; 

Userモデル

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

答えて

1

あなたは、そこにあるUserオブジェクトのidフィールドを上書きするように指示しています。これは、JSPから取得した値がidであるためです。所有者を変更する場合は、新しい所有者であるUserオブジェクト全体を取得し、親レコード上でその参照を参照するように変更する必要があります。既存のオブジェクトのID番号を変更することはできません。

これを達成する方法はたくさんあります。普通はが使用され、値を '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

これには他にもさまざまな方法がありますが、さまざまな側面と欠点があります。私はこれをお勧めします。なぜなら、サーバ側の状態に頼らずに、潜在的な悪用を最小限に理解して公開するからです。プロパティエディタを定義する必要があるのは1回だけで、ユーザーをバインドするすべてのコントローラの1行のメソッドとしては「シンプル」です。技術的にはWebDataBinderのデフォルト設定でエディタを設定し、コントローラに何も追加することはできませんが、私はEntityクラスでそれを個人的に行うことをお勧めします。 – Affe

+0

速い応答ありがとう:) – Webnet

関連する問題