2011-12-20 7 views
7

Anche se la mia domanda è formulata specificamente per il modo in cui le relazioni Entità sono rappresentate nel framework Play, che utilizza Hibernate, sono sicuro che questo è un generale concetto.Cercare di capire l'importanza di un lato proprietario di una relazione uno-molti in ORM

Quando abbiamo una relazione uno-a-molti, viene sempre richiesto di specificare il lato proprietario.

Così, ad esempio, se avessimo una relazione uno-a-molti tra Persona e PhoneNumber, scriveremmo codice come questo.

@Entity 
class Person { 
    @OneToMany(mappedBy="person") 
    public Set<PhoneNumber> phoneNumbers; 
} 

@Entity 
class PhoneNumber { 
    @ManyToOne 
    public Person person; 
} 

Nel codice sopra riportato, l'entità di appartenenza è PhoneNumber. Quali sono i pro e i contro di entrambe le parti come entità proprietaria?

Mi rendo conto che quando l'entità proprietaria è PhoneNUmber, la relazione rappresentata è ManyToOne, che non risulterà in una tabella di join, mentre quando il lato proprietario è Persona, la relazione rappresentata sarebbe OneToMany, nel qual caso verrà creata una tabella delle relazioni essere creato.

È questo il motivo principale per determinare il lato proprietario o ci sono altri motivi?

Aggiornamento: Ho appena realizzato che this thread fornisce parte della risposta, ma spero ci possono essere altri punti pure.

risposta

1

Con la maggior parte dei livelli ORM si ha il concetto di caricamento lento. Quando crei un oggetto Person, non caricherà i telefoni impostati a meno che non venga richiesto. A volte il modo in cui vuoi cercare i dati può anche dettare come lo memorizzi.

Come se si desidera richiamare prima persona e quindi mostrare i numeri di telefono su richiesta, quindi mantenere i riferimenti delle persone nel telefono va bene. Innanzitutto fai una semplice query per caricare dati personali e poi cerca numeri di telefono basati su una persona (già caricata) person.id (un'altra semplice query)

Considerando che per mostrare persona + dati telefonici in una volta, preferiresti avere una tabella di join in cui è possibile caricare i dati in base alla tabella delle persone + la tabella di join della persona-telefono utilizzando l'ID della persona come chiavi nella tabella del telefono, tutto in una volta. Qui sarebbe costoso effettuare ricerche senza una tabella delle relazioni.

Ma francamente, se si pensa SQL invece di ORM, allora si dovrebbe andare con una tabella di rapporto ogni volta: D

+0

Sto cercando di pensare ad alta voce. Diciamo che in entrambi i casi, facciamo un recupero impaziente. Per il primo caso, dove PhoneNumber è l'entità proprietaria, la prima query verrà attivata per ottenere tutte le entità Person e quindi verranno generate singole query per ogni Persona per ottenere tutti gli PhoneNumber per quella Persona. Tuttavia, se avessimo la Persona come parte proprietaria, abbiamo bisogno di attivare solo una query con un join. Mi dispiace se questa è una domanda stupida, ma un join non è possibile con Person che è un FK in PhoneNumber? – Parag

+0

Sì, il join dovrebbe essere possibile anche con ID utente FK nella tabella del telefono.Eccomi (supponendo) che una ricerca normalizzata sia più veloce ma devi essere sicuro del tuo piano di spiegazioni. Un altro motivo (almeno teorico) per utilizzare una tabella di relazioni sarebbe consentire la condivisione di numeri di telefono, come un numero di telefono utilizzato da due persone in turni. Francamente, come funziona uno strato ORM dovrebbe essere irrilevante per tali considerazioni perché nessuno progetta lo schema con un livello ORM in mente – rjha94

+0

vedere la mia risposta in questo thread pure per ragioni per i nomi 'mappedBy' e 'owning side', cosa succede se non definiamo un lato proprietario, GOTCHAs - http://stackoverflow.com/questions/2749689/what-is-the-owning-side-in-an-orm-mapping/21068644#21068644 –

6

Un punto importante da tenere a mente è che il rapporto proprietario è quello che in realtà persistono il relazione su salva. Con un esempio:

Person person = new Person(); 
    PhoneNumber pn = new PhoneNumber(); 
    pn.phone = "12345678"; 
    person.phoneNumbers.add(pn); 
    session.save(person); 

Il rapporto non è salva infatti se si ricarica l'entità dal database vedrete numeri. Per aggiungere effettivamente la relazione è necessario impostare la persona sul lato proprietario (PhoneNumber) e quindi salvare.

// the relation is not saved 
    Person loadedPerson = (Person)session.load(Person.class, person.id); 
    System.out.println(loadedPerson.phoneNumbers.size()); // prints 0! 

    pn.person = person; 
    session.save(pn); 

    loadedPerson = (Person)session.load(Person.class, person.id); 
    System.out.println(loadedPerson.phoneNumbers.size()); // prints 1 
Problemi correlati