Pregunta

Tengo problemas para el mapeo de la siguiente estructura de base de datos (acortado por razones de brevedad con sólo PKs / FKs y algunas columnas adicionales:

Política

POLICY_ID (PK) ...

Riesgo

Risk_Id (PK) ...

Fiesta

Party_Id (PK) ...

PartyRole

  • PartyRole_Id (PK)
  • Party_Id (FK no-null)
  • POLICY_ID (FK)
  • Risk_Id (FK)
  • Party_Role_Type

Así que la mesa PartyRole puede contener una fila que los enlaces de una parte en una política y / o una fila que los enlaces del mismo partido a un riesgo. Básicamente se trata de una de muchos a muchos tabla de unión, sino que combina muchos a muchas relaciones: Fiesta <-> Política y uno para la fiesta <-> Riesgos. Party_Role_Type puede ser o bien de política o PARTIDO y actúa eficazmente como un discriminador para identificar que la relación de la fila pertenece.

He tratado de modelar esta estructura con 4 entidades: Política, Fiesta, Riesgo, PartyRole. Aquí están las asignaciones: Código:

<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>

Todos los POJOs Java están configurados para que coincida con este mapeo y todas las asociaciones están configurados correctamente cuando los objetos añadido o eliminado en las colecciones. La política se considera una raíz agregada, por lo que cuando se guarda por Hibernate Quiero salvar las Partes asociados con la Política. Cuando agrego una Parte a la política y el riesgo (y todas las funciones asociadas) me sale el siguiente excepción:

Causado por: java.sql.BatchUpdateException: la integridad violación de restricción: clave externa ningún padre; FK_PARTY_ROLE_POLICY tabla: PARTY_ROLE

Lo que está mal? También es esta la mejor manera de hacer corresponder esta relación? ¿Existe la posibilidad de mapear esta relación alguna manera sin el uso de la entidad intermedia? Gracias por todo lo que ayuda.

¿Fue útil?

Solución

Yo realmente no tienen la oportunidad de volver a escribir una respuesta a esto, pero he encontrado cuál era el problema. La cuestión estaba en estas líneas aquí:

<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>

Estúpidamente echado de menos que la "columna" se especifica en los elementos de las bolsas está apuntando a POLICY_ID y Risk_Id, lo cual es incorrecto. Debe ser el nombre de la clave externa columna que hace referencia al clave principal de la entidad donde se definen las bolsas de uno a muchos. Así que en mi caso debería haber sido Party_Id y para diferenciar entre las funciones de política y papeles partido, tuve que usar un "donde" constrant en la bolsa. Así las definiciones terminaron con este aspecto:

<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>

Otros consejos

Me suena que esto es un error generado por sus RDBMS. Por lo tanto, tratar de habilitar el registro de SQL (hibernate.show_sql = true) y ver lo que Hibernate está tratando de hacer. Pero me vuelva a verificar la estructura de la tabla de PARTY_ROLE, ya que parece que los FKs fueron creados con restricciones no-nulos. Hay algunas bases de datos (Sybase, IIRC) que crea las claves ajenas con no-nulo por defecto. Y, si se especifica la relación como NULL, puede tratar de encontrar una política con el NULL ID, que desde luego no va a existir :-)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top