レガシーデータベース構造冬眠マッピングの問題
-
30-09-2019 - |
質問
次のデータベース構造をマッピングするのに問題があります(PKS/FKSといくつかの追加の列だけで、簡潔に短縮されました。
ポリシー
policy_id(pk)...
危険
risk_id(pk)...
パーティ
party_id(pk)...
パーティーロール
- partyrole_id(pk)
- party_id(fk not-null)
- policy_id(fk)
- risk_id(fk)
- party_role_type
したがって、パーティロールテーブルには、パーティーをポリシーにリンクする行および/または同じ当事者をリスクにリンクする行を含めることができます。基本的に、多くの人にとって参加テーブルですが、多くの関係と多くの関係の両方を組み合わせています。パーティー<->ポリシーとパーティー<->リスクのポリシーです。 party_role_typeはポリシーまたはパーティのいずれかであり、行がどの関係に属するかを特定するための判別要因として効果的に機能します。
この構造を、ポリシー、パーティー、リスク、パーティロールの4つのエンティティでモデル化しようとしました。ここにマッピングがあります:コード:
<class name="com.blah.Party" table="Party">
<id column="Party_Id" name="_id" type="int" unsaved-value="-1" access="field">
<generator class="sequence">
<param name="sequence">SQ_Party</param>
</generator>
</id>
<bag name="_policyRoles" access="field" table="Party_Role">
<key column="Policy_Id" />
<one-to-many class="com.blah.PartyRole" />
</bag>
<bag name="_riskRoles" access="field" table="Party_Role">
<key column="Risk_Id" />
<one-to-many class="com.blah.PartyRole" />
</bag>
</class>
<class name="com.blah.Risk" table="Risk">
<id column="Risk_Id" name="_id" type="int" unsaved-value="-1" access="field">
<generator class="sequence">
<param name="sequence">SQ_Risk</param>
</generator>
</id>
<bag name="_partyRoles" access="field">
<key column="Risk_Id" />
<one-to-many class="com.blah.PartyRole" />
</bag>
</class>
<class name="com.blah.Policy" table="Policy">
<id column="Policy_Id" name="_id" type="int" unsaved-value="-1" access="field">
<generator class="sequence">
<param name="sequence">SQ_Policy</param>
</generator>
</id>
<bag name="_partyRoles" inverse="true" cascade="save-update" access="field" table="Party_Role" >
<key column="Policy_Id" />
<one-to-many class="au.com.cgu.harvest.domain.party.PartyRole" />
</bag>
</class>
<class name="au.com.cgu.harvest.domain.party.PartyRole" table="Party_Role" schema="Harvest">
<id column="Party_Role_Id" name="_id" type="int" unsaved-value="-1" access="field">
<generator class="sequence">
<param name="sequence">Harvest.SQ_Party_Role</param>
</generator>
</id>
<property name="partyRoleType" column="PARTY_ROLE_TYPE"
type="java.lang.String" />
<many-to-one name="_party" column="Party_Id" class="com.blah.Party" access="field" cascade="save-update" fetch="join" />
<many-to-one name="_risk" column="Risk_Id" class="com.blah.Risk" access="field" />
<many-to-one name="_policy" column="Policy_Id" class="com.blah.Policy" access="field" />
</class>
すべてのJava Pojosは、このマッピングに一致するようにセットアップされ、すべての関連付けは、コレクションにオブジェクトが追加または削除されたときに正しくセットアップされます。ポリシーは集計ルートと見なされるため、冬眠によって保存された場合、ポリシーに関連する当事者を保存したいと思います。政策とリスク(および関連するすべての役割)に当事者を追加すると、次の例外が得られます。
原因:java.sql.batchupdateException:整合性制約違反:外部キー親なし; fk_party_role_policyテーブル:party_role
なにが問題ですか?また、これはこの関係をマッピングする最良の方法ですか?どういうわけかこの関係をマッピングする機会はありますか? それなし 中間エンティティの使用?あなたが助けてくれてありがとう。
解決
私は本当にこれに対する答えを書くことに戻る機会を得ることができませんでしたが、私は問題が何であるかを見つけました。問題はここでこれらの行にありました:
<bag name="_policyRoles" access="field" table="Party_Role">
<key column="Policy_Id" />
<one-to-many class="com.blah.PartyRole" />
</bag>
<bag name="_riskRoles" access="field" table="Party_Role">
<key column="Risk_Id" />
<one-to-many class="com.blah.PartyRole" />
</bag>
バッグの要素で指定された「列」がPolicy_idとRisk_idを指していることを愚かに逃しましたが、これは間違っています。それはの名前であるべきです 外部キー 参照する列 主キー 1対多くのバッグが定義されているエンティティの。したがって、私の場合、それはparty_idであり、ポリシーの役割とパーティーの役割を区別するために、バッグに「Where」を使用する必要がありました。そのため、定義は次のようになりました。
<bag name="_policyRoles" access="field" table="Party_Role" where="Party_Role_Type = 'POLICY'">
<key column="Party_Id" />
<one-to-many class="com.blah.PartyRole" />
</bag>
<bag name="_riskRoles" access="field" table="Party_Role" where="Party_Role_Type = 'RISK'">
<key column="Party_Id" />
<one-to-many class="com.blah.PartyRole" />
</bag>
他のヒント
これはRDBMSによって生成されたエラーであると思います。したがって、SQLロギング(hibernate.show_sql = true)を有効にして、Hibernateが何をしようとしているかを確認してください。しかし、FKSがヌルの制約で作成されたように見えるため、Party_roleのテーブル構造を再確認します。デフォルトでNot-NullでFKSを作成するデータベース(Sybase、IIRC)があります。そして、関係をnullとして指定した場合、ID nullでポリシーを見つけようとするかもしれませんが、それは確かに存在しません:-)