在使用Hibernate的JPA时进行本地SQL查询分页,避免出现错误。

3
感谢您的关注,非常抱歉我的英语不太好:S
我正在使用JPA 2.0与Hibernate 4.X进行一些 SQL 原生查询。 代码非常简单:
private void doIt() throws Exception {
        EntityManager em = getEntityManager();
        Query q = em.createNativeQuery("A very simple native query, which return no entities, but collections of arrays");
        q.setFirstResult(0);
        q.setMaxResults(5);
        Collection<Object> results = q.getResultList();
        System.out.println("1"); //Means page 1
        for (Object elem : results) {
            String line = "";
            Object[] row = (Object[]) elem;
            for (Object object : row) {
                if(object==null){
                    object="null";
                }
                line += object +"("+object.getClass()+")"+ ",";
            }
            System.out.println(row.length + " " + line);

        }


        em = getEntityManager();
        q = em.createNativeQuery("The same simple native query, which return no entities, but collections of arrays");
        q.setFirstResult(5);
        q.setMaxResults(5);
        results = q.getResultList();
        System.out.println("2"); //Means page 2
       for (Object elem : results) {
            String line = "";
            Object[] row = (Object[]) elem;
            for (Object object : row) {
                if(object==null){
                    object="null";
                }
                line += object +"("+object.getClass()+")"+ ",";
            }
            System.out.println(row.length + " " + line);

        }


        em = getEntityManager();
        q = em.createNativeQuery("The same simple native query, which return no entities, but collections of arrays");
        q.setFirstResult(10);
        q.setMaxResults(5);
        results = q.getResultList();
        System.out.println("3"); //Means page 3
        for (Object elem : results) {
            String line = "";
            Object[] row = (Object[]) elem;
            for (Object object : row) {
                if(object==null){
                    object="null";
                }
                line += object +"("+object.getClass()+")"+ ",";
            }
            System.out.println(row.length + " " + line);

        }
    }

而我的结果是这样的:
1 
data1,data2,...,data-n        -->I need this output
data1,data2,...,data-n
data1,data2,...,data-n
data1,data2,...,data-n
data1,data2,...,data-n

2
data1,data2,...,data-n,6      -->OMG! lol
data1,data2,...,data-n,7
data1,data2,...,data-n,8
data1,data2,...,data-n,9
data1,data2,...,data-n,10

3
data1,data2,...,data-n,11
data1,data2,...,data-n,12
data1,data2,...,data-n,13
data1,data2,...,data-n,14
data1,data2,...,data-n,15

简而言之,第一页的输出每行有n个项目(这是我期望的输出),但第二和第三页有n+1个项目,额外的项目似乎是带来的行号码。
有人遇到了相同的问题吗?我在Hibernate文档中搜索过,但无法解决这个“有趣的:@”问题。
此代码使用Toplink执行,并且没有这个问题。
非常感谢! :)
1个回答

5
这是Hibernate实现分页的方式,使用其Dialect实现。Dialect的API如下:它接受要分页的SQL查询和范围信息,并生成产生所需行范围的SQL语句。
在Oracle Dialect的情况下,它可以使用ROWNUM而不需要修改原始查询。在例如DB2或SQL Server的情况下,方言需要显著更改您的查询(包括但不限于在输出中添加附加列),以便能够为您过滤所需的范围。
最后一件事——为什么您的第一页或结果不同。 SQL允许(取决于实现)构造如SELECT TOP n的语句,因此范围[0,n][m,n]的查询通常是不同的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接