検証エラー:値が無効です
P:selectOneMenuに問題があります。どうしてもJSFにJPAエンティティのセッターを呼び出させることはできません。 JSF検証は次のメッセージで失敗します。
form:location:検証エラー:値が無効です
私はこれを同じタイプのいくつかの他のクラスで動作させています(つまり、テーブルクラスを結合します)が、私の人生ではこれを動作させることはできません。
誰かがこの種の問題のトラブルシューティング/デバッグのヒントを投げることができれば、それは大歓迎です。
ログステートメントを使用して、次のことを確認しました。
Conveter
は、null
以外の正しい値を返しています。- JPAエンティティにBean Validationがありません。
- セッター
setLocation(Location location)
は呼び出されません。
これは私ができる最も簡単な例であり、単に機能しません:
<h:body>
<h:form id="form">
<p:messages id="messages" autoUpdate="true" />
<p:selectOneMenu id="location" value="#{locationStockList.selected.location}" converter="locationConverter">
<p:ajax event="change" update=":form:lblLocation"/>
<f:selectItems value="#{locationStockList.locationSelection}"/>
</p:selectOneMenu>
</h:form>
</h:body>
コンバータ:
@FacesConverter(forClass=Location.class, value="locationConverter")
public class LocationConverter implements Converter, Serializable {
private static final Logger logger = Logger.getLogger(LocationConverter.class.getName());
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value.isEmpty())
return null;
try {
Long id = Long.parseLong(value);
Location location = ((LocationManagedBean) context.getApplication().getELResolver().getValue(context.getELContext(), null, "location")).find(id);
logger.log(Level.SEVERE, "Converted {0} to {1}" , new Object[] {value, location});
return location;
} catch (NumberFormatException e) {
return new Location();
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null || value.toString().isEmpty() || !(value instanceof Location))
return "";
return String.valueOf(((Location) value).getId());
}
}
コンソール出力:
// Getter method
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0]
// Session Bean
INFO: Finding ejb.locations.Location with id=3
// Session Bean
INFO: ### Returning : ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3]
// Converter
SEVERE: Converted 3 to ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3]
// Getter method -> Where did my selected Location go ??
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0]
私の場合、正しいget/setメソッドを実装するのを忘れていました。開発中に多くの属性を変更したために発生しました。
適切なgetメソッドがないと、JSFは選択したアイテムを復元できず、BalusCが彼の答えのアイテム1で言ったことを実行します。
1選択したアイテムが利用可能なアイテムのリストにありません。これは、使用可能なアイテムのリストが、後続のリクエストで適切に再初期化されていないリクエストスコープBeanによって処理される場合、または何らかの方法で異なるリストを返すゲッターメソッド内でビジネスジョブを誤って実行している場合に発生します。
これは、コンバーターの問題またはDTOの問題の可能性があります。オブジェクトDTOにhashCode()およびequals()メソッドを追加して、これを解決してください。上記のシナリオでは、ここで「DTO」として示すこれらのメソッドをLocationオブジェクトクラス内で生成できます。
例:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Location other = (Location) obj;
if (id != other.id)
return false;
return true;
}
- 上記の例は、 'long'型の 'id'用です