2011-12-20 11 views
8

Esiste la possibilità di disabilitare la tabella di unione delle relazioni @OneToMany con l'annotazione @JoinColumn. L'impostazione predefinita è una tabella di join.OneToMany - quali sono le differenze tra join table e foreign key?

Quali sono i vantaggi e gli svantaggi per un sistema di produzione, ad esempio?
Quando dovrei usare una tabella di join e quando no?

Grazie.

+0

Non è necessario utilizzare la tabella delle relazioni nella relazione 1: n. Chiedi più precisamente. –

+0

Come impostazione predefinita, il mapping @OneToMany crea una tabella di join. Non so perché l'impostazione predefinita non è la mappatura con chiave esterna ... –

+1

La mia ipotesi è che non è per prestazioni o svantaggi, ma perché JPA generalmente presuppone che tutti i campi all'interno di una tabella siano mappati all'interno dell'entità corrispondente. Questo è un caso limite dal momento che è più comune avere un OneToMany con un back ManyToOne. Con OneToMany unidirezionale che utilizza joincolumn, richiede che la tabella figlio abbia una chiave esterna, ma l'entità figlio non ha un riferimento al suo genitore. – Chris

risposta

16

Per impostazione predefinita, @OneToMany creerà una tabella di join solo se si utilizzerà la relazione unidirezionale .

In altre parole, se avete Employee e Project entità e l'entità Employee è definito come segue (assumono non ci sono orm.xml voci per queste entità):

@Entity 
public class Employee { 
    // ... 

    @OneToMany 
    Set<Project> projects; 
} 

@Entity 
public class Project { 
    // ... 
} 

il provider JPA creerà una tabella di join (avviso non esiste l'attributo mappedBy nell'annotazione @OneToMany in quanto non vi è alcun riferimento all'entità Employee da Project).

D'altra parte, se userete relazione bidirezionale:

@Entity 
public class Employee { 
    // ... 

    @OneToMany(mappedBy="employee") 
    Set<Project> projects; 
} 

@Entity 
public class Project { 
    // ... 

    @ManyToOne 
    Employee employee; 
} 

non verrà utilizzata la tabella unirsi, in quanto vi "molti" saranno utilizzati per memorizzare la chiave esterna per questa relazione.

Tuttavia, è possibile forzare l'utilizzo della tabella di unione anche nei casi in cui si ha una relazione bidirezionale @OneToMany con l'attributo mappedBy definito. Puoi ottenerlo usando l'annotazione @JoinTable sul lato proprietario della relazione.

Esiste anche la possibilità, come già menzionato, di utilizzare @JoinColumn nel caso in cui la tabella di join venga utilizzata per impostazione predefinita (rapporto unidirezionale @OneToMany).

È meglio testare l'FK e unire la differenza di prestazioni del tavolo per te. Posso solo immaginare che meno join (in questo caso: FK) sembrano avere prestazioni migliori.

Inoltre, a volte il DBA definisce lo schema del database e devi solo adattare i tuoi mapping allo schema esistente. Quindi non hai scelta su FK o join table - è per questo che hai una scelta.

+0

Hibernate è chiaro a riguardo: "È preferibile uno a uno unidirezionale con una tabella di join, che viene descritta tramite una @JoinTable." http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#d0e1168 sezione "2.2.5.3.1.3 Unidirezionale con join table" – lko

0

Le tabelle di unione sono necessarie per i polimorfismi. Ad esempio, se Employee e Manager collegano lo stesso progetto e sono mappati con una strategia di una tabella per classe, a livello di DB relazionale, l'unico modo per sapere che il progetto (id = 1, emp_id = 10) si riferisce a un manager è inserire emp_id nella tabella manager_2_employee. Se uno non è in una situazione del genere, allora emp_id può andare direttamente nel progetto.

+0

Scopri i vantaggi della tabella join http://stackoverflow.com/domande/1307203/hibernate-unidirezionale-uno-a-molti-associazione-perché-è-un-join-table-better –

0

Come menzionato nei commenti sopra, per impostazione predefinita la sospensione passa alla tabella di join. Ciò si traduce in una migliore normalizzazione db.

Se si dispone di una scelta, JoinColumn offre prestazioni migliori rispetto alla tabella di join in quanto è necessario rimuovere l'unione di una tabella aggiuntiva in SQL Query.