2010-03-16 11 views
36

Ho visto persone utilizzare mapping molti-a-uno per rappresentare relazioni uno-a-uno. Ho letto anche questo in un libro di Gavin King e sugli articoli.Hibernate - perché utilizzare molti a uno per rappresentare uno a uno?

Ad esempio, se un cliente può avere esattamente un indirizzo di spedizione, e un indirizzo di spedizione può appartenere a un solo cliente, la mappatura è dato come:

<class name="Customer" table="CUSTOMERS"> 
    ... 
    <many-to-one name="shippingAddress" 
       class="Address" 
       column="SHIPPING_ADDRESS_ID" 
       cascade="save-update" 
       unique="true"/> 
    ... 
</class> 

Le ragioni libro come (citando esso):

"non importa ciò che è sul lato di destinazione dell'associazione, in modo da poter trattare come un associazione a-uno, senza tanti parte ."

La mia domanda è, perché utilizzare many-to-one e non one-to-one? Che cos'è un one-to-one che lo rende un'opzione meno desiderabile per many-to-one?

Grazie.

risposta

28

Esistono diversi modi per implementare un'associazione one-to-one in un database: è possibile condividere una chiave primaria ma è anche possibile utilizzare una relazione di chiave esterna con un vincolo univoco (una tabella ha una colonna di chiave esterna che fa riferimento a la chiave primaria della tabella associata).

Nel caso successivo, il modo di mappatura in modalità ibernazione è l'utilizzo di un'associazione many-to-one (che consente di specificare la chiave esterna).

La ragione è semplice: Non si cura cosa c'è sul lato di destinazione del associazione, in modo da poter trattare come un a-uno un'associazione senza molti parte. Tutto ciò che si desidera è esprimere "Questa entità ha una proprietà che è un riferimento a un'istanza di un'altra entità " e utilizzare un campo chiave esterna a rappresentare tale relazione.

In altre parole, utilizzando un many-to-one è il modo per mappare uno-a-uno associazioni di chiave esterna (che in realtà sono forse più frequenti rispetto Shared Key associazioni primaria one-to-one).

+1

Puoi fornire un esempio per chiarire il tuo punto sulla mappatura della "relazione di chiave esterna con un vincolo univoco"?Dal momento che tale relazione è logicamente uno-a-uno, perché dovresti mapparla come molti-a-uno in letargo? – KyleM

+5

Questo sembra rispondere _quando_ ma non _perchè _...? –

+0

Lo svantaggio però è che non è possibile usare 'inverse =" true "'. Non funziona su 'many-to-one'. – pavanlimo

3

Direi che il problema è fondamentalmente correlato alla mancata corrispondenza di impedenza relazionale dell'oggetto. Per poter correlare le due rappresentazioni di oggetti in un database, è necessario avere una sorta di relazione tra le loro tabelle. Tuttavia, il database conosce solo la relazione 1: N: tutti gli altri ne derivano.

Con database relazionali e linguaggi di oggetti, è compito dello sviluppatore trovare la rappresentazione meno innaturale del concetto che lui/lei vuole rappresentare (in questo caso, una relazione 1: 1).

0

Come ho capito, l'ibernazione richiede che la chiave primaria di entrambi gli oggetti corrisponda a una relazione 1 a 1. Molti a 1 evitano questo requisito.

Tuttavia, molti a 1 perdono l'informazione che ci dovrebbe essere solo uno o forse nessun oggetto su molti lati.

3

La più grande differenza è, con una chiave condivisa mapping one-to-one i 2 oggetti sono legati l'uno all'altro, esistono insieme.

f.e. se si crea un persona e un Indirizzo classe che sono legati a tabelle con lo stesso nome, ogni persona avrà esattamente un indirizzo ...

classe Persona, proprietà: indirizzo tavolo persona, colonne: id, nome tavolo Indirizzo, colonne: id, città

Con molti a uno relazione la struttura della tabella cambia un po ', ma lo stesso effetto può essere raggiunto ...

  • classe Persona -> Proprietà: indirizzo
  • tabella Person -> colonne: id, nome, AddressID (fk)
  • tabella degli indirizzi -> colonne: id, città

... ma anche Di Più. Ora, questa persona può avere più indirizzi: Person

  • classe -> Proprietà: indirizzo
  • tabella Person -> colonne: id, nome, AddressID (FK), shippingaddressid (FK)
  • tavolo Indirizzo - > colonne: id, città

Le due chiavi esterne (AddressID e shippingaddressid) potrebbero puntare a una singola voce DB ... o un singolo indirizzo potrebbero appartenere a 2-3 persone. così che cosa è un molti a uno dal lato della persona è uno a uno dal lato indirizzo.

e solo indovina cosa assomiglia a un'associazione uno-a-molti con solo 1 elemento? Sì, proprio come un one-to-one ...

NOTA: l'indirizzo in realtà dovrebbe essere un valore oggetto, non deve essere condiviso in DB (quindi è un esempio stupido, ma credo che sarà ok)

Così, in breve:

  1. in OR mapping uno-a-uno è più difficile da gestire
  2. 12:59 ha i suoi limiti
  3. utilizzando molti a uno invece è mo flessibile e la stessa cosa può essere raggiunta con
Problemi correlati