使用Hibernate在JPA中分页本机SQL查询,没有错误

时间:2012-01-30 23:17:36

标签: java hibernate jpa nativequery

感谢您的关注,并抱歉mi英语:S

我正在使用JPA 2.0和Hibernate 4.X来做一些sql本地查询。 Te代码非常简单:

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 个答案:

答案 0 :(得分:4)

这是在Hibernate中完成分页的方式 - 使用其Dialect实现。 Dialect的API如下:它将SQL查询作为分页和范围信息,并生成产生所需行范围的SQL语句。

如果是Oracle Dialect,它可以使用ROWNUM,无需修改原始查询。在例如DB2或SQL Server方言需要显着改变您的查询(包括但不限于在输出中添加其他列)才能为您过滤所需的范围。

最后一件事 - 为什么你的第一页或结果是不同的。 SQL允许(取决于实现)像SELECT TOP n这样的结构,因此范围[0, n][m, n]的查询通常是不同的。