H2数据库是否支持滚动

时间:2015-07-25 14:34:53

标签: java hibernate jdbc h2

我正在尝试使用滚动来遍历表的所有记录。 代码和查询非常简单。

// a really really simple query
String hql = "from " + MyTable.class.getSimpleName();

Query query = session.createQuery(hql);
query.setReadOnly(true);
query.setFetchSize(Integer.MIN_VALUE);

// An exception is caused here
ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY);

// My code would have continued by iterating the results
while (results.next()) { ... }

但这导致GenericJDBCException“无法使用滚动执行查询”

org.hibernate.exception.GenericJDBCException: could not execute query using scroll
  at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
  at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
  at org.hibernate.loader.Loader.scroll(Loader.java:2632)
  at org.hibernate.loader.hql.QueryLoader.scroll(QueryLoader.java:557)
  at org.hibernate.hql.internal.ast.QueryTranslatorImpl.scroll(QueryTranslatorImpl.java:408)
  at org.hibernate.engine.query.spi.HQLQueryPlan.performScroll(HQLQueryPlan.java:268)
  at org.hibernate.internal.SessionImpl.scroll(SessionImpl.java:1346)
  at org.hibernate.internal.QueryImpl.scroll(QueryImpl.java:89)
  ...
Caused by: org.h2.jdbc.JdbcSQLException: Invalid value "-2147483648" for parameter "rows" [90008-172]
  at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
  at org.h2.message.DbException.get(DbException.java:169)
  at org.h2.message.DbException.getInvalidValueException(DbException.java:215)
  at org.h2.jdbc.JdbcStatement.setFetchSize(JdbcStatement.java:399)
  at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setFetchSize(NewProxyPreparedStatement.java:1722)
  at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1886)
  at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1836)
  at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1816)
  at org.hibernate.loader.Loader.scroll(Loader.java:2595)
  ... 15 more

H2数据库是否可能不支持滚动,或者我做错了什么?

1 个答案:

答案 0 :(得分:2)

以下行是错误的:

query.setFetchSize(Integer.MIN_VALUE);

Integer.MIN_VALUE,是告诉JDBC使用流式传输的技巧。但是这个技巧(仅)支持MySQL,而不是H2。

来自the MySQL documentation

  

仅向前只读结果集与提取大小Integer.MIN_VALUE 的组合可作为驱动程序逐行传输结果集的信号。在此之后,将逐行检索使用该语句创建的任何结果集。

堆栈跟踪显示异常“参数行的无效值-2147483648。”此值正好为-2 ^ 31(= Integer.MIN_VALUE)。 H2不知道如何处理负的提取大小并抛出异常。

结论:滚动适用于H2数据库。