2013-06-25 7 views
5

Ho provato la relazione many to many tra due classi Person e Address. Non lo so, ma da qualche parte non sto pensando lungo le linee corrette. Ad esempio, per molti a molti mappatura, ho fatto due tavoliPerché ho bisogno della terza tabella per mappature da molti a molti? Perché non posso usare solo due tavoli?

CREATE TABLE person(p_id INTEGER,p_name TEXT,PRIMARY KEY(p_id)); 
CREATE TABLE address(a_id INTEGER,address TEXT); 

e poi ho provato qualcosa nel mapping XML. Dopo alcuni tentativi infruttuosi, ho letto che sono necessarie tre tabelle per mappature da molti a molti, proprio come dice una domanda da answer.

Mi spieghi il motivo di ciò? Perché ho bisogno del terzo tavolo? Perché non riesco a creare un'associazione solo con i due tavoli?

+0

perché un downvote? –

+0

Questa è una cosa molto semplice che dovresti facilmente cercare – Zutty

+0

@ Zutty. Sai la risposta ... se così puoi pubblicare post ... Per me è una buona domanda. – kark

risposta

7

La terza tabella funge da tabella di giunzione che definisce la relazione molti a molti. Nel tuo esempio presumo che un Person possa avere più addresses e un indirizzo possa appartenere a più People. Questa relazione non può essere modellata utilizzando due tabelle.

Si può tentare di includere semplicemente una chiave esterna alla Address nella tabella Person o una chiave esterna per Person nella tabella Address. Ognuna di queste mappature avrebbe un lato one, ovvero one delle particolari entità corrisponde a many dell'altro. Nessuna di queste opzioni raggiunge la relazione many to many e l'utilizzo di una terza tabella è necessario per mappare la relazione più complessa.

Per mappare come many to many è necessario essere in grado di associare più istanze di entrambe le entità l'una con l'altra. Questo è tradizionalmente fatto attraverso il seguente:

Table A 
ID_A 

Table B 
ID_B 

Table C 
ID_A 
ID_B 
6

A causa della natura della relazione.

Se la mappatura è stata one-to-one, di quanto si potrebbe aggiungere una colonna person_id alla tabella Address e ogni Address tuple ricorda a un solo Person.

Address 
+---------------------+ 
|id|p_id|address  | 
+---------------------+ 
| 1| 1 |some street 1| //one address uniquely points to one person 
+---------------------+ 
| 2| 2 |new street 5 | 
+---------------------+ 

Lo stesso vale per uno-a-molti: se un Person può avere più Address es, allora non ci sarebbe più tuple in Address tabella con lo stesso person_id.

Address 
+---------------------+ 
|id|p_id|address  | 
+---------------------+ 
| 1| 1 |some street 1| //two addresses point to one person 
+---------------------+ 
| 2| 1 |new street 5 | 
+---------------------+ 

Ma cosa succede se si può avere Person mutliple Address es, ma anche, uno Address può appartenere a più Person s? Quindi una colonna person_id nella tabella Address non sarebbe sufficiente perché uno Address può riguardare più di Person s! Quindi è necessaria una terza tabella per associare tutte le coppie di Person se Address es.

Assoc table 
+---------+ 
|a_id|p_id|  
+---------+ 
| 1 | 1 | //one address for two persons 
+---------+ 
| 1 | 2 | 
+---------+ 
| 2 | 3 | //two addresses for the same person 
+---------+ 
| 3 | 3 | 
+---------+ 
1

Hmmm non sono sicuro, ma penso che stia parlando di creazione di una "terza classe" nella sua mappatura e non realmente "terza tabella" (altrimenti si sarebbe nemmeno parlare di mapping Hibernate).Quindi supporrò che stia semplicemente lottando con la sua mappatura per la mia risposta (e sarà comunque utile in seguito per il suo mapping in letargo):

Grazie all'annotazione @JoinTable non è necessario creare un'entità per il terzo tavolo. Se hai una relazione molti-a-molti tra le tue tabelle, devi solo creare 2 entità "Persona" e "Indirizzo", e l'annotazione @JoinTable su ogni lato applicherà la magia molti-a-molti senza dover creare un'entità per la terza tabella tra di loro.

TRANNE se la tua terza tabella ha alcune colonne aggiuntive, e in tal caso non hai una scelta dovrai creare un'entità specifica per questa terza tabella (o altrimenti non puoi ottenere quella colonna in più con solo entità "Persona" e "Indirizzo").

Alcuni link utili per la mappatura:

http://www.mkyong.com/hibernate/hibernate-many-to-many-relationship-example-annotation/ http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/

0

im utilizzando ManyToMany con JPA annotazioni, ho bisogno del tuo preziosi suggerimenti. (presupponete la persona e l'indirizzo, lo stesso indirizzo è riferito a più persone (che vivono allo stesso indirizzo)). Devo cancellare una persona da quell'indirizzo.

Person p1 = new Person(); 
    Person p2 = new Person(); 
    Address add1 = new Address(); 

    p1.add(add1); 
    p2.add(add1); 

Utilizzo dello stesso add ref per entrambe le persone. Come pure

add1.add(p1) ; 
    add1.add(p2) ; 

THen su unire o persistere iit mappato in modo appropriato.

p1 - ADD1 p2 - ADD1

devo eliminare p2 da sola, quando ho fatto

p2.removeAddress(add1) 
    removeAddress(add1) { coll.remove(add1) } 

Quello che succede è che cancellato la voce per l'indirizzo e più volte da provider JPA Hibernate cerca di nuovo per persistono nell'entità Indirizzo e dice "entità eliminata passata a persistere" e il rollback della transazione henc avviene. Mi stavo mappando come

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @JoinTable(name = "XXXX", joinColumns = { @JoinColumn(name = "X1_ID", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "X2_ID", nullable = false, updatable = false) }) 
    private Collection<Parser> parsers; 


    Please share your ideas. 
Problemi correlati