2011-08-26 26 views
7

Ho il seguente JPA entità:DESTRA Join In JPQL

@Entity 
class UserClient{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 
} 

@Entity 
class UserAccess{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    @ManyToOne(optional = false, cascade = { CascadeType.REFRESH }) 
    private UserClient user; 

    @Temporal(TemporalType.TIMESTAMP) 
    private Date accessTs; 
} 

Ora volevo eseguire una query JPQL per ottenere l'elenco degli utenti con la loro ultima data di accesso. Sfortunatamente la seguente query non restituisce gli utenti che non hanno mai avuto accesso al sistema, cioè nella tabella UserClient, ma non hanno alcun record nello UserAccess.

SELECT ua.user, MAX(ua.accessTs) FROM UserAccess ua RIGHT JOIN ua.user 

Mi manca qualcosa? L'uso corretto di RIGHT JOIN è corretto?

sto utilizzando l'ultima versione di Hibernate JPA (4.0.0.CR1)

risposta

5

Si dovrebbe fare il tavolo UserClient lato proprietario del rapporto (che ha senso più logico IMO). Quindi è possibile utilizzare uno LEFT JOIN anziché uno RIGHT JOIN.

SELECT uc, MAX(ua.accessTs) FROM UserClient uc LEFT JOIN uc.userAccess ua 

Here's why left join on UserAccess works:

SQL left join visual description

+0

vi siete persi l'alias ua su us.userAccess. Inoltre, è sufficiente avere l'associazione inversa OneToMany. Non c'è bisogno di farne il lato proprietario (che è impossibile in JPA, BTW) –

+0

@Matt L'utente può essere coinvolto in molti altri oggetti, quindi per me è più logico che questi oggetti puntino su Utente altrimenti. Pensi che qualcosa non vada nel mio GIUSTO PARTITO? –

+0

@JB Nizet grazie per la correzione, l'ho modificato in fretta. Non ho provato la query sopra me stesso. Sei sicuro che JPA possa abbandonare la partecipazione come descrivi? Sentiti libero di modificare la mia risposta per meno fallire, o semplicemente pubblicare il tuo basato sul mio ... –

Problemi correlati