У меня возникли проблемы с отображением следующей структуры базы данных (сокращенной для краткости только с PK/FK и несколькими дополнительными столбцами:
Политика
Идентификатор_политики (ПК) ...
Риск
Risk_Id (ПК) ...
Вечеринка
Party_Id (ПК) ...
PartyRole
- PartyRole_Id (ПК)
- Party_Id (FK не нулевой)
- Идентификатор политики (FK)
- Risk_Id (ФК)
- Party_Role_Type
Таким образом, таблица PartyRole может содержать строку, связывающую сторону с политикой, и/или строку, связывающую ту же сторону с риском. По сути, это таблица соединения «многие ко многим», но она сочетает в себе отношения «многие ко многим»: Party‹->Policy и один для Party‹->Risk. Party_Role_Type может быть либо POLICY, либо PARTY и эффективно действует как дискриминатор, чтобы определить, к какой связи принадлежит строка.
Я попытался смоделировать эту структуру с помощью 4 объектов: Policy, Party, Risk, PartyRole. Вот сопоставления: Код:
<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
Что не так? Кроме того, это лучший способ отобразить эти отношения? Есть ли возможность каким-то образом сопоставить эту связь без использования промежуточного объекта? Спасибо за все, что вы помогаете.