relaciones relacion one obtener muchos mapeo many listar ejemplos datos con java sql hibernate rdbms

java - relacion - ¿Por qué se recomienda evitar la asociación unidireccional de uno a muchos en una clave externa?



relacion one to one (1)

Posible duplicado:
Hibernación de una a una asociación unidireccional: ¿por qué es mejor una tabla de unión?

En la documentación en línea de Hibernate, en la sección 7.2.3 uno a muchos, se menciona que:

La asociación unidireccional de uno a muchos en una clave externa es un caso inusual y no se recomienda. En su lugar, debe utilizar una tabla de unión para este tipo de asociación.

¿Me gustaría saber por qué? Lo único que me viene a la mente es que puede crear problemas durante las eliminaciones en cascada. Por ejemplo, Persona se refiere a la dirección en una relación de uno a muchos en una clave externa, y la dirección se negaría a ser eliminada antes que la persona.

¿Alguien puede explicar lo racional detrás de la recomendación?

Aquí está el enlace al contenido del documento de referencia: 7.2.3. Uno a muchos

He copiado el contenido actual pegado aquí:

Una asociación unidireccional de uno a muchos en una clave externa es un caso inusual y no se recomienda.

<class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <set name="addresses"> <key column="personId" not-null="true"/> <one-to-many class="Address"/> </set> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id> </class>

create table Person (personId bigint not null primary key) create table Address (addressId bigint not null primary key, personId bigint not null)

En su lugar, debe utilizar una tabla de unión para este tipo de asociación.


La asociación unidireccional de uno a muchos en una clave externa es un caso inusual y no se recomienda.

Hay dos aspectos a esto:

  • unidireccional
  • uno a muchos

El thread de la respuesta eliminada de @CalmStorm enlaza solo con la segunda de estas cosas, pero comencemos con eso.

Ese hilo recomienda reemplazar las relaciones de uno a muchos con tablas de unión porque de lo contrario, el enfoque de uno a muchos llena la tabla lateral con muchas columnas que no pertenecen a esa entidad, solo están disponibles para "vincular" los portales (sic) ''. Esta táctica puede dar como resultado un modelo limpio en la capa de Hibernate, pero desafortunadamente da como resultado una base de datos dañada.

Porque SQL solo puede afirmar que el registro hijo tiene un padre; no hay manera de hacer cumplir una regla que el padre debe tener un hijo. Por consiguiente, no hay forma de insistir en que una tabla tenga entradas en una tabla de unión, ya que el resultado es que es posible tener registros secundarios huérfanos, lo mismo que las claves externas deben evitar.

Tengo varias otras objeciones, pero la siguiente más importante es inapropiada. Las tablas de intersección están destinadas a representar relaciones de muchos a muchos. Usarlos para representar relaciones de uno a muchos es confuso y requiere demasiados objetos de base de datos adicionales para mi gusto.

Entonces, al segundo aspecto: asociaciones unidireccionales de uno a muchos. El problema con estos es la forma peculiar en que Hibernate los maneja por defecto. Si insertamos un padre y un hijo en la misma transacción, Hibernate inserta el registro del niño, luego inserta el padre y luego actualiza al niño con la clave del padre. Esto requiere restricciones de clave externa diferibles (¡puaj!) Y probablemente también restricciones no nulas diferibles (yuck doble).

Hay un par de soluciones para esto. Una de ellas es utilizar asociaciones de uno a varios bireccionales. Según el documento que cites, este es el enfoque más común. El otro enfoque es ajustar la asignación del objeto hijo, pero eso tiene sus propias ramificaciones.