3

Hibernate/JPAの世界で入力を受け取るdataTablesを処理する正しい方法は何でしょうか。私の知る限り、次の3つの選択肢のいずれかが原因で、カードの家全体が崩壊していますが、どちらが間違っているのかわかりません。

  • すべてのリクエストの前後でトランザクションを開始およびコミットするカスタムJSFPhaseListenerを介した半自動トランザクションおよびEntityManager処理
  • 編集コンポーネントをdataTable内に配置する
  • リクエストスコープのEntityManagerからデータをフェッチするリクエストスコープのマネージドBeanを使用する(PrettyFacesの助けを借りてURLからリクエストスコープのBeanにIDを設定する)
  • ビュースコープまたはセッションスコープのBeanではなく、リクエストスコープのBeanを使用してdataTableをバックアップします。

JPAを使用したICEfacesdataTableデモが表示されますが、どちらもトランザクションを手動で管理しており、デフォルトでは編集コンポーネントを表示していません。オブジェクトが編集可能に指定される行をクリックし、[保存]をクリックすると、手動で保存をトリガーする前に、オブジェクトを新しいEntityManagerに手動で再接続します。ここでクリックして編集する機能は、適切なオブジェクトが現在のセッションに確実に再アタッチされるようにする方法を提供していると思います。同様の機能がないとどうなるかわかりません。

新しいICEfaces3.0ace:dataTable(旧称PrimeFaces 2.0 dataTable)について私が得ている印象は、ビュースコープまたはセッションスコープのBeanで使用することを目的としているということですが、StaleObjectStateを回避する方法がわかりません。および/またはLazyInitializationExceptions(リクエストAおよびEntityManager AでDAOから出て、EntityManagerBを使用してリクエストBによって変更またはページインされたモデルオブジェクトがある場合)。

ある種の深いfuを介してJavaEEで動作する可能性があると思いますが、Tomcat 6からより洗練されたものにアップグレードする余裕はありません(長期的には私の意図ですが)。また、SpringやSeamなどのクールなものを使い始めるつもりはありません。ICEfacesは私たちにとって十分に奇妙であり、正直言ってあまりにも奇妙です。

要約すると、これらのどれが間違った選択ですか?リクエストスコープのエンティティマネージャー、リクエストスコープのdataTable、またはdataTable内の編集コンポーネントを使用していますか?それとも、ここで他に何か問題がありますか?

4

1 に答える 1

4

私に言わせれば、あなたの要件が少し凝ったものを求めて叫んでいるように見えるとき、主な欠点はほとんど裸のTomcatに固執しているようです。マントラは通常、「その他すべてのもの」が必要ないときにTomcatを使用することです。したがって、必要なときに、裸のTomcatを使用し続けるのはなぜですか。

そうは言っても、パターンはそれほど難しくありません。

  • ビュースコープのバッキングBeanを使用する
  • @PostConstruct-(IDなどのパラメーターがない場合)またはPreRenderViewEventビューパラメーターと組み合わせたメソッドで初期データを取得します
  • エンティティマネージャを使用してデータを取得および保存する別のサービスクラスを使用する
  • エンティティマネージャを「トランザクションスコープ」にする
    • EJB / CDI / Springなし:
      • 操作ごとに、エンティティマネージャファクトリから新しいエンティティマネージャを取得します。
      • (リソースローカル)トランザクションを開始し、操作を実行し、トランザクションをコミットして、エンティティマネージャーを閉じます。
  • バッキングBeanから直接エンティティのリストを返し、テーブルの編集モード入力フィールドをエンティティの対応するプロパティにバインドします。
  • 単一の行を更新する場合は、対応するエンティティをサービスの更新メソッドに渡します。エンティティマネージャーの取得、トランザクションの開始などのオーバーヘッドは別として、これは基本的merge()にエンティティマネージャーのみを呼び出します。

あなたがdetached entitiesいつも一緒に働いているサービスの外でそれを理解してください。したがって、LazyInitializationExceptionsのリスクはありません。バッキングBeanはビュースコープ内にある必要があるため、正しい(デタッチされた!)エンティティがJSFによって更新され、JSFが独自のコードをサービスに渡し、サービスが永続コンテキストにマージします。

したがって、永続化のフローは次のようになります。

状態の               表示スコープの表示        トランザクションスコープのPC
フェイスレット/コンポーネント       バッキングBean       サービス
      文字列------>切り離されたエンティティ->接続されたエンティティ

(データを取得するためのフローはまったく逆です)

この方法でサービスを作成するのは少し面倒で、一種のマゾヒストの練習です。サンプルアプリと上記の2つの方法(getとupdate)の場合、それほど悪くはありませんが、サイズの大きいアプリの場合、これはすぐに手に負えなくなります。

すでにJSFとJPAをTomcatに追加している場合は、 TomEEのようなものを使用してください。これはTomcatよりもわずかに大きく(25MB対7MB)、避けようとしていると思われるものがすべて含まれていますが、実際にはとにかく必要です。

Tomcatのインストールを完全にアップグレードできない場合(たとえば、製品の所有者または管理者が開発者ではなくサーバーを所有していると考えている場合)、CDIの学習に投資することをお勧めします。これはあなたの戦争に簡単に追加することができ(たった1つの余分なjar)、退屈なコードの多くを抽象化しましょう。また、実際に使用できるものの1つは、JTAプロバイダーです。これも戦争に個別に追加できますが、追加するものが多いほど、TomEE(またはGlassFish、Resin、JBossなどの代替手段)を使用するだけでうまくいきます。

要件のさまざまな部分をカバーするこの記事も参照してください:JSF2.0での通信

于 2012-02-19T11:43:06.690 に答える