2013-08-05 20 views
9

Tôi đang cố gắng để thay đổi HQL sau để sử dụng Tiêu chuẩn JPA:CriteriaBuilder.and & CriteriaBuilder.or, cách thực hiện?

select distinct d from Department d 
left join fetch d.children c 
where d.parent is null 
and (
    d.name like :term 
    or c.name like :term 
    ) 
order by d.name 

DepartmentSet<Department> của trẻ em.

Tiêu chí:

CriteriaBuilder cb = getEntityManager().getCriteriaBuilder(); 
CriteriaQuery<Department> c = cb.createQuery(Department.class); 
Root<Department> root = c.from(Department.class); 
root.fetch("children", JoinType.LEFT); 
Path<Department> children = root.join("children", JoinType.LEFT); 
c.orderBy(cb.asc(root.get("name"))); 
c.distinct(true); 
c.where(cb.isNull(root.get("parent"))); 
String param = "%" + "term" + "%"; 
cb.and(cb.like(root.<String> get("name"), param)); 
cb.or(cb.like(children.<String> get("name"), param)); 

TypedQuery<Department> tq = getEntityManager().createQuery(c); 
departments = tq.getResultList(); 

Tôi biết nó có thể là một chút ngắn gọn, tuy nhiên, HQL trả 24 và Tiêu chuẩn phiên bản 28. Tôi nghĩ rằng tôi sẽ không xử lý:

and (x = y OR z = y) 

một cách chính xác. Mọi con trỏ sẽ được đánh giá cao. Cảm ơn.

Trả lời

23

Dưới đây là mệnh đề where của truy vấn JPQL của bạn:

where d.parent is null 
and (
    d.name like :term 
    or c.name like :term 
    ) 

Các mệnh đề where chứa hai vị từ:

d.parent is null 

(d.name like :term 
or c.name like :term) 

Các vị thứ hai là một or chứa hai các vị từ:

d.name like :term 

c.name like :term 

Vì vậy, bạn cần cấu trúc tương tự trong truy vấn tiêu chí của bạn:

Predicate orClause = 
    cb.or(cb.like(root.<String>get("name"), param), 
      cb.like(children.<String>get("name"), param)); 

c.where(cb.isNull(root.get("parent")), 
     orClause); 
+0

Nhờ một triệu. – kmansoor

+0

Cảm ơn vì điều này vì tôi cũng đang tìm kiếm điều này. – user75ponic

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