JSF / PrimeFacesの問題に出くわしました。バッキング Bean のスコープを変更することで問題を解決できましたが、最初のケースで失敗した理由を理解したいと思います。そのため、動作を再現する絞り込んだ例を次に示します。
フォーム内に 2 つのp:dataTablesを上下に表示する単純なxhtmlページがあります。一番上のp:dataTableには数値が表示され、2 番目にはその除数が表示されます。したがって、古典的なマスター詳細ビューがあります。ボタンを使用してページを更新できるため、上のテーブルから新しい数値を選択すると、その除数を下のテーブルに表示できます。
<h:form id="NUMBERS-form">
<p:dataTable id="dt1" var="item" value="#{numbersController.divisorSets}"
rowKey="#{item}" rows="10" selection="#{numbersController.selectedDivisorSet}"
selectionMode="single">
<p:column>
#{item}
</p:column>
</p:dataTable>
<p:dataTable id="dt2" var="item" value="#{numbersController.divisors}"
rowKey="#{item}" rows="10" selection="#{numbersController.selectedDivisor}"
selectionMode="single">
<p:column id>
#{item}
</p:column>
</p:dataTable>
<p:commandButton id="Update" ajax="true" update=":NUMBERS-form"
action="#{numbersController.foo}" value="update"/>
</h:form>
バッキング Bean は 2 つの読み取り専用コレクションを定義します。1 つはDivisorSets (つまり、除数を見つけたい数値) 用で、もう 1 つは現在選択されている数値の除数用です。また、現在選択されている数値とその数値の現在選択されている除数の 2 つのフィールドとプロパティの getter/setter があります。
@ManagedBean
@ViewScoped // if this is toggled to @RequestScoped it stops working
public class NumbersController implements Serializable {
private static final Logger l = Logger.getLogger(NumbersController.class.getName());
public List<DivisorSet> getDivisorSets() {
List<DivisorSet> retValue = new ArrayList<DivisorSet>();
for (int i = 10 ; i < 20 ; i++)
retValue.add( new DivisorSet(i) );
return retValue;
}
public List<Integer> getDivisors() {
if (selectedDivisorSet != null)
return selectedDivisorSet.getDivisors();
else return null;
}
private DivisorSet selectedDivisorSet;
// getter and setter ...
private Integer selectedDivisor;
// getter and setter ...
public String foo() { return null; }
}
ページが最初にロードされると、最上位のp:dataTableのみが読み込まれます。一番上のテーブルの行が選択され、p:commandButtonが押されると、その数の除数が一番下のp:dataTableにフェッチされます。ここまでは順調ですね。ここで問題が発生します。行が上部のテーブルから選択され、行が下部のテーブルからも選択され、p:commandButtonが押された場合、セッターにあるログ メッセージは次のことを明らかにします。
- バッキング Bean のスコープが[表示]に設定されている場合、選択された両方の数値がモデル値の更新フェーズで正しく設定されます
- バッキング Bean のスコープがRequest only the selected number from the top table に正しく設定されている場合、selectedDivisorフィールド (下部のp:dataTableにリンクされている) のセッターは値 0 (または他のフィールドでは null) を持ちます。さまざまなクラスを使用して試した例)。
この簡単な例には、下のp:dataTableから数値を選択する必要があるというビジネス ロジックがないことに注意してください。これは、実際のコンテキストで発生した同じ問題の絞り込みバージョンにすぎません。ビューがRequestScoped の場合(成功したViewScopedとは対照的に) 、下のテーブルの選択された値が正しく設定されない JSF ライフサイクルの手順を誰かが説明できますか?