2011-08-26 9 views
7

Tengo el siguiente JPA entidades:afiliarse directamente en 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; 
} 

Ahora quería ejecutar una consulta JPQL para obtener la lista de los usuarios con su última fecha de acceso. Lamentablemente, la siguiente consulta no devuelve los usuarios que nunca tuvieron acceso al sistema, es decir, que existen en la tabla UserClient, pero no tienen ningún registro en UserAccess.

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

¿Echo de perder algo? ¿Es ese el uso correcto de RIGHT JOIN?

estoy usando la última versión de Hibernate JPA (4.0.0.CR1)

Respuesta

5

Usted debe hacer la tabla UserClient el lado propietario de la relación (que tiene sentido más lógico OMI). Luego puede usar un LEFT JOIN en lugar de un 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

se ha perdido el alias UA en us.userAccess. Además, tener la asociación inversa OneToMany es suficiente. No es necesario que sea del lado del propietario (lo cual es imposible en JPA, BTW) –

+0

@Matt El usuario puede estar involucrado en muchos otros objetos, por lo que para mí es más lógico que estos objetos apunten al usuario. ¿Crees que haya algo mal con mi DERECHA? –

+0

@JB Nizet gracias por la corrección. Lo edité a toda prisa. No he intentado la consulta anterior yo mismo. ¿Estás seguro de que JPA puede unirse como lo describes? Siéntase libre de editar mi respuesta por menos errores, o simplemente publique la suya basada en la mía ... –

Cuestiones relacionadas