我正在尝试将休眠条件转换为jpa条件。我能够成功地将其转换为简单查询,但无法对包含子查询的查询进行转换。查询已生成,但未添加where子句中的限制。我在下面提供了旧代码(休眠标准)和新编写的代码(jpa标准)
我想使用jpa条件api构建动态查询。动态查询使用子查询。
//旧版代码
Criteria criteria = getSession().createCriteria(SecurityUsers.class, "user");
criteria.add(Restrictions.eq("type", 0L));
if (dto.getUserId() != null && !"".equals(dto.getUserId()))
criteria.add(Restrictions.like("name", "%" + dto.getUserId().trim().toUpperCase() + "%"));
if (dto.getUserStatus() != null && !"".equals(dto.getUserStatus()))
criteria.add(Restrictions.eq("activeFlag", dto.getUserStatus().trim()));
if (dto.getUserType() != null && !"".equals(dto.getUserType()))
criteria.add(Restrictions.eq("userAgency", dto.getUserType().trim()));
if ((dto.getFirstName() != null && !"".equals(dto.getFirstName())) ||
(dto.getLastName() != null && !"".equals(dto.getLastName())) ||
(dto.getState() != null && !"".equals(dto.getState()))) {
DetachedCriteria personCriteria = DetachedCriteria.forClass(Person.class, "person");
personCriteria.add(Property.forName("person.personId").eqProperty("user.personId"));
personCriteria.setProjection(Property.forName("personId"));
if (dto.getFirstName() != null && !"".equals(dto.getFirstName()))
personCriteria.add(Restrictions.like("firstName", "%" + dto.getFirstName() + "%"));
if (dto.getLastName() != null && !"".equals(dto.getLastName()))
personCriteria.add(Restrictions.like("lastName", "%" + dto.getLastName() + "%"));
criteria.add(Subqueries.exists(personCriteria));
if (dto.getState() != null && !"".equals(dto.getState())) {
DetachedCriteria addressCriteria = DetachedCriteria.forClass(Address.class, "address");
addressCriteria.add(Property.forName("person.addressId").eqProperty("address.addressId"));
addressCriteria.setProjection(Property.forName("addressId"));
addressCriteria.add(Restrictions.eq("state", dto.getState()));
personCriteria.add(Subqueries.exists(addressCriteria));
}
}
if (dto.getUserGroups() != null && !"".equals(dto.getUserGroups())) {
String[] userGroups = Utilities.getStringArray(dto.getUserGroups(), ",");
DetachedCriteria userGroupsCriteria = DetachedCriteria.forClass(SecurityGroupings.class, "groups");
userGroupsCriteria.add(Property.forName("user.name").eqProperty("groups.id.securityUsers_1.name"));
userGroupsCriteria.setProjection(Property.forName("id"));
userGroupsCriteria.add(Restrictions.in("groups.id.securityUsers.name", userGroups));
criteria.add(Subqueries.exists(userGroupsCriteria));
}
// my jpa criteria code
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<SecurityUsers> q = cb.createQuery(SecurityUsers.class);
Root<SecurityUsers> root = q.from(SecurityUsers.class);
q.select(root);
List<Predicate> predicates = new ArrayList<>();
predicates.add((Predicate) cb.equal(root.<String>get("type"), 0L));
if (dto.getUserId() != null && !"".equals(dto.getUserId())) {
predicates.add(
(Predicate) cb.like(root.<String>get("name"), "%" + dto.getUserId().trim().toUpperCase() + "%"));
}
if (dto.getUserStatus() != null && !"".equals(dto.getUserStatus())) {
predicates.add((Predicate) cb.equal(root.<String>get("activeFlag"), dto.getUserStatus().trim()));
}
if (dto.getUserType() != null && !"".equals(dto.getUserType())) {
predicates.add((Predicate) cb.equal(root.<String>get("userAgency"), dto.getUserType().trim()));
}
Predicate[] p0 = predicates.toArray(new Predicate[predicates.size()]);
q.where(cb.and((javax.persistence.criteria.Predicate[]) p0));
if ((dto.getFirstName() != null && !"".equals(dto.getFirstName()))
|| (dto.getLastName() != null && !"".equals(dto.getLastName()))
|| (dto.getState() != null && !"".equals(dto.getState()))) {
Subquery<Person> personSubquery = q.subquery(Person.class);
Root<Person> personInfo = personSubquery.from(Person.class);
List<Predicate> personPredicates = new ArrayList<>();
personSubquery.select(personInfo.get("personId"));
personPredicates.add(cb.equal(personInfo.<String>get("personId"), root.<String>get("personId")));
if (dto.getFirstName() != null && !"".equals(dto.getFirstName())) {
personPredicates
.add((Predicate) cb.like(root.<String>get("firstName"), "%" + dto.getFirstName() + "%"));
}
if (dto.getLastName() != null && !"".equals(dto.getLastName())) {
personPredicates.add((Predicate) cb.like(root.<String>get("lastName"), "%" + dto.getLastName() + "%"));
}
Predicate[] p = personPredicates.toArray(new Predicate[personPredicates.size()]);
personSubquery.where(cb.and((javax.persistence.criteria.Predicate[]) p));
q.select(root).where(cb.exists(personSubquery));
if (dto.getState() != null && !"".equals(dto.getState())) {
Subquery<Address> addressSubquery = personSubquery.subquery(Address.class);
Root<Address> addressInfo = addressSubquery.from(Address.class);
List<Predicate> addressPredicates = new ArrayList<>();
addressSubquery.select(addressInfo.get("addressId"));
addressPredicates
.add(cb.equal(addressInfo.<String>get("addressId"), addressInfo.<String>get("addressId")));
addressPredicates.add(cb.equal(addressInfo.<String>get("state"), dto.getState()));
Predicate[] p1 = addressPredicates.toArray(new Predicate[addressPredicates.size()]);
addressSubquery.where(cb.and((javax.persistence.criteria.Predicate[]) p1));
personSubquery.select(personInfo).where(cb.exists(addressSubquery));
}
}
if (dto.getUserGroups() != null && !"".equals(dto.getUserGroups())) {
String[] userGroups = Utilities.getStringArray(dto.getUserGroups(), ",");
Subquery<SecurityGroupings> securityGroupingSubquery = q.subquery(SecurityGroupings.class);
Root<SecurityGroupings> securityGroupingInfo = securityGroupingSubquery.from(SecurityGroupings.class);
List<Predicate> securityGroupingPredicates = new ArrayList<>();
securityGroupingPredicates.add(
cb.equal(securityGroupingInfo.<String>get("id.securityUsers_1.name"), root.<String>get("name")));
Predicate[] p2 = securityGroupingPredicates.toArray(new Predicate[securityGroupingPredicates.size()]);
securityGroupingSubquery.where(cb.and((javax.persistence.criteria.Predicate[]) p2));
q.select(root).where(cb.exists(securityGroupingSubquery));
}
q.where(cb.and((javax.persistence.criteria.Predicate[]) p0));
TypedQuery<SecurityUsers> typedQuery = em.createQuery(q);
// typedQuery.setFirstResult(pagingDTO.getFirstResult());
// typedQuery.setMaxResults(10);
List<SecurityUsers> resultList = typedQuery.getResultList();
我的代码无法生成正确的查询。正在生成的查询是这样的:
select securityus0_.name as name1_71_, securityus0_.description as description2_71_, securityus0_.su_person_id as su_person_id3_71_, securityus0_.priority as priority4_71_, securityus0_.user_type as user_type5_71_, securityus0_.email_address as email_address6_71_, securityus0_.su_shared_logon_flag as su_shared_logon_fl7_71_, securityus0_.su_create_username as su_create_username8_71_, securityus0_.su_create_date as su_create_date9_71_, securityus0_.su_update_username as su_update_usernam10_71_, securityus0_.su_user_agency as su_user_agency11_71_, securityus0_.su_active_flag as su_active_flag12_71_, securityus0_.su_update_date as su_update_date13_71_, securityus0_.su_expedite_flag as su_expedite_flag14_71_, securityus0_.su_ow_id as su_ow_id15_71_ from gm.security_users securityus0_ where exists (select person1_.person_id from gm.person person1_ where exists (select address2_.address_id from gm.address address2_ where address2_.address_id=address2_.address_id and address2_.a_state=?))