Вопрос

У меня проблемы с сопоставлением следующей структуры базы данных (сокращен для краткости только с PKS/FK и несколькими дополнительными столбцами:

Политика

Police_id (pk) ...

Риск

Risk_id (PK) ...

Вечеринка

Party_id (pk) ...

Партироль

  • Partyrole_id (pk)
  • Party_id (fk не null)
  • Police_id (fk)
  • Risk_id (fk)
  • Party_role_type

Таким образом, таблица Partyrole может содержать строку, которая связывает сторону с политикой и/или строкой, которая связывает одну и ту же сторону с риском. По сути, многие для многих присоединяются к таблице, но он сочетает в себе многие со многими отношениями: Party <--> политика и один для партии <--> риска. 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 настроены, чтобы соответствовать этому отображению, и все ассоциации настроены правильно, когда объекты добавляются или удаляются в коллекциях. Политика считается совокупным корнем, поэтому, когда она сохраняется с Hibernate, я хочу сохранить стороны, связанные с политикой. Когда я добавляю сторону в политику и риск (и все связанные роли), я получаю следующее исключение:

Вызвано: java.sql.batchupdateexception: нарушение ограничения целостности: внешний ключ без родителей; FK_PARTY_ROLE_POLICY TABLE: 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>

Я тупо упустил, что «столбец», указанный в элементах мешков, указывает на Police_id и Risk_id, что неверно. Это должно быть название внешний ключ столбец, который ссылается на основной ключ из сущности, где определены сумки с одним к многим. Таким образом, в моем случае это должно было быть party_id, и чтобы различать политические роли и партийные роли, мне пришлось использовать ограничение «где» на сумке. Так что определения в итоге выглядели так:

<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. Но я бы дважды проверил структуру таблицы для Party_Role, так как кажется, что FK были созданы с не-нулевыми ограничениями. Есть некоторые базы данных (Sybase, IIRC), которые по умолчанию создают FK с не-нулевыми. И, если вы указываете отношения как NULL, это может попытаться найти политику с ID NULL, который, безусловно, не будет существовать :-)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top