@Override
    public List<T> search(P params, OrderPage orderPage) {
        // total rowcount
        orderPage.setRowcount((Integer) (addRestrictions(
                getSession().createCriteria(this.persistentClass), params)
                .setProjection(Projections.rowCount()).uniqueResult()));

        // pages list
        Criteria c = addRestrictions(getSession().createCriteria(
                this.persistentClass), params);
        orderPage.applyPage(c);
        orderPage.applyOrder(c);

        return c.list();
    }

    /**
     * template method for search
     *
     * @param c
     * @param params
     * @return
     */
    protected Criteria addRestrictions(Criteria c, P params) {
        return c;
    }

위 코드에서 중복이 보이시나요? 안 보이신 다구요?

    @Override
   public List<T> search(P params, OrderPage orderPage) {
       // total rowcount
       orderPage.setRowcount((Integer) (addRestrictions(

               getSession().createCriteria(this.persistentClass), params)

               .setProjection(Projections.rowCount()).uniqueResult()));

       // pages list
       Criteria c = addRestrictions(getSession().createCriteria(

               this.persistentClass), params)
;
       orderPage.applyPage(c);
       orderPage.applyOrder(c);

       return c.list();
   }

어떤가요. 중복 이죠? 그러나..

Criteria c = addRestrictions(getSession().createCriteria(

               this.persistentClass), params)
;
orderPage.setRowcount((Integer) (c.setProjection(Projections.rowCount()).uniqueResult()));
orderPage.applyPage(c);
orderPage.applyOrder(c);

대강 이런 식으로 리팩터링 해보면 하이버네이트는 요상한 쿼리와 함께 에러를 뱉어냅니다.

전체 Row 갯수를 반환하는 Criteria(쿼리는 select count(*).. )이런식으로 시작)를 다시 Order와 Page 처리를 할 때 사용하면 이상한 쿼리(select count(*).. order by ... 이게 이상한 이유는 order by에서 사용한 컬럼이 group by에 있어야 하는데 groupd by를 정의한 적이 없거니와, 사실 두 번째 쿼리는 count(*)가 없어야 하는데 앞에서 만들어둔 Criteria에 이어 붙인 꼴이 되어서 이상해졌습니다.)가 되버립니다.

중복처럼 보이지만 제거하면 코드가 깨지는... 요상한 경우. 이거 어떻게 처리하는게 좋을까요? 전 요리 조리 해보다가 그냥 뒀습니다.