2010-01-19 18 views
17

Duplicar posible:
Hibernate unidirectional one to many association - why is a join table better?¿Por qué se recomienda evitar la asociación unidireccional de uno a muchos en una clave externa?

En la documentación en línea de hibernación, en la sección 7.2.3 Uno-a-muchos, se menciona que:

uno unidireccional -to-many association en una clave externa es un caso inusual, y no se recomienda. Debería en su lugar usar una tabla de unión para este tipo de asociación.

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

¿Alguien puede explicar el razonamiento detrás de la recomendación?

Aquí está el enlace al contenido del documento de referencia: 7.2.3. One-to-many

tengo copia pegar el contenido real aquí:

Una asociación unidireccional uno-a-muchos en una clave externa es una inusual caso, y no es recomendado.

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

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

+0

ver http://stackoverflow.com/questions/1307203/hibernate-unidirectional-one-to-many-association-why-is-a-join-table-better –

Respuesta

14

asociación unidireccional uno-a-muchos en una clave foránea es un caso inusual, y no se recomienda.

Hay dos aspectos a esto:

  • unidireccional
  • uno-a-muchos

El thread@CalmStorm 's Enlaces eliminados respuesta a las direcciones en el segundo de estas cosas, pero comencemos con eso.

Ese subproceso recomienda sustituir las relaciones de uno a muchos con tablas de unión porque, de lo contrario, el enfoque de uno a varios 'rellena muchas tablas laterales con columnas que no pertenecen a esa entidad, solo están ahí para' vincular ' poros (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 rota.

Porque SQL solo puede afirmar que el registro secundario tiene un elemento principal; no hay forma de hacer cumplir una regla de que el padre debe tener un hijo. En consecuencia, no hay forma de insistir en que una tabla tenga entradas en una tabla de unión, el resultado es que es posible tener registros secundarios huérfanos, precisamente lo que las claves externas pretenden evitar.

Tengo otras objeciones, pero la siguiente más importante es la inadecuación. 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.

Por lo tanto, para el segundo aspecto: unidireccional asociaciones uno a muchos. El problema con estos es la peculiar manera en que Hibernate los maneja por defecto. Si insertamos un padre y un hijo en la misma transacción, Hibernate inserta el registro secundario, luego inserta el elemento primario y luego lo actualiza con la clave principal. Esto requiere restricciones de claves foráneas diferibles (¡asqueroso!) Y probablemente también restricciones diferibles, no nulas (doble asco).

Hay un par de soluciones para esto. Una es usar asociaciones binarias de uno a muchos. De acuerdo con in the document you cite este es el enfoque más común. El otro enfoque es ajustar el mapeo del objeto hijo, pero eso tiene sus propias ramificaciones.

+0

Gracias, eso aclara mucho! – Shaw

+7

No estoy seguro si está recomendando One-to-Many unidireccional o no –

+1

Estoy de acuerdo con @Pangea. APC hace algunos buenos comentarios, algunos de los cuales estoy de acuerdo, pero no está claro lo que APC piensa que es una buena solución. –

Cuestiones relacionadas