2010-01-19 15 views
17

Eventuali duplicati:
Hibernate unidirectional one to many association - why is a join table better?Perché è consigliabile evitare l'associazione unidirezionale uno a molti su una chiave esterna?

nella documentazione in linea di Hibernate, ai sensi della sezione 7.2.3 Uno-a-molti, è detto, che:

uno unidirezionale -a-many association su una chiave esterna è un caso insolito, e non è raccomandato. Devi usare invece di usare una tabella di join per questo tipo di associazione .

Mi piacerebbe sapere perché? L'unica cosa che mi viene in mente è che può creare problemi durante le eliminazioni a cascata. Ad esempio, la persona si riferisce all'indirizzo su una relazione uno a molti su una chiave esterna e l'indirizzo si rifiuta di essere eliminato prima della persona.

Qualcuno può spiegare il razionale dietro la raccomandazione?

Ecco il link per il contenuto del documento di riferimento: 7.2.3. One-to-many

ho copia incollato il contenuto effettivo qui:

Un unidirezionale associazione uno-a-molti su una chiave esterna è un insolito caso, e non è raccomandato.

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

si dovrebbe invece usare una tabella di unirsi per questo tipo di associazione.

+0

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

risposta

14

unidirezionale associazione uno-a-molti su una chiave esterna è un caso insolito, e non è consigliabile.

Ci sono due aspetti:

  • unidirezionale
  • uno-a-molti

Il thread@CalmStorm 's collegamenti risposta cancellati a indirizzi solo il secondo di queste cose, ma iniziamo con questo.

Quella discussione consiglia di sostituire le relazioni uno-a-molti con le tabelle di join perché altrimenti l'approccio "uno-a-molti" popola il lato tabella molti con colonne che non appartengono a tale entità, ci sono solo per "collegamento" porpuses (sic) '. Questa tattica può portare a un modello pulito nel livello di Hibernate, ma sfortunatamente risulta in un database danneggiato.

Poiché SQL può solo affermare che il record figlio ha un genitore; non c'è modo di applicare una regola che il genitore deve avere un figlio. Di conseguenza, non c'è modo di insistere sul fatto che una tabella abbia delle voci in una tabella di join, essendo il risultato che è possibile avere record figli orfani, proprio quello che le chiavi esterne devono prevenire.

Ho diverse altre obiezioni, ma la successiva più importante è l'inadeguatezza. Le tabelle di intersezione sono pensate per rappresentare relazioni molti-a-molti. Usarli per rappresentare le relazioni uno-a-molti è fonte di confusione e richiede troppi oggetti di database aggiuntivi a mio piacimento.

Quindi, per il secondo aspetto: unidirezionale associazioni uno-a-molti. Il problema con questi è il modo particolare in cui Hibernate li gestisce di default. Se inseriamo un genitore e un figlio nella stessa transazione, Hibernate inserisce il record figlio, quindi inserisce il genitore, quindi aggiorna il bambino con la chiave del genitore. Ciò richiede vincoli di chiave estranei deferrabili (yuck!) E probabilmente anche vincoli non differenziali non nulli (doppio svantaggio).

Ci sono un paio di soluzioni alternative a questo. Uno è quello di utilizzare le associazioni birionali da uno a molti. Secondo in the document you cite questo è l'approccio più comune. L'altro approccio consiste nel modificare la mappatura dell'oggetto figlio ma che ha le sue ramificazioni.

+0

Grazie, che chiarisce molto! – Shaw

+7

Non sono sicuro che tu stia raccomandando one-to-many unidirezionale o no –

+1

Sono d'accordo con @Pangea. APC ha alcuni punti positivi, alcuni dei quali sono d'accordo, ma non è chiaro che cosa pensi sia una buona soluzione per APC. –

Problemi correlati