1

私はたくさんの財産を持っている豆を持っていて、それらの半分はn対nの関係にあります。また、一時的な' isEdited 'ブール値を追加して、ユーザーがいくつかの変更を行ったことを確認し、すべてのエンティティのdbフェッチを減らすことができるようにしました。私の現在の問題は、Beanをシリアル化する必要があり、プロパティを実際のインスタンスと比較したい場合があります。私が試した最初の解決策は、apache commons-lang =>EqualsBuilder.reflectEqual();メソッドからのものです。これは、継承されたアイテムの一部がequalsメソッドを正しく実装しておらず、編集できないため、うまく機能しません。編集されたプロパティを更新するためにajaxリスナーを追加したり、各setterメソッドまたは新しいequals実装を更新したりできることはわかっています。しかし、私はもう少し実用的で一般的な方法を探しているので、将来的にもこの実装を使用できます。

だから私が欲しいもの:(私は単純な豆を持っているとしましょう):

public class Foo {

    private String prop1;

    private String prop2;

    /**
     * @return the prop1
     */
    public String getProp1() {
        return prop1;
    }

    /**
     * @param prop1 the prop1 to set
     */
    public void setProp1(String prop1) {
        this.prop1 = prop1;
    }

    /**
     * @return the prop2
     */
    public String getProp2() {
        return prop2;
    }

    /**
     * @param prop2 the prop2 to set
     */
    public void setProp2(String prop2) {
        this.prop2 = prop2;
    }



}

私のBeanよりもEventListenerインターフェースを実装し、このリスナーがすべてのセッターを処理します。(初期化後に)呼び出されたセッターメソッドの場合、編集されたプロパティはtrueに設定されます。

だから私の質問は、セッターを処理するためにアクション/イベントリスナーを追加する適切な方法は何でしょうか?

編集** PropertyChangeListenerを試しましたが、イベント出力がありません。そして、各セッターpcs.firePropertyChange();メソッドを追加した場合、それらのメソッドを介してisEditedを真に設定できることは意味がありません。

4

1 に答える 1

1

Map<String,Boolean>各セッターでそれを更新できませんか?prop1たとえば、次のようにします。

public void setProp1(String prop1) { 
    if(!prop1.equals(this.prop1))
        updateMap.put("prop1", true);
    this.prop1 = prop1;
}

このようにして、エンティティを保存するときに、その「メタデータ」を含むマップが作成されます。

編集:ユーザーが値を設定してから元に戻ると、マップが true のままになるため、難しい問題があります。元の値を使用して別のマップ (またはオブジェクトのクローン) を作成し、両方を比較することで、これを回避できます。

public void setProp1(String prop1) { 
    if(!prop1.equals(this.prop1) && !prop1.equals(ORIGINAL_VALUE))
        updateMap.put("prop1", true);
    else
        updateMap.put("prop1", false);
    this.prop1 = prop1;
}

編集: Adam は側面については正しく、実際、変更には時間がかかる可能性があります。また、リフレクションを使用する場合は、メソッドの構造に縛られているため、別の問題があります。将来、メソッドの名前や型を変更したい場合は、そのリフレクション ヘルパー クラスも更新する必要があります。

元の値と比較できるように、保存する前に一時的な値を更新することをお勧めしますが、ゲッターなしでフィールド/オブジェクトに直接アクセスする場合はメソッドを変更する必要があります。

最後に、3 番目のオプション (常に 3 番目のオプションがあります) と、valueChangeListenerコンポーネントで を使用することです。例えば:

<h:inputText id="prop1Input" value="#{bean.prop1}" valueChangeListener="#{bean.changesListener}"/>

そして、Bean には次の構造を持つメソッドが必要です。

public void changesListener(ValueChangeEvent e) {
    //Get the new value
    Object o = e.getNewValue();
    //get the component's id
    String componentId = e.getComponent().getId();
    //Cast the value and compare it, after that you should update a map. You are
    //going to need one anyway to know which field changed.
    boolean valueChanged = //compare against original value
    if(componentId.equals("prop1Input"));
    map.put("prop1", valueChanged);
}

このアプローチに関する重要な注意事項として、リスナーは検証フェーズ中に実行されます。このリスナーの意図は、新しい値と古い値の両方を処理できるようにすることです。これはあなたのケースのようです。それを起動したコンポーネントもわかるので、問題ないはずです。

于 2012-10-08T13:28:07.980 に答える