java.sql.SQLException: ResultSet 只能向前访问

java.sql.SQLException: ResultSet may only be accessed in a forward direction

我有一个程序可以在 MySQL 数据库上顺利运行。现在为了外部需求,我必须切换到 SQL 服务器。多亏了 Hibernate,切换很顺利,除了错误:

java.sql.SQLException: ResultSet may only be accessed in a forward direction.

我在对从数据库中获取的数据执行自定义分页时遇到此错误。下面是一个尝试获取数据库中存储的用户并对其进行分页的最小示例(以下示例假定 table 中至少有 3 行)。

自定义分页:

import org.hibernate.Query;
import org.hibernate.Session;

public class newMain1 {

    public static void main(String[] args) {
        getList(1, getSession());
        getList(2, getSession());
    }

    private static void getList(int page, Session s) {
        int rowsPerPage = 2;
        String hql = "FROM User u ";

            try {
                Query query = s.createQuery(hql);
                int start = (page - 1) * rowsPerPage;
                query.setFirstResult(start);
                query.setMaxResults(rowsPerPage);
                //line that throws exception when int page is 2
                query.list();
                //line that throws exception when int page is 2
            } finally {
                if (s.isOpen()) {
                    s.close();
                }
            }
    }

    private Session getSession(){
        //gets org.hibernate.Session
    }
}

用户 Java POJO:

public class User {    
    private Long id;
    private String username;
    private String password;
    private String email;

    public User() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

SQL 服务器的用户 table:

CREATE TABLE [USER] (
  ID bigint NOT NULL,
  USERNAME varchar(150) NOT NULL UNIQUE,
  PASSWORD varchar(150) NOT NULL,
  EMAIL varchar(150) NOT NULL UNIQUE,
  PRIMARY KEY (ID)
);

用户 POJO 的 Hibernate 映射:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="product.model.User" table="USER">
        <id column="ID" name="id" type="long">
            <generator class="increment"/>
        </id>
        <property column="EMAIL" name="email" type="string"/>
        <property column="USERNAME" name="username" type="string"/>
        <property column="PASSWORD" name="password" type="string"/>
    </class>
</hibernate-mapping>

休眠配置 xml:

<session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
    <property name="hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=myDB;prepareSQL=3;sendStringParametersAsUnicode=false;</property>
    <property name="hibernate.connection.username">sa</property>
    <property name="hibernate.connection.password">myPassword</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.globally_quoted_identifiers">true</property>
    <mapping resource="product_mapping/user.hbm.xml"/>
  </session-factory>

我正在使用 SQL Server 2012、JDK 1.8、Hibernate 4.0。1.Final、jtds 驱动程序 1.3.1

请注意 getList(1, getSession()) 不会抛出异常,而 getList(2, getSession()) 会。

经过几个小时的调查,我发现这个问题是由于我使用的休眠方言引起的。

考虑到我需要使用的休眠版本,正确的方言是:org.hibernate.dialect.SQLServer2008Dialect

来源:https://forum.hibernate.org/viewtopic.php?p=2452163