【发布时间】:2017-11-05 18:05:47
【问题描述】:
我在使用 MS SQL 2012 的休眠方言时遇到问题。我有一个使用 org.h2.Driver 正常工作的过滤器,它告诉我我有
org.springframework.data.jpa.domain.Specification<T> 定义正确。
H2方言返回查询:
SELECT
requesthea0_.DIG_REQUEST_ID AS DIG_REQU1_3_,
requesthea0_.ASSIGNEE AS ASSIGNEE8_3_,
requesthea0_.COMMENT AS COMMENT2_3_,
requesthea0_.CREATED_BY AS CREATED_9_3_,
requesthea0_.CREATED_DATE AS CREATED_3_3_,
requesthea0_.DECLINE_ID AS DECLINE10_3_,
requesthea0_.DEPARTMENT_ID AS DEPARTM11_3_,
requesthea0_.EMERGENCY_FLAG AS EMERGENC4_3_,
requesthea0_.LOCATION_ID AS LOCATIO12_3_,
requesthea0_.MODIFIED_BY AS MODIFIE13_3_,
requesthea0_.MODIFIED_DATE AS MODIFIED5_3_,
requesthea0_.PRIORITY_ID AS PRIORIT14_3_,
requesthea0_.REQUESTED_COMPLETION_DATE AS REQUESTE6_3_,
requesthea0_.RESOLUTION_ID AS RESOLUT15_3_,
requesthea0_.STATUS_ID AS STATUS_16_3_,
requesthea0_.TITLE AS TITLE7_3_
FROM
DBO.DIG_REQUEST requesthea0_
LEFT OUTER JOIN
DBO.DIG_PICK_LISTS requestpri1_
ON
requesthea0_.PRIORITY_ID=requestpri1_.ID
LEFT OUTER JOIN
DBO.DIG_PICK_LISTS requeststa2_
ON
requesthea0_.STATUS_ID=requeststa2_.ID
WHERE
requesthea0_.STATUS_ID IN (?)
ORDER BY
requesthea0_.REQUESTED_COMPLETION_DATE ASC,
requestpri1_.ID ASC,
requeststa2_.ID ASC,
requesthea0_.DIG_REQUEST_ID ASC limit ?
而使用 org.hibernate.dialect.SQLServer2012Dialect 创建一个查询:
SELECT TOP(?)
requesthea0_.DIG_REQUEST_ID AS DIG_REQU1_3_,
requesthea0_.ASSIGNEE AS ASSIGNEE8_3_,
requesthea0_.COMMENT AS COMMENT2_3_,
requesthea0_.CREATED_BY AS CREATED_9_3_,
requesthea0_.CREATED_DATE AS CREATED_3_3_,
requesthea0_.DECLINE_ID AS DECLINE10_3_,
requesthea0_.DEPARTMENT_ID AS DEPARTM11_3_,
requesthea0_.EMERGENCY_FLAG AS EMERGENC4_3_,
requesthea0_.LOCATION_ID AS LOCATIO12_3_,
requesthea0_.MODIFIED_BY AS MODIFIE13_3_,
requesthea0_.MODIFIED_DATE AS MODIFIED5_3_,
requesthea0_.PRIORITY_ID AS PRIORIT14_3_,
requesthea0_.REQUESTED_COMPLETION_DATE AS REQUESTE6_3_,
requesthea0_.RESOLUTION_ID AS RESOLUT15_3_,
requesthea0_.STATUS_ID AS STATUS_16_3_,
requesthea0_.TITLE AS TITLE7_3_
FROM
DBO.DIG_REQUEST requesthea0_
LEFT OUTER JOIN
DBO.DIG_PICK_LISTS requestpri1_
ON
requesthea0_.PRIORITY_ID=requestpri1_.ID
LEFT OUTER JOIN
DBO.DIG_PICK_LISTS requeststa2_
ON
requesthea0_.STATUS_ID=requeststa2_.ID
WHERE
requesthea0_.STATUS_ID IN ()
ORDER BY
requesthea0_.REQUESTED_COMPLETION_DATE ASC,
requestpri1_.ID ASC,
requeststa2_.ID ASC,
requesthea0_.DIG_REQUEST_ID ASC
没有参数标记“?”出于某种原因。
这是在 MS SQL 服务器上,用于Select @@version 返回
Microsoft SQL Server 2012 - 11.0.2100.60 (X64) Feb 10 2012 19:39:15 Copyright (c) Microsoft Corporation Express Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
我有两个 mssql 依赖项:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.1.0.jre7</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
<scope>runtime</scope>
</dependency>
示例堆栈跟踪:
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:492)
at org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:50)
...
at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
... 162 common frames omitted
更新:为了完整起见,我还尝试将 net.sourceforge.jtds.jdbc.Driver 作为备用驱动程序,但仍然遇到相同的错误。
啊哈,控制台出现了另一个错误。我们未能获取 ManyToOne 孩子,然后 JPA 显然不知道如何处理 NULL:
org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [SELECT ID, LIST_NAME, SHORT_TEXT, LONG_TEXT, SEQUENCE, ALTERNATE_SEQUENCE FROM dbo.DIG_PICK_LISTS WHERE ID = ?]; SQL state [null]; error code [0]; The requested operation is not supported on forward only result sets.; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: The requested operation is not supported on forward only result sets.
所以根本问题是 JDBC extractData 方法使用了 SqlServer 不支持的 ResultSet.first() 方法。
@Override
public PickListItem extractData(ResultSet rs) throws SQLException, DataAccessException
{
PickListItem pickListItem = new PickListItem();
rs.first();
pickListItem.setId(rs.getLong("ID"));
pickListItem.setListName(rs.getString("LIST_NAME"));
pickListItem.setShortText(rs.getString("SHORT_TEXT"));
pickListItem.setLongText(rs.getString("LONG_TEXT"));
pickListItem.setSequence(rs.getDouble("SEQUENCE"));
pickListItem.setAlternateSequence(rs.getDouble("ALTERNATE_SEQUENCE"));
return PickListSubTypeFactory.createSubType(pickListItem);
}
【问题讨论】:
标签: java sql-server spring hibernate jpa