2
\$\begingroup\$

My company develops a Spring web application that exposes a REST API and right now we're starting to look into pagination for the methods that load data from some heavy tables.

We initially looked into Spring Data JPA but had some difficulties in integrating the Repository logic so in the end I integrated only the beans that handle the Pageable page request and the Page response from the methods.

Since I have to return a Page that contains the data and the total number of elements I created a wrapper object that I called PaginationHelper in order to avoid creating two separate methods with the same query logic, one for calculating the total number of elements and the other to actually return the current requested page.

This is a code example from the Rest Controller to the DAO:

PaginationHelper

public class PaginationHelper<T> {

    private long numTotalElements;
    private List<T> page;

    public PaginationHelper() {

    }

    public PaginationHelper(List<T> page, long numTotalElements) {
        this.page = page;
        this.numTotalElements = numTotalElements;
    }

//getters and setters


}

Controller search method

@RequestMapping(value="/search",method=RequestMethod.GET)
    public Page<Foo> findFoo(@RequestParam (value = "filterParam1", required=false) String param1,
                                                             @RequestParam(value="filterParam2", required=false) String param2,
                                                             @RequestParam(value="filterParam3", required=false) boolean param3,
                                                             Pageable pageRequest)
    {
        Page<Foo> retPage=null;
        boolean flCount = false;
        PaginationHelper pagHelper = myService.search(param1, param2, param3, pageRequest);

        if(pagHelper!=null && pagHelper.getPage()!=null)
        {
            retPage = new PageImpl(pagHelper.getPage(), pageRequest, pagHelper.getNumTotalElements())
        }
        return retPage;
    }

Service

public PaginationHelper search(String param1, 
            String param2, boolean param3, Pageable pageRequest) {

//--> I'm not so sure about this, seems very dirty to me
        PaginationHelper<Foo> paginationHelper = new PaginationHelper<Foo>();
        paginationHelper = myDao.search(true, param1, param2, param3, pageRequest, paginationHelper);
        paginationHelper = myDao.search(false, param1, param2, param3, pageRequest, paginationHelper);

        return wpRet;
    }

DAO

@Override
    @Transactional
    public PaginationHelper<Foo> search(boolean flCount, String param1, String param2, boolean param3, 
            Pageable pageRequest, PaginationHelper<WrapperDiscussioneForumEPT> paginationHelper) {

        Session session = sessionManager.getFilteredSession(FilterType.NONE);

        String hql = "FROM " + Foo.class.getName() + " f WHERE f.param1 = param1 AND f.param2 = param2 AND f.param3 = param3";

        Query q = session.createQuery(hql);

        q.setParameter("param1", param1);
        q.setParameter("param2", param2);
        q.setParameter("param3", param3);

        if(flCount)
        {
            long numElementi = (long)q.uniqueResult();
            paginationHelper.setNumElementiTotali(numElementi);
        }
        else
        {
            q.setFirstResult(pageRequest.getPageNumber()*pageRequest.getPageSize()).setMaxResults(pageRequest.getPageSize());
            retLst =  q.list();
            paginationHelper.setPage(retLst);
        }

        return paginationHelper;
    }

So in short, the sole reason for the PaginationHelper existence is to avoid writing two methods very similar to access the data from the DBMS. Instead, just one method will do the count or the page retrieve based on a flag passed. I fear this is not a good approach. And I fear is not a good approach to instantiate a paginationHelper instance and pass it to both the two calls of the DAo search method.

Our stack:

  • Spring -> 4.1.1.RELEASE
  • Hibernate -> 4.3.5.Final
  • Spring Security -> 3.2.4.RELEASE
  • spring-data-jpa -> 1.8.2.RELEASE
  • spring-data-commons -> 1.10.2.RELEASE
\$\endgroup\$
4
  • \$\begingroup\$ It seems that you just use the PaginationHelper class only as a data transfer object. I do not see any other use. I would just create two separate method in my dao(select and count) and have the Service layer call them explicitly and then return a Page object. \$\endgroup\$ Feb 1, 2018 at 17:35
  • \$\begingroup\$ @PanayiotisPoularakis, won't that end in an unneded code duplication, since the most of the query will be the same? Thanks for your comment! \$\endgroup\$
    – frankieta
    Feb 13, 2018 at 9:37
  • \$\begingroup\$ @PanayiotisPoularakis What is meant by Data Transfer Object? \$\endgroup\$
    – sofs1
    Apr 1, 2018 at 8:03
  • 1
    \$\begingroup\$ @user3705478 it is a pattern (some argue that is an anti-pattern stackoverflow.com/questions/1440952/…) which introduces POJOs with sole scope to carry information between interfaces (most commonly between client-server calls) \$\endgroup\$ Apr 2, 2018 at 9:33

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.