Hibernate:使用setFirstResult和setMaxResult进行分页

时间:2015-10-28 16:44:27

标签: java hibernate pagination

我正在开发一个使用Hibernate作为ORM框架的Java EE项目。 为了对查询结果进行分页,我使用.setFirstResult和.setMaxResult方法(Criteria API)。

问题是第一页正确显示但是当我转到第2页时,我显示的第一个结果与第一页的最后结果相同。

通过将日志记录级别切换到调试,我设法捕获Hibernate构建的SQL查询。他们是:

-- First page query (results from 1 to 10)
select * from ( select this_.DT_FINE_VAL as DT1_5_0_, this_.DT_INI_VAL as DT2_5_0_, this_.CD_TIPO_PERIODO as CD3_5_0_, this_.DT_AGGIORNAMENTO as DT4_5_0_, this_.DT_INSERIMENTO as DT5_5_0_, this_.CD_USERID_AGG as CD6_5_0_, this_.CD_USERID_INS as CD7_5_0_ from GPER0_POVS2.T_POVS2_PERIODI_FUNZ this_ order by this_.CD_TIPO_PERIODO desc ) where rownum <= 10;

-- Second page query (results from 11 to 20)
select * from ( select row_.*, rownum rownum_ from ( select this_.DT_FINE_VAL as DT1_5_0_, this_.DT_INI_VAL as DT2_5_0_, this_.CD_TIPO_PERIODO as CD3_5_0_, this_.DT_AGGIORNAMENTO as DT4_5_0_, this_.DT_INSERIMENTO as DT5_5_0_, this_.CD_USERID_AGG as CD6_5_0_, this_.CD_USERID_INS as CD7_5_0_ from GPER0_POVS2.T_POVS2_PERIODI_FUNZ this_ order by this_.CD_TIPO_PERIODO desc ) row_ where rownum <= 20) where rownum_ > 10;

似乎第二个查询是&#34;错误&#34;。 我使用Oracle作为DBMS。 这可能是一个Hibernate错误吗?有人能帮助我吗?

感谢。

编辑: 这是代码:

Session currentSession = getCurrentSession();
Criteria criteria = currentSession.createCriteria(PeriodoFunz.class);
criteria.setResultTransformer(Criteria.ROOT_ENTITY);
Order order = paginationInfo.isAsc() ? Order.asc(paginationInfo.getOrderBy()) : Order.desc(paginationInfo.getOrderBy());
criteria.addOrder(order);
....
criteria = criteria.setFirstResult(paginationInfo.getFromRecord()).setMaxResults(paginationInfo.getPageSize());
List<PeriodoFunz> result = criteria.list();

2 个答案:

答案 0 :(得分:4)

您的订单条件似乎导致SQL查询不是 stable (以不同的顺序为查询返回相同的结果行)。

您可以通过为唯一属性添加第二个订单条件来避免这种情况,例如: ID:

Order order = paginationInfo.isAsc() ? Order.asc(paginationInfo.getOrderBy()) : Order.desc(paginationInfo.getOrderBy());
criteria.addOrder(order);
Order orderById = paginationInfo.isAsc() ? Order.asc("id") : Order.desc("id");
criteria.addOrder(orderById);

答案 1 :(得分:0)

阅读此 https://blogs.oracle.com/oraclemagazine/on-rownum-and-limiting-results

使用此分页查询的重要一件事是ORDER BY语句应按唯一的顺序排序。