2011-08-26 30 views
7

Tôi đã sau JPA thực thể:RIGHT JOIN trong 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; 
} 

Bây giờ tôi muốn chạy một truy vấn JPQL để có được danh sách của người sử dụng với ngày truy cập cuối cùng của họ. Thật không may, truy vấn sau không trả lại người dùng không bao giờ truy cập vào hệ thống, tức là tồn tại trong bảng UserClient, nhưng không có bất kỳ bản ghi nào trong UserAccess một.

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

Tôi có bỏ lỡ điều gì đó không? Đó có phải là sử dụng đúng RIGHT JOIN không?

Tôi đang sử dụng mới nhất của Hibernate JPA phát hành (4.0.0.CR1)

Trả lời

5

Bạn nên làm cho UserClient bảng chủ sở hữu bên của mối quan hệ (trong đó có ý nghĩa logic hơn IMO). Sau đó, bạn có thể sử dụng LEFT JOIN thay vì 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

bạn bỏ lỡ alias ua trên us.userAccess. Ngoài ra, có sự kết hợp OneToMany nghịch đảo là đủ. Không cần phải làm cho nó bên chủ sở hữu (đó là impossile trong JPA, BTW) –

+0

@Matt Người dùng có thể được tham gia vào nhiều đối tượng khác, vì vậy với tôi nó hợp lý hơn các đối tượng này trỏ đến người dùng sau đó khác. Bạn có nghĩ gì sai với RIGHT JOIN của tôi không? –

+0

@JB Nizet cảm ơn sự điều chỉnh, tôi đã chỉnh sửa điều này một cách nhanh chóng. Tôi đã không tự mình thử truy vấn trên. Bạn có chắc chắn rằng JPA có thể để lại tham gia như bạn mô tả không? Cảm thấy tự do để chỉnh sửa câu trả lời của tôi cho ít thất bại, hoặc chỉ đăng bài của riêng bạn dựa trên tôi ... –