2012-12-14 7 views
7

Sto lavorando su un sistema legacy, ho bisogno di leggere alcune informazioni dal database. Qui di seguito sono il rapporto tavoloAssociazione uno a molti - Unire tabelle con colonna chiave non primaria in JPA

produttore (VendorID - pk, vendorEid, nome)
VendorContactBridge (bridgeId -pk, vendorEid, contactEid)
contatto (contactID -pk, contactEid, telefono)

vendorEid e contactEid non sono la chiave primaria della tabella ma sono utilizzate come colonne di join nella tabella Join VendorContactBridge.

Venditore Entity -

@Entity 
@Table(name="Vendor") 
public class Vendor implements Serializable{ 

@Id 
@Column(name="VENDORID") 
private BigDecimal vendorId; 

@Column(name="VENDOREID") 
private BigDecimal vendorEid; 

@OneToMany(fetch = FetchType.EAGER) 
@JoinTable(name="VENDORCONTACTBRIDGE", 
joinColumns={@JoinColumn(name="VENDOREID", referencedColumnName="VENDOREID")}, 
inverseJoinColumns={@JoinColumn(name="CONTACTEID", referencedColumnName="CONTACTEID")}) 
private Set<Contact> vendorContact; 
} 

Contatto Entity -

@Entity 
@Table(name="CONTACT") 
public class Contact implements Serializable{ 

@Id 
@Column(name="CONTACTID") 
private BigDecimal contactId; 

@Column(name="CONTATEID") 
private BigDecimal contactEId; 

@ManyToOne 
@JoinTable(name="VENDORCONTACTBRIDGE", 
joinColumns={@JoinColumn(name="CONTACTEID", referencedColumnName="CONTATEID")}, 
inverseJoinColumns={@JoinColumn(name="VENDOREID", referencedColumnName="VENDOREID")}) 
private Vendor vendor; 
} 

durante l'esecuzione della query, ottenendo sotto eccezione

SecondaryTable JoinColumn non può fare riferimento una chiave non primaria.

Ho rimosso il recupero Eager che ho dato nell'entità Vendor, non ottengo alcuna eccezione ma non carica la collezione. Cosa c'è di sbagliato con l'associazione?

risposta

10

Secondo il JPA 2.0 specs paragrafo 11.1.21 JoinColumn annotaion a pagina 379

Supporto per colonne di riferimento che non sono le colonne chiave primaria della tabella di riferimento è facoltativo. Le applicazioni che utilizzano tali mappature non saranno portatili .

Sembra che Hibernate scelga di non implementare questa parte facoltativa. Altre implementazioni potrebbero. L'ho provato su EclipseLink ma anche quello non funziona (fallisce la validazione).

Vedo due soluzioni. Uno è quello di regolare lo schema per utilizzare le chiavi primarie che sarebbe la cosa giusta da una prospettiva di teoria del design di database. Tuttavia potrebbe non essere un'opzione a causa di altri software che dipendono da questo schema che lascia l'opzione due. Lavorare intorno ad esso NON moddelling la relazione in JPA, basta usare l'eid e recuperare gli oggetti rilevanti da soli.

+0

Opzione 2: Vuoi dire, dovrei fare due db chiamare uno per ottenere ContactEid da VendorContactBridge base VendorEid e il nuovo in contatto ased su ContactEid? La mia comprensione è corretta? – Pankaj

+0

Questo sarebbe il principio di base. Ma sarebbe meglio usare una query nativa come si sarebbe in grado di fare un join e quindi utilizzare una query sql per recuperare gli oggetti. – Eelke

Problemi correlati