web-dev-qa-db-ja.com

ORMはリッチドメインモデルの作成を可能にしますか?

私のプロジェクトのほとんどで約8年間Hibernateを使用した後、その使用を思いとどまらせ、アプリケーションがストアード・プロシージャーを介してのみDBと対話することを望んでいる会社を見つけました。

これを数週間行った後、構築を開始するアプリケーションのリッチドメインモデルを作成できず、アプリケーションは(恐ろしい)トランザクションスクリプトのように見えます。

私が見つけた問題のいくつかは次のとおりです。

  • ストアドプロシージャは最小量のデータをロードするだけなので、オブジェクトグラフをナビゲートできません。つまり、異なるフィールドを持つ同様のオブジェクトがある場合があります。たとえば、顧客からすべてのデータを取得するためのストアドプロシージャと、顧客からアカウント情報といくつかのフィールドを取得するためのストアドプロシージャがあります。
  • ロジックの多くはヘルパークラスで終わるため、コードはより構造化されます(エンティティは古いC構造体として使用されます)。
  • ストアドプロシージャから結果セットを抽出してエンティティに配置するフレームワークがないため、より退屈な足場コード。

私の質問は:

  • 誰かが同様の状況にあり、ストアプロシージャアプローチに同意しませんでしたか?あなたは何をした?
  • ストアドプロシージャを使用することの実際の利点はありますか? 「誰もドロップテーブルを発行できない」というばかげた点は別として。
  • ストアドプロシージャを使用してリッチドメインを作成する方法はありますか? AOPを使用してDAO /リポジトリをエンティティに挿入し、オブジェクトグラフをナビゲートできる可能性があることを知っています。ブードゥー教に非常に近いため、このオプションは好きではありません。

結論

まず、皆様のご回答ありがとうございます。私が到達した結論は、ORMはリッチドメインモデルの作成を可能にしない(一部の人々が述べたように)が、それは(しばしば反復的な)作業の量を単純化します。以下は結論のより詳細な説明ですが、いかなるハードデータにも基づいていません。

ほとんどのアプリケーションは、情報を要求して他のシステムに送信します。これを行うには、モデル用語(ビジネスイベントなど)で抽象化を作成し、ドメインモデルがイベントを送信または受信します。イベントには通常、モデルからの情報の小さなサブセットが必要ですが、モデル全体は必要ありません。たとえば、オンラインショップの場合、支払いゲートウェイは、ユーザーに請求するために一部のユーザー情報と合計を要求しますが、購入履歴、利用可能な製品、およびすべての顧客ベースを必要としません。したがって、イベントには小規模で特定のデータセットがあります。

アプリケーションのデータベースを外部システムとして使用する場合は、ドメインモデルエンティティをデータベースにマップできるようにする抽象化を作成する必要があります(データマッパーを使用して、 NimChimpskyが言及したように )。 。明白な違いは、2つが同期していないため、1つのドメインエンティティが部分的にマッピングされる可能性があるという余分な苦痛を伴いながら、各モデルエンティティのデータベース(レガシースキーマまたはストアドプロシージャ)へのマッピングを手作りする必要があるということです。データベースエンティティ(たとえば、ユーザー名とパスワードのみを含むUserCredentialsクラスは、他の列を持つUsersテーブルにマップされます)、または1つのドメインモデルエンティティが複数のデータベースエンティティにマップされる場合があります(たとえば、1対1テーブルのマッピングは1つですが、すべてのデータを1つのクラスに収めたいと考えています)。

