2

次のデータベース構造のマッピングに問題があります (簡潔にするために、PK/FK といくつかの余分な列だけで短縮されています:

ポリシー

Policy_Id (PK) ...

危険

Risk_Id (PK) ...

パーティ

Party_Id (PK) ...

パーティーの役割

  • PartyRole_Id (PK)
  • Party_Id (FK not-null)
  • Policy_Id (外部キー)
  • Risk_Id (外部キー)
  • Party_Role_Type

したがって、PartyRole テーブルには、パーティをポリシーにリンクする行や、同じパーティをリスクにリンクする行を含めることができます。基本的に、これは多対多の結合テーブルですが、多対多の関係 (Party<->Policy と Party<->Risk の 1 つ) の両方を組み合わせています。Party_Role_Type は POLICY または PARTY のいずれかであり、行が属する関係を識別するための識別子として効果的に機能します。

この構造を、ポリシー、パーティ、リスク、パーティロールの 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 pojo はこのマッピングに一致するように設定され、オブジェクトがコレクションで追加または削除されると、すべての関連付けが正しく設定されます。ポリシーは集約ルートと見なされるため、Hibernate によって保存されるときに、ポリシーに関連付けられたパーティを保存したいと考えています。ポリシーとリスク (および関連するすべての役割) に関係者を追加すると、次の例外が発生します。

原因: java.sql.BatchUpdateException: 整合性制約違反: 外部キーに親がありません。FK_PARTY_ROLE_POLICY テーブル: PARTY_ROLE

なにが問題ですか?また、これはこの関係をマッピングする最良の方法ですか? 中間エンティティを使用せずに、この関係を何らかの形でマッピングする機会はありますか? 助けてくれてありがとう。

4

2 に答える 2

1

これに対する答えを書くことに戻る機会は本当にありませんでしたが、問題が何であるかを見つけました。問題はここのこれらの行にありました:

<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>
于 2010-12-07T11:32:23.553 に答える
0

これはRDBMSによって生成されたエラーであるように思われます。したがって、SQLロギング(hibernate.show_sql = true)を有効にして、Hibernateが何をしようとしているのかを確認してください。ただし、FKはnull以外の制約で作成されているように見えるため、PARTY_ROLEのテーブル構造を再確認します。デフォルトでnull以外のFKを作成するデータベース(Sybase、IIRC)がいくつかあります。また、関係をNULLとして指定すると、IDがNULLのPOLICYを見つけようとする場合がありますが、これは確かに存在しません:-)

于 2010-12-03T13:18:53.017 に答える