1

I implemented a generic solution for using lazy loading primefaces datatables using JPA Criterea. However I am still having some doubts with thie implemented solution whenever we deal with several Joins (say for example an entity User that has relation with other entities like Account, Address, Department.....in addition to raw type properties like: String username, Date birthdate...etc).

I tested this solution but I am having some delays while loading huge number of data (however the solution is supposed to load only a limited number of rows specified by PageSize coming from datatable), so:

How to improve the performance of this solution? How to be sure the number of loaded data is the one specified in the Pagesize? Can you check the count() method and tell if it counts the number of result rows without loading all the data?

And most importantly how to use this solution in order to be generic with filters coming from Search forms (I mean how to use this sae generic method and give search critereas from a search form with multi search fields)?

Please I need your answer on the above mentioned questions especially the last one. Here is the code:

public <T extends Object> List<T> search(Class<T> type, int first, int pageSize, String  sortField, SortOrder sortOrder, Map<String, String> filters){
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<T> q = cb.createQuery(type);  
        Root<T> root=q.from(type);
        q.select(root);

        //Sorting
        if (sortField != null && !sortField.isEmpty()) {  
            String[] sortingField = sortField.split("\\.", 2);
            Path path = sortingField.length == 1 ? root.get(sortingField[0]): root.join(sortingField[0]).get(sortingField[1]);
             if (sortOrder.equals(SortOrder.ASCENDING)) {  
                    q.orderBy(cb.asc(path));  
                } else if (sortOrder.equals(SortOrder.DESCENDING)) {  
                    q.orderBy(cb.desc(path));  
                }
        }  

        // Filtering
        Predicate filterCondition = cb.conjunction();
        String wildCard = "%";

        for (Map.Entry<String, String> filter : filters.entrySet()) {
            String[] filterField = filter.getKey().split("\\.", 2);
            Path path = filterField.length == 1 ? root.get(filterField[0]): root.join(filterField[0]).get(filterField[1]);
            filterCondition = cb.and(filterCondition, filter.getValue().matches("[0-9]+") 
                    ? cb.equal(path, Long.valueOf(filter.getValue()))
                    : cb.like(path, wildCard + filter.getValue() + wildCard));   
        }q.where(filterCondition);

        //Pagination
        TypedQuery<T> s = entityManager.createQuery(q);
        if (pageSize >= 0){
            s.setMaxResults(pageSize);
        }
        if (first >= 0){
            s.setFirstResult(first);
        }
        log.info("\n\n\n");
        log.info("XXXXXXXXXxX");
        log.info("=> CommonRepository - Total number of rows returned: ");
        log.info("XXXXXXXXXXX");
        log.info("\n\n\n");
        return s.getResultList();
 }


public <T extends Object> int count(Class<T> type, Map<String, String> filters){
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
        Root<T> root=cq.from(type);

        // Filtering
        Predicate filterCondition = cb.conjunction();
        String wildCard = "%";

        for (Map.Entry<String, String> filter : filters.entrySet()) {

            String[] filterField = filter.getKey().split("\\.", 2);

            Path path = filterField.length == 1 ? root.get(filterField[0]): root.join(filterField[0]).get(filterField[1]);

            filterCondition = cb.and(filterCondition, filter.getValue().matches("[0-9]+") 
                    ? cb.equal(path, Long.valueOf(filter.getValue()))
                    : cb.like(path, wildCard + filter.getValue() + wildCard));   
        }cq.where(filterCondition);
        cq.select(cb.count(root));
        return entityManager.createQuery(cq).getSingleResult().intValue();
}
CurlyPaul
  • 1,138
  • 1
  • 10
  • 29
  • Have you seen this answer: http://stackoverflow.com/a/13973903/870122 – perissf May 14 '14 at 15:24
  • hi dear perissf, thanks for your reply. I will see in details the the answer you pointed to..but lease can you reply to my questions based based on the code I posted already..and by the way would it be possible to use generic search method like the one i have implemented above that lazy loads data and apply it for many cases? – user3636976 May 15 '14 at 04:47

0 Answers0