CriteriaBuilder.and & CriteriaBuilder.or, how-to?

匿名 (未验证) 提交于 2019-12-03 02:56:01

问题:

I'm trying to change the following HQL to use JPA Criteria:

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 

Department has a Set<Department> of children.

Criteria:

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(); 

I know it can be a bit terse, however, the HQL returns 24 and Criteria version 28. I think I'm not handling:

and (x = y OR z = y) 

correctly. Any pointers will be greatly appreciated. Thanks.

回答1:

Here's the where clause of your JPQL query:

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

The where clause contains two predicates:

d.parent is null  

and

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

The second predicate is an or containing two predicates:

d.name like :term 

and

c.name like :term 

So you need the same structure in your criteria query:

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); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!