2012-02-23 2 views
1

JPA2.0を使用して、hibernateを使用してエンティティモデルを設計しようとしています。JPAエンティティモデルの提案

私はこのようなドメインを持っています:たくさんのレストランがありますので、明らかにレストランの実体があります。各レストランにはさまざまな種類の料理が用意されており、0対多数のレストランでも同じことができます。各料理にはいくつかの食材があり、いくつかの料理は食材を共有します。各成分にはいくつかの栄養素があり、それぞれの栄養素は成分の0から多くのものによって所有されているかもしれません。

Imは私の問題が何であるかを正確には確信していないので、苦労していますが、私は何かが欠けていることを知っています。私はドメインモデルをどのように正確に実行するか、主キーと.equals/.hashcodeメソッドにどのような影響があるかという疑問があると考えています。

元私は、生成された代理キーを使用する予定でした。各エンティティは

@Id 
@GeneratedValue 
public Long id; 

のようなものを持っているでしょうそして.equalsは、IDを除くすべてのエンティティのメンバーの平等をテストします。たとえば、レストランはLong IDの値にかかわらず同じですが、Listメンバーの等価性になります。 (もちろん食べ物は栄養素にhirarchyのすべてのteh方法を呼び出すことを続けるだろう)

私はDAO beanにレストランを与えるとき、私はデータストアに同等のレストランはない.equalsを介して)。しかし、私はそれがエレガントで効率的でない(私が間違っているかどうか私に知らせてください、私はしばしば間違っている...笑)見つけることはありません、面倒なjpql呼び出しを含むだろうと思います。さらに進んだところで、既にデータストアに入っていた(しかし、新たに保存されていなかった料理の一部である)食材を遭遇した場合、全く新しいものを作り出すのではなく、論理的に複写する)。

私はそれについてもっと考えていたほど、この階層の中で物事をより高く維持するのはより痛いものでした。

私は、それ自身が子メンバーを保持する複合Key(@IdClassまたは@EmbeddedId経由)の考え方を調べ始めました。これは、階層構造の上位にあるものを永続させるようなものは、idで検索するだけでなく、何かを見つけられなくても持続するように思えます。しかし、私はこれについて非常に疑わしいです...それは正しいように見えません。それは、すべてのメンバーとエンティティ自身と複合キーの一部であるエンティティを作成していることを意味します。

注意すべき事項比較的限られた量の栄養素があります。食材のためのスペースは{numOfNutrients}^{typesOfNutrients}であり、これはかなり大きい可能性があります。私たちがレストランに着く頃には、スペースが本当に大きくなるため、クライアントがアクセスして複製レストランを構築することはほとんど不可能になります。データ・ストアに複製があるかどうかは気にしませんが、それは起こりそうもないためです。実際には、これが起こったかどうかを知ることはほぼ面白いでしょう。また、レストランの例が考案されているわけでもありません。私の本物のドメインは形は似ています。

お散歩に申し訳ありません。私はポストに多くのアイデアがあることを知っています。しかし、私は彼らがすべてとても関連していると感じ、私はそれらを一気に上げたかった。

誰かが魔法使いを提供できますか?

私はこのポストを知っています:A class that behaves like @Entity and @Embeddable 通常、私は "特別な場合を除いて"これをしないでください。私はこれらの事件の1つについて話していますか?そうでない場合は、これを使用するのに適切なケースは何でしょうか。

レストランがデータベースに入れられると、その表現は変更できません。私はこれが実際の例では非現実的であることを認識していますが、私のドメインの場合はそうです。これは私が複合キーのすべてのメンバーを作ることが行く方法だと思います。

+0

私は '等しい'部分を理解しませんでした。レストランR1とR2は、両方ともサーバーDishes(D1、D2、D3)と言います。それで、彼らは平等で許可されていませんか? – Kent

+0

レストランR1とR2は同じ料理のリストを保持していれば同じです。すべての料理で.equalsをチェックして決定します。それはある意味で再帰的です。 R1:(D1、D2、D3)== R2 :(D1、D2、D3)、ただしR1(D1、D2、D3)!= R3:(D1、D6)だから、0-多くのレストランで料理を提供することができます。 – b3bop

答えて

1

Hibernateはエンティティがすでに永続的かどうかを知るためにequalsとhashCodeを使用しません。エンティティにIDがある場合、それは永続的です。それ以外は新しいものです。また、同じIDを持つ2つのエンティティは同じです。 equalsメソッドは、2つの分離されたエンティティを比較するか、またはデタッチされたエンティティを添付されたエンティティと比較するためにのみ使用されます。コードです(Hibernateコードには含まれません)。

エンティティがセットに格納されている場合は、equalsおよびhashCodeも必要です。

本当にequalsメソッドとhashCodeメソッドが必要な場合は、子エンティティのコレクションを使用してそれを実装することは非常に悪い考えです。データベースを呼び出すにはデータベースの半分を読み込む必要があるだけでなく、料理に食材を追加するとすぐにそのhashCodeが変更され、格納されているセットが「破損」します。

equalsおよびhashCode(レストランの名前、料理名、栄養素の名前)を実装するには、エンティティのnull不可能で不変な一意の機能フィールドを使用する必要があります。そして、間違いなく代理識別子を使用してください。このようなフィールドがない場合は、そのIDを使用できます。しかし、Setにエンティティを格納する前に生成されていることを確認してください。

+0

ahhデータベースの半分をロードすることについて何を意味するのか分かります...クライアント(レストラン、栄養素に至るまでのすべてのメンバー)でレストランの階層を持っていれば、新しいクエリを作成するためにクエリを実行する必要があります食べ物、食材、栄養素、または既存のものと交換することができます。それが私のコードです。それは私が休止状態にすることができない何か? – b3bop

+0

正確です。それはすべてUIに依存します。あなたが料理の成分を選択するために選択ボックスを使用する場合、それらが既に存在し、あなたのIDを知っている。ユーザーが原料名を入力できるようにする場合は、この成分をデータベースの名前で検索し、存在する場合はそれを使用するか、存在しない場合は新しいものを作成する必要があります。 –

+0

すごく感謝します。 – b3bop