1

新しいアパートを追加するためのフォームがあり、このフォームには、ユーザーが責任者を選択できるドロップダウンがあります。

どうやら私のアプリケーションは、ドロップダウンから選択してアパートを保存しようとすると、人が変更されたと考えています。そして、最初に人を保存する必要があることを示す以下のエラーが表示されます。ただし、Person は変更されません。別の人への参照で保存する必要があるのはアパートだけです。

object is an unsaved transient instance - save the transient instance before merging

Person 自身が変更されていないことをアプリケーションに理解させるにはどうすればよいですか。アパートだけ?

これが私のコードです:

@Entity
@Table(name = "Person")
public class Person{
    @Id
    private Long id;
    private String fullName;
    ....
}

@Entity
@Table(name = "Appartment")
public class Appartment{
    ....
    @ManyToOne (fetch = FetchType.LAZY)
    @JoinColumn (name = "client_contact_person_id")
    private Person clientResponsiblePerson;
}

このアクションは、すべての人を責任者のリストにロードします。

そしてJSP:

<s:select name="appartment.clientResponsiblePerson.id" list="responsiblePersons"
        listKey="id" listValue="fullName" headerKey="-1"
        label="%{getText('appartment.clientContact.ourContact')}" headerValue="%{getText('person.choose')}"
        required="true" cssClass="select medium" />

何か案は?何の解決策もなく、何時間も検索してデバッグしてきました... :(

更新: スティーブンは、から id を削除することを提案しましたappartment.clientResponsiblePerson.id。これは合理的な提案です。試してみましたが、アプリケーションがフォームから送信された値を人物オブジェクトにマップする方法を知らないようです。im設定としてlistKey="id"、送信された値は個人のIDです。

次のエラーが表示されます。 Invalid field value for field "appartment.clientResponsiblePerson".

tag 'select', field 'list', name 'appartment.clientResponsiblePerson': The requested list key 'responsiblePeople' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name} - [unknown location]

したがって、私の最初の考えは、s:select から listKey と listValue を削除する必要があるかもしれないということでした。おそらく、struts はオブジェクトから id を自動的に検出し、値に toString を使用しますか? しかし、私はこれ以上運がなくてもこれを試しました。

もう1つの非常に奇妙なことは、まったく同じことを別の形で行っていることです. そのフォームでは、ドロップダウンからエリアを選択しています。そして、名前に appartment.area.id を使用しています。そして、それはそこで完全に機能します。奇妙な..また、Area - Appartment 参照が自動的に永続化またはマージするように設定されていないことも確認しました。

私が達成しようとしていることは、本当に率直であるべきだと思います。私がここに来ていないのは何ですか?

4

1 に答える 1

1

どうやら私のアプリケーションは、ドロップダウンから選択してアパートを保存しようとすると、人が変更されたと考えています。

それがまさにあなたのコードが行っていることです。次の行が原因です。

appartment.clientResponsiblePerson.id

これは、Struts2 フレームワークに、ドロップダウンで選択した人物の ID を取得して に渡すように指示していますgetAppartment().getClientResponsiblePerson().setId(id)。それは新しい責任者に変わるのではなく、既存の担当者の主キーを変更します。setClientResponsiblePerson(Person) を呼び出すと、個人が変更されます。

代わりに使用してみてappartment.clientResponsiblePerson、それがどのように機能するかを確認してください。

アップデート

もう1つの非常に奇妙なことは、まったく同じことを別の形で行っていることです.

それがどのように機能するかはわかりません。

Struts2 は a が何であるかを認識しないPersonため、いくつかのオプションがあります。

  1. "1" (またはドロップダウンから渡されたもの) から Person のインスタンスに変換する方法を Struts2 に指示する型コンバーターを作成します。
  2. setPerson(Integer)渡された Integer 主キーに基づいて適切な Person エンティティを検索するメソッドをアクションに追加し、s:select を次のように更新します。<s:select name="person" list="responsiblePersons" .../>

個人的には#1を使っています。

于 2012-06-21T21:06:06.483 に答える