2016-01-04 24 views
6

Ho i seguenti 2 soggetti:Differenza tra unirsi e navigazione percorso nella query JPA

class User { 
private String name; 
private UserType userType; 
} 

class UserType { 
private String name; 
} 

Voglio recuperare tutti gli utenti con nome UserType uguale a 'admin'. Posso scrivere le seguenti 2 query che restituiscono lo stesso risultato.

select u from User u where u.userType.name = 'admin'; 

e

select u from User u join u.userType ut where ut.name = 'admin'; 

Volevo solo capire quale approccio è preferibile e qual è la differenza. Se posso sempre ottenere il risultato usando la navigazione tra entità quando voglio seguire l'approccio di join?

+2

E se fosse necessario un join esterno sinistro? Inoltre, il primo approccio che produce un'adesione implicita è evitabile poiché potrebbe produrre un cross join a seconda del provider JPA in uso. Pertanto, insisti sempre nell'osservare attentamente anche le istruzioni SQL generate. – Tiny

risposta

2

Analizzando il codice SQL generato dalle due query (jpa + Spring Data) è stato osservato che la navigazione porta a un cross join mentre menzionare solo "join" porta per impostazione predefinita un join interno.

Quindi, la navigazione non è efficiente come unire esplicitamente le colonne richieste.

+1

Non sembra esserci un accordo generale su questo comportamento. Hibernate produce in modo imprevisto un cross join, EclipseLink produce un inner join come previsto, altri provider potrebbero avere il proprio comportamento. Ovviamente non si dovrebbe dipendere da questo comportamento irritante di diversi fornitori che porteranno quindi a logiche di business non portabili su diversi provider in cui nessuna delle caratteristiche proprietarie non viene affatto utilizzata. – Tiny

2

Tecnicamente, sono equivalenti ma il secondo è molto più flessibile.

con la sintassi join esplicito, è possibile modificare la JOIN-LEFT JOIN con una ON criteri:

select u 
from User u 
left join u.userType ut on ut.name = 'admin' 

Questa query sarà sempre restituire un utente, anche se non ha un tipo di utente, in modo a volte questo è desiderabile per alcuni casi d'uso particolari.