inputPeriodという名前のカスタムJSF入力コンポーネントがあります。これは、日付期間を入力するように設計されています。各期間には、開始日と終了日があります。コンポーネントの機能は、JSON文字列を生成してコンポーネントに送信するJavascriptで実現されます。次に、入力コンポーネントは、JSON期間をPeriodオブジェクトのリストに変換し、それらを管理対象Beanに設定するデフォルトのコンバーターを使用します。これはすべて完璧に機能します。
私が抱えている問題の原因は、EJBエンティティで同じコンポーネントを使用したいということです。BannerPeriodエンティティと1対多の関係にあるBannerエンティティがあります。BannerPeriodエンティティの各インスタンスは、入力コンポーネントで使用している既存のPeriodオブジェクトとまったく同じように、開始日と終了日を取得します。私はこれのために新しいコンバーターを実装しました:
@ManagedBean
@RequestScoped
public class BannerPeriodConverter implements Converter {
@Override
public Object getAsObject(FacesContext fc, UIComponent uic, String str) {
if (str != null) {
Date from = null, to = null;
try {
JSONObject period = new JSONObject(str);
if (period.has("from")) {
from = new Date(period.getLong("from"));
}
if (period.has("to")) {
to = new Date(period.getLong("to"));
}
} catch (JSONException ex) {
throw new ConverterException(ex);
}
BannerPeriod bp = new BannerPeriod();
bp.setBegins(from);
bp.setEnds(to);
return bp;
}
return null;
}
@Override
public String getAsString(FacesContext fc, UIComponent uic, Object o) {
if (o != null && o instanceof BannerPeriod) {
BannerPeriod bp = (BannerPeriod) o;
JSONObject period = new JSONObject();
try {
period.put("from", bp.getBegins() != null ? bp.getBegins().getTime() : (Object) null);
period.put("to", bp.getEnds() != null ? bp.getEnds().getTime() : (Object) null);
} catch (JSONException ex) {
throw new ConverterException(ex);
}
return period.toString();
}
return "";
}
}
コンバーターはコンポーネントで正常に動作します。私が抱えている問題は、既存のバナー期間でバナーを編集すると、エンティティが主キーを失うことです。したがって、フォームを送信すると、既存の期間を更新する代わりに、重複する例外が発生するか、既存の期間が再度作成されて、データベースに実際の重複が作成されます。
だから私の質問は、これを避けるために何ができるかということです。私の推測では、入力コンポーネントは何らかの形で既存のエンティティの主キーを保持する必要がありますが、どうすればそのようなものを作成するのが最善でしょうか?現時点では、入力コンポーネントはエンティティとEJBプロジェクトから完全に切り離されています。入力コンポーネントは独自のJSFプロジェクトにありますが、上記のコンバーターはEJBプロジェクトにあります。デフォルトでは、入力コンポーネントは、主キーをまったく持たないプレーンなPeriodオブジェクトで機能します。それはそうし続けるべきです。
それとも、これは他の方法で解決する必要がありますか?