0

オンライン学習用の Java EE アプリを作成したいと考えています。私はこのデータ表現を考えています:

@Entity
public class Course {
    private String name;
    private String[] instructors;
    private String[] teachingAssistants;
    private GradeBook gradeBook;

    // plenty of methods
}

@Entity
public class GradeBook {
    private GradeBookColumn[];

    // some methods
}

@Entity
public abstract class GradeBookColumn {
    private String name;
    private GradeBookColumnType type;

    // more methods
}

それだけではありませんが、要点はわかります。

現在、EJB 3.2 仕様では、エンティティ Bean が削除され、JPA エンティティに置き換えられています。私の質問は、この悲劇的な喪失にどう対処するかです。シリアル化された JPA エンティティが機能しない理由は 3 つあります。

  1. パフォーマンス。エンティティ全体とそのすべてのデータをネット経由でプッシュする必要があります。そのデータは非常に多く、すべてを処理するには許容できないほど長い時間がかかる可能性があります。
  2. 安全。エンティティ内のすべてのデータがネット経由で転送される場合、そのデータをダウンロードしたプログラムからすべてのデータにアクセスできます。ただし、ユーザーが十分な権限を持っている場合にのみ、特定のデータにアクセスできるようにしたいと考えています。
  3. 書き込みアクセス。データのコピーがダウンロードされると、クライアントはそれを変更できるようになります。ただし、変更が行われた場合、それらはサーバーに永続化されません。もちろん、エンティティを永続化するためにいつでもサーバーに送り返すこともできますが、すべてのデータをさらに遅いアップストリーム接続を介して送信する必要があります。

では、エンティティ Bean を使用せずにこれらの要件を満たすようにこのシステムを設計するにはどうすればよいでしょうか。

4

1 に答える 1

1

エンティティ Bean の喪失が本当に悲劇的かどうかはわかりませんが、それは意見の問題です :)

リモート サーバーに接続するデスクトップにリッチ クライアントがあるようです。次の 2 つのオプションがあります。

A. ク​​ライアントとサーバーの間で「切り離された」オブジェクト グラフを交換します。クライアントは何らかのデータを受け取り、それを変更してから送り返します。次にサーバーは、受信したデータを「マージ」します。サーバーには、データをロードするときに 1 つのトランザクションがあり、マージ バックするときに 1 つのトランザクションがあります。競合が発生しないようにするために、データをバージョン管理できます。

B. 「拡張永続コンテキスト」を使用します。その場合、クライアントはまだセッションに「接続」されているエンティティを受け取ります。クライアント側のエンティティへの変更はキャッシュされ、サーバーでメソッドを呼び出すと同期されます。

だから、あなたが直面している3つのデザインの問題に関して、これが私の見解です:

  1. パフォーマンス。JPA やその他の最新の ORM は、不必要なデータ転送を避けるために遅延に依存しています。データはオンデマンドでロードされます。グラフのどの部分を積極的または遅延的にロードできるかを選択できます。オプション A では、クライアントにデータを送信する前に、必要なデータをすべてロードする必要があります。クライアントがロードされていないデータにアクセスしようとすると、トランザクションの外部にあるため、例外が発生します。オプション B を使用すると、クライアントはいつでもデータを遅延ロードできると思います (再確認する価値があります)。

  2. 安全。JPA エンティティは、データ オブジェクトではなく、ビジネス オブジェクトである必要があります。必要なチェックを行い、必要な不変条件を保持するビジネス メソッドをカプセル化できます。つまり、セキュリティはデータ レベルではなく、ビジネス ロジック レベルで処理されます。これは、オプション A と B の両方に適用されます。

  3. 書き込みアクセス。オプション A では、グラフ全体を返送してマージする必要があります。オプション B では、フレームワークはキャッシュされた変更をより最適化された方法でマージする必要があります。

結論:

拡張永続コンテキストは、長い作業単位を持つ GUI アプリケーション用に設計されています。彼らは理論的にはあなたの問題を解決するはずです。ただし、実際には、拡張永続コンテキストには複雑な部分があります (たとえば、ステートフル セッション Bean を使用する必要があります)。

グラフをデタッチしてマージするアプローチはより簡単ですが、パフォーマンスに関して言及した問題が発生します。

3 番目のオプションは、従来のデータ転送オブジェクト (DTO)に戻ってパフォーマンスを最適化することです。その場合、JPA エンティティはサーバー側だけにとどまります。JPA エンティティを転送する代わりに、本当に必要なデータのサブセットのみを DTO に転送します。欠点は、DTO が急増することであり、JPA エンティティから DTO を作成し、DTO から JPA エンティティを更新するボイラープレート コードが必要になります。

于 2013-09-09T06:58:57.310 に答える