質問

たとえば、エンタープライズ アプリケーションに Java EE スタックを使用することに決めたとします。

さて、ドメイン モデリング (または:MVC の M を設計するため)、どの API を安全に想定して使用できるか、どの API を避けるべきか...たとえば、抽象化の層を介して?

例えば、

  1. モデルに Hibernate/JPA API の呼び出しを散りばめたほうがよいでしょうか?それとも抽象化を構築すべきでしょうか...これら 2 つの特定の永続性 API に対するハードコーディングを避けるための独自の永続性レイヤーはありますか? 私がこれを尋ねる理由: 数年前、Hibernate に取って代わられた Kodo API がありました。(特定のベンダー API への呼び出しをモデルに散りばめる代わりに) 永続化レイヤーを設計し、このレイヤーに対してモデルの残りの部分をコーディングしていれば、Kodo から Hibernate、xyz へ (比較的) 簡単に切り替えることができたでしょう。

  2. ドメイン モデルで永続化ベンダーが提供する *QL を積極的に使用することをお勧めしますか?HQL に似た言語を頻繁に使用することで生じる現実の問題 (パフォーマンス、スケーラビリティ、移植性など) を私は知りません。 私がこれを尋ねる理由: SQL よりも移植性の高いクエリ言語を使用してカスタム コードを実行できる場合でも、カスタム コードの作成はできるだけ避けたいと考えています。

申し訳ありませんが、私はこの分野に関してはまったくの初心者です。このトピックに関する詳細情報はどこで入手できますか?

役に立ちましたか?

解決

私が信じている伝統的な見解は次のとおりです。

  • プロジェクト内のエンティティはドメイン モデルを形成します。これらは再利用可能である必要があり、永続化テクノロジと密接に結合されていない必要があります (タイトと永続化テクノロジについては後で説明します)。疎結合)
  • ビジネス層はドメイン モデルを使用しますが、サービスやその他のものも公開します。
  • データ アクセス層は、ドメイン モデル (エンティティ) を永続ストアに永続化する役割を果たします。

エンティティはデータ アクセス層を直接呼び出すべきではありません。ただし、ビジネス層は、ある意味でドメイン モデルのエンティティを読み込み、永続化します。

これを Java EE テクノロジーにマッピングすると、通常は次のようになります。

  • エンティティ --> Hibernate/JPA アノテーションを含む POJO。アノテーションは JPA/Hibernate との緊密な結合を意味するものではなく、まったく同じ POJO を Hibernate なしで他の場所で使用できることに注意してください。
  • ビジネス層 --> セッション EJB または Spring
  • データアクセス層 --> JPA/Hibernate

これは大まかなスケッチであり、さまざまなバリエーションが考えられます。特に、セッション EJB をスキップして、別の方法でビジネス層を実装できます。ビジネス層が JPA/Hibernate Session/EntityManager を直接呼び出すようにすることもできます。この場合、JPA/Hibernate は実際には DAL になります。あるいは、Session/EntityManager へのアクセスをいわゆるデータ アクセス オブジェクト (DAO) にラップすることもできます。 )。

HQL に関しては、移植可能なものにこだわるようにし、ネイティブ SQL を使用する場合は SQL-92 の規則に従ってください。物事が複雑になったら、DAO を導入するかもしれません。こうすることで、HQL クエリが存在する唯一の場所が DAO 内であることがわかります。最初に DAO にクエリ ロジックを「手続き的に」実装し、パフォーマンスに問題がある場合は、より複雑な HQL クエリを使用して再実装することもできます。

編集

コメントでのご質問について:

ビジネス層はデータ層に依存します。ビジネス層を Hibernate/JPA に依存させたくない場合は、データ層を次のようにする必要があります。 抽象的な ハイバネート/JPA を終了します。データ層に DAO を使用している場合は、これが当てはまります。DAO は、(あなたの言葉を借りれば) 「Hibernate 上の薄い手書きの永続化レイヤー」になります。あなたの場合、すべてのエンティティに DAO を導入します。

あなたが求めているのは、非常に一般的な設計に関する質問です。それについてはケースバイケースであるため、決定的なレシピを与えることはできませんし、すべてのバリエーションを 1 つの答えに要約することもできません。たとえば、トランザクションの問題についてはこれまで話しませんでしたが、通常はビジネス層で開始されますが、データ層が認識する必要があります。通常、これは使用されるテクノロジーと要件によって異なります。

それでも、興味があるかもしれないリソースのリストは次のとおりです。本 エンタープライズ アプリケーション アーキテクチャのパターン, 、本 現実世界の Java EE パターン - ベスト プラクティスの再考, 、本 ドメイン駆動設計 より具体的にはパターン データアクセスオブジェクト, リポジトリパターン, ビューでセッションを開く (Web アプリの場合)、おそらく 貧血ドメインモデル.

編集2

さて、トランザクションについてもう少し文章を書きます。

トランザクションは概念的にはビジネス層で管理されるべきです。一貫性を保つために 1 つの作業単位で何を行う必要があるかという定義は、アプリケーションのロジックそのものに依存します。

EJB3 では、アノテーションとアプリを使用してトランザクションを宣言できます。サーバーがそれを管理します。見る この他の答え 詳細については私のものです。Springではトランザクションを宣言的にマークすることもできますが、詳細はわかりません。それ以外の場合は、トランザクションを自分で開始/停止する必要があります。これは、JDBC トランザクションを使用するか JTA トランザクションを使用するかによって若干異なります。

トランザクションは、Hibernate/JPA の遅延ロードにも関連します。遅延ロードされたエンティティは、現在のトランザクションが存在する場合にのみ実際にロードできます。トランザクションがビジネス層で終了した場合、プレゼンテーション層に返されるエンティティを積極的にロードする必要があります。

この問題を回避するために、Web アプリケーションの一般的なパターンは次のとおりです。 ビューでセッションを開く, 、すでに述べました。この場合、プレゼンテーション層はトランザクションを開始/停止しますが (これは概念的に少し間違っています)、遅延読み込みでは問題なく動作します。

他のヒント

あなたのドメインモデルとその永続化層は、理論的には別々でなければなりません - あなたは汚染せずに永続化層を作成するために、Hibernateのようなものを使用することができますので、もしについて、どのようにそれが永続化される何かを知っているEntityと呼ばれるクラスの必要は、ありませんドメインモデルクラス自体。そうしない「コード[...]この層に対するモデル」 - あなたは、ドメインモデルは、ORM層に依存しないORM層のいくつかの並べ替え、と永続ストアにマッピングし、モデルをコーディングします。明らかに永続化層は、ドメインモデルに依存するが、罰金のようになります。

私は個人的にあなたが尋ねる理由(N)Hibernateであまりにも多くのHQLを使用しての恥ずかしがり屋戦うが、それは避けられない時間があります。あなたはこのとにかくを酷使しそうにないので、あなたはすでに、そこに、主な問題を知っているし、自分が強調されています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top