2012-03-06 67 views
5

Tôi muốn viết một phương thức trả về một danh sách các đối tượng được thêm cuối cùng được nhóm theo trường 'serviceId'.Viết mệnh đề HQL sử dụng Tiêu chí Hibernate API

Các HQL sau hoạt động, nhưng tôi muốn viết những dòng này sử dụng Tiêu chuẩn API:

FROM Notification WHERE date IN 
    (SELECT MAX(date) FROM Notification GROUP BY serviceId) 
ORDER BY date ASC 

Something như thế này:

Criteria crit = session.createCriteria(Notification.class); 
crit.add(Restrictions.in("date", <MAX dates>)); 
criteria.addOrder(Order.desc("date")); 

Cảm ơn trước.

EDIT:

Bây giờ tôi cần một truy vấn tương tự mà các công trình sử dụng EclipseLink API =/
Về cơ bản, tôi cần người cuối cùng N hàng (ngày max), mà trạng thái được một trong năm được mô tả dưới đây, được nhóm theo cột serviceId.
Do sự thiếu kinh nghiệm của tôi, nó là tốt nhất mà tôi có thể:

ExpressionBuilder builder = new ExpressionBuilder(); 
Expression exStatus1 = builder.get("status").equal(MessageType.START.toString()); 
Expression exStatus2 = builder.get("status").equal(MessageType.RUNNING.toString()); 
Expression exStatus3 = builder.get("status").equal(MessageType.PAUSED.toString()); 
Expression exStatus4 = builder.get("status").equal(MessageType.END_ERROR.toString()); 
Expression exStatus5 = builder.get("status").equal(MessageType.END_SUCCESS.toString()); 

ReadAllQuery query = new ReadAllQuery(); 
query.setReferenceClass(Notification.class); 
query.setSelectionCriteria(((exStatus1).or(exStatus2).or(exStatus3).or(exStatus4).or(exStatus5))); 
query.setMaxRows(listSize); 
query.addDescendingOrdering("date"); 

Các khoản để tránh trùng lặp serviceIds trong dòng Kết quả là mất tích ...

Trả lời

4

Bạn sẽ muốn sử dụng các dự báo Tiêu chuẩn API có truy vấn con tách rời:

Criteria crit = session.createCriteria(Notification.class, "main"); 

DetachedCriteria notificationSubQuery = DetachedCriteria.forClass(Notification.class, "sub"); 
notificationSubQuery.setProjection(Projections.max("date")); 
notificationSubQuery.add(Restrictions.eqProperty("sub.serviceId", "main.serviceId")); 

crit.add(Subqueries.propertyIn("date", notificationSubQuery)); 
crit.addOrder(Order.desc("date")); 

Đây là kỹ thuật bạn đang sử dụng trong truy vấn HQL của mình.

EDIT:

tôi cập nhật các truy vấn để phù hợp với serviceId giữa lớp học của bạn chính thông báo và truy vấn phụ của bạn, về cơ bản giống như truy vấn HQL này:

FROM Notification main WHERE date IN 
    (SELECT MAX(sub.date) FROM Notification sub WHERE sub.serviceId = main.serviceId) 
ORDER BY date ASC 

Điều này ngăn cản trường hợp bạn sẽ có ngày kết hợp không tối đa giữa hai dịch vụ khác nhau như vậy:

serviceId = 1: date = 3,4,5 
serviceId = 2: date = 4,5,6 

Trả về truy vấn cũ :

serviceId: 1, date: 5 
serviceId: 2, date: 5,6 

mới trở lại truy vấn:

serviceId: 1, date: 5 
serviceId: 2, date: 6 

Hãy cho tôi biết nếu làm việc này cho bạn.

+1

Nhưng OP muốn truy vấn phụ là 'chọn tối đa (ngày) từ nhóm Thông báo theo serviceId', thay vì chỉ' chọn tối đa (ngày) từ Thông báo' –

+0

Lỗi của tôi, được cập nhật. –

+0

Hoạt động tốt! Cảm ơn. – elias

Các vấn đề liên quan