PersonSearchRepositoryImpl.java
package com.tradecloud.repository.impl;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.party.Employee;
import com.tradecloud.domain.party.EmployeeRole;
import com.tradecloud.domain.party.base.Person;
import com.tradecloud.dto.company.PersonSearch;
import com.tradecloud.repository.GeneralRepository;
import com.tradecloud.repository.PersonSearchRepository;
import com.tradecloud.repository.SearchMetaParams;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import com.tradecloud.repository.company.CompanySearchRepositoryImpl;
import org.apache.log4j.Logger;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Repository
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class PersonSearchRepositoryImpl extends RepositoryBaseImpl<Person, PersonSearch> implements PersonSearchRepository {
private static final long serialVersionUID = 1L;
private static final String LIKE = "%";
private static Logger log = Logger.getLogger(CompanySearchRepositoryImpl.class);
@Autowired
private GeneralRepository generalRepository;
@SuppressWarnings("unchecked")
@Override
public List<Person> search(PersonSearch search) {
javax.persistence.criteria.CriteriaBuilder cb = getSession().getCriteriaBuilder();
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
Root<Employee> root = cq.from(Employee.class);
List<Predicate> predicates = buildPredicates(cb, root, search);
cq.select(root)
.where(predicates.toArray(new Predicate[0]))
.distinct(true);
SearchMetaParams metaParams = search.getSearchMetaParams();
cq.orderBy(cb.asc(root.get("lastName")));
Query<Employee> query = getSessionCustom().createQuery(cq);
if (metaParams != null && metaParams.isPaged()) {
query.setFirstResult(metaParams.getRowIndex());
query.setMaxResults(metaParams.getRowCount());
}
return query.getResultList().stream().map(emp -> ((Employee) emp)).collect(Collectors.toList());
}
@Override
public long count(PersonSearch search) {
javax.persistence.criteria.CriteriaBuilder cb = getSessionCustom().getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<Employee> root = cq.from(Employee.class);
List<Predicate> predicates = buildPredicates(cb, root, search);
cq.select(cb.countDistinct(root)) // count distinct persons
.where(predicates.toArray(new Predicate[0]));
return getSessionCustom().createQuery(cq).getSingleResult();
}
private List<Predicate> buildPredicates(javax.persistence.criteria.CriteriaBuilder cb, Root<Employee> root,
PersonSearch search) {
List<Predicate> predicates = new ArrayList<>();
// active
if (search.getActive() != null) {
predicates.add(cb.equal(root.get("active"), search.getActive()));
}
// firstName ilike
if (search.getFirstName() != null && !search.getFirstName().trim().isEmpty()) {
predicates.add(cb.like(cb.lower(root.get("firstName")),
"%" + search.getFirstName().toLowerCase() + "%"));
}
// lastName ilike
if (search.getLastName() != null && !search.getLastName().trim().isEmpty()) {
predicates.add(cb.like(cb.lower(root.get("lastName")),
"%" + search.getLastName().toLowerCase() + "%"));
}
// email ilike
if (search.getEmail() != null && !search.getEmail().trim().isEmpty()) {
predicates.add(cb.like(cb.lower(root.get("email")),
"%" + search.getEmail().toLowerCase() + "%"));
}
// roles (ManyToMany join with EmployeeRole)
if (search.getRoles() != null && !search.getRoles().isEmpty()) {
Join<Person, EmployeeRole> rolesJoin = root.join("employeeRoles", JoinType.INNER);
predicates.add(rolesJoin.get("code").in(search.getRoles()));
}
// organisationalUnit
if (search.getOrganisationalUnit() != null) {
Join<Person, OrganisationalUnit> orgJoin = root.join("organisationalUnit", JoinType.LEFT);
List<Predicate> orgPredicates = new ArrayList<>();
for (OrganisationalUnit child : search.getOrganisationalUnit().getChildren()) {
if (search.isLiteSearch()) {
orgPredicates.add(cb.equal(orgJoin.get("code"), child.getCode()));
}
}
orgPredicates.add(cb.equal(orgJoin.get("code"), search.getOrganisationalUnit().getCode()));
predicates.add(cb.or(orgPredicates.toArray(new Predicate[0])));
}
return predicates;
}
}