エンティティが少ないアプリケーションでは、エンティティを横断する必要がない場合、追加の作業量は少なくなる可能性がありますが、エンティティを横断する必要がある場合は増加します(したがって、ある種の「レイジー」を実装する場合があります。ローディング ')。アプリケーションがより多くのエンティティを持つように成長するにつれて、この作業は増加するだけです(そして、非線形に増加するように感じます)。ここでの私の仮定は、ORMを再発明しようとするものではないということです。

DBを外部システムとして扱うことの1つの利点は、アプリケーションの2つの異なるバージョンを実行したい状況をコーディングできることです。この場合、各アプリケーションは異なるマッピングを持ちます。これは、本番環境への継続的デリバリーのシナリオでより興味深くなります...しかし、これはORMを使用した場合でも可能ではないと思います。

開発者は、データベースにアクセスできない場合でも、悪意のあるコードを挿入するだけで、システムに格納されているすべての情報ではないにせよほとんどの情報を取得できることに基づいて、セキュリティの側面を無視します(たとえば、 お客様のクレジットカードの詳細を記録する行を削除するのを忘れたなんて信じられません。).


小さな更新(2012年6月6日)

ストアドプロシージャ(少なくともOracleでは)は、テーブルの構造に変更を加えるとプロシージャとトリガーが無効になるため、ダウンタイムがゼロの継続的デリバリーなどの処理を防止します。したがって、DBが更新されている間、アプリケーションも停止します。オラクルはこれに対してソリューションを提供します Edition-Based Redefinition ですが、この機能について私が尋ねたいくつかのDBAは、実装が不十分であり、運用DBには入れません。

21
Augusto

アプリケーションは、ドメイン主導の設計原則に基づいてモデル化する必要があります。 ORM、ストレートJDBC、SP(またはその他)を呼び出すかどうかは問題ではありません。うまくいけば、この場合、SPからモデルを抽象化する薄いレイヤーでうまくいくはずです。 別の投稿者が述べた のように、SPとその結果をサービスとして表示し、結果をドメインモデルにマッピングする必要があります。

16
Martijn Verburg

ストアドプロシージャを使用することの実際の利点はありますか?

金融の世界(および Sarbanes-Oxley コンプライアンスが必要な場所)では、システムを監査して、システムが想定されていることを確実に実行できるようにする必要があります。このような場合、すべてのデータアクセスがストアドプロシージャを介して行われると、コンプライアンスを確保するのがはるかに簡単になります。そして、すべてのアドホックSQLが削除されると、物事を隠すことははるかに難しくなります。これが「良いこと」である理由の例として、ケントンプソンの古典的な論文Reflection on Trusting Trustを参照します。

5
Tangurena

ストアドプロシージャは、クライアント側のSQLコードよりもはるかに効率的です。彼らはDBでSQLをプリコンパイルし、最適化を実行できるようにします。

アーキテクチャ的には、SPは、タスクに必要な最小限のデータを返します。これは、転送されるデータが少ないことを意味するので、良いことです。このようなアーキテクチャがある場合は、サービスとしてのDB(それをWebサービスとして考え、各SPは呼び出すメソッドです)。このように操作することは問題になりませんが、ORMがあなたをガイドしますローカルであるかのようにリモートデータを操作するため、注意しないとパフォーマンスの問題が発生します。

私はSPを完全に使用し、DBがデータAPIを提供し、それを使用する状況にありました。その特定のアプリは非常に大規模で、驚くほど優れたパフォーマンスを発揮しました。その後のSPについて悪いことは言わないでしょう!

もう1つの利点があります。DBAはすべてのSQLクエリを作成し、DB内のすべてのリレーショナル階層を適切に処理するため、その必要はありません。

2
gbjbaanb

よくあることは、開発者がドメインモデルとしてORMオブジェクトを誤って使用していることです。

これは誤りであり、ドメインをDBスキーマに直接結び付けます。

実際に必要なのは、好きなだけリッチな独立したドメインモデルであり、ORMレイヤーを個別に使用することです。

つまり、オブジェクトの各セット間のマッピングが必要になります。

2
ozz

ドメインオブジェクトは自由に設定できますが、Hibernateを使用する必要はありません。適切な用語は data-mapper だと思います。永続化されたデータがドメインオブジェクトとは完全に異なる構造になる可能性が非常に高くなります。

1
NimChimpsky