3

数週間前に EJB を学び始めましたが、クライアント側とサーバー側でエンティティ クラスを再利用する方法について質問があります。CRUD アプリケーションがあるとします。

  1. サーバーは EJB として記述され、データを管理します (作成、読み取り、更新、削除)。JPAを使用してデータベースに接続します。
  2. クライアントは JSF2 を使用して作成されており、リモート EJB を使用してデータを管理する単純な GUI です。
  3. 両方 (クライアントとサーバー) が異なるサーバーで動作します。
  4. EJB を使用するには、クライアントに EJB インターフェースとエンティティーが必要です (エンティティーは、EJB によって返されるオブジェクトを逆シリアル化するために必要です)。
  5. サーバー側エンティティには JPA アノテーションがあります。
  6. クライアント側のエンティティはサーバーと同じである必要がありますが、JPA アノテーションは必要ありません。
  7. 保守が容易なため、両方の (クライアントとサーバー) エンティティは同じ jar ライブラリにある必要があります。

これらは問題を解決するための私の提案です:

  1. クライアントとサーバーが必要な方法で実装できるように、エンティティ インターフェイスのみを含むライブラリを作成します。
  2. JPA アノテーションのないエンティティ実装を含むライブラリを作成します (サーバーはアノテーションの代わりに xml を使用する必要があります)。

最善の解決策は何ですか?私の解決策は正しいですか?何か提案があればよろしくお願いします。

4

1 に答える 1

2

クライアントを信頼する場合、または JPA アノテーションがクライアントに漏れても構わない場合は、JPA エンティティをデータ転送オブジェクト (DTO) として使用できます。警告: サーバーによってフェッチされない遅延管理されたリレーションシップは、クライアントで使用できず、シリアル化中に例外が発生したり、クエリやシリアル化が多すぎる可能性があります。(これはあなたのオプション 1)

または、エンティティごとに DTO を作成することもできます。エンティティごとに多数の DTO が存在する場合があります (たとえば、フォーラム投稿のすべてのフィールドを含む完全な DTO、タイトル、日付、作成者のみを含む要約 DTO)。Commons BeanUtilsのようなユーティリティを使用して、多くのボイラープレート コードを記述せずにエンティティから DTO に反射的にコピーできます ( dto.setTitle(entity.getTitle()); dto.setDate(entity.getDate()); ...)。この場合、DTO はクライアントとサーバーによって共有される別の JAR に存在しますが、エンティティは独自の展開単位に存在し、サーバーに対してプライベートです。これは、EJB 1/2 の昔は最も推奨されていた方法でした。(これはオプション 2 といくつかの類似点がありますが、エンティティ自体の代わりに DTO を再利用します)

次に、サーバーを WEB サービスまたは REST エンドポイントとして公開できます (JAX-WS および JAX-RS を使用すると、これが非常に簡単になります)。適切な構成により、クライアントで JPA Bean を再利用することさえ可能になる場合があります。これには、他のテクノロジーと相互運用できるという追加のボーナスがありますが、おそらく遅くなります。

オプション2も実行可能ですが、XMLデプロイメント記述子を維持するオーバーヘッドが追加されます(この場合、JPAをサポートしている場合、XDocletが役立つ場合があります-何年も使用していません)。

どのような種類のリモート処理を使用する場合でも、通信には一般的にコストがかかることに注意してください。したがって、リモート呼び出しは可能な限り粗粒度で、データ交換は可能な限り少なくする必要があります (したがって、上記の要約 DTO です)。

于 2013-09-11T14:44:10.407 に答える