Hibernate with sql server retrieving data Encountered unexpected unknown token

时间:2018-07-24 10:19:08

标签: java sql-server hibernate c3p0 mssql-jdbc

Using c3p0 0.9.2.1, hibernate 4.2.21, JBoss AS 7.1.1 and connecting with Microsoft SQL Server 2014 - 12.0.2000.8 (X64).

mssql-jdbc 6.2.2 (I tested 6.4.0 for doubt but we are using 6.2.2) is used for JRE7 support.

Scenario

Retrieving data from a table as multiple rows but NOT at once. It's simply a loop and each time a row retrieved and finally they put in HashMap.

Problem & Output

After long investigation and debugging I found out that the problem scope related with two columns in the table. One is VARBINARY(MAX) called signature and the other is VARCHAR(1024) called status. If both of these columns have a value on a row, this exception occurs on retrieving the next row. If any of them is set to null, all is good. No matter the length of the value in them.

Tries so far

  • Changing the columns order making the VARCHARcolumn is the last cloumn
  • Changing the columns order making the VARBINARY column is the last cloumn
  • Changing the length (VARBINARY to 8000 and VARCHAR to 50)
  • Setting values on other columns with similar or larger length
  • Logging org.hibernate.session object methods isConnected() and isOpen() and until the exception is thrown, the output was always true for both

Questions

What does that exception means ? Specially that sql server logging doesn't show anything about it !!

Why it's happening and what might be the cause of this ?

   18:53:12,294 SEVERE [com.microsoft.sqlserver.jdbc.internals.TDS.TOKEN]
(http-localhost-127.0.0.1-8080-6) ConnectionID:24 ClientConnectionId:
5bbf35a7-2a3c-4fb5-845a-bbd81d2739ef: getNextResult: Encountered
unexpected unknown token (0x1)
    18:53:12,296 SEVERE [com.microsoft.sqlserver.jdbc.internals.TDS.Reader]
(http-localhost-127.0.0.1-8080-6) ConnectionID:24 ClientConnectionId:
5bbf35a7-2a3c-4fb5-845a-bbd81d2739ef got unexpected value in TDS
response at offset:1158
    18:53:12,300 ERROR [stderr] (http-localhost-127.0.0.1-8080-6) java.lang.reflect.InvocationTargetException

    18:53:12,300 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    18:53:12,301 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

    18:53:12,301 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

    18:53:12,302 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at java.lang.reflect.Method.invoke(Unknown Source)
.
.
    18:53:12,304 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)

    18:53:12,305 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)

    18:53:12,306 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)

    18:53:12,307 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)

    18:53:12,308 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)

    18:53:12,309 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

    18:53:12,309 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)

    18:53:12,310 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)

.
.
    18:53:12,312 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)

    18:53:12,312 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)

.
.

    18:53:12,314 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)

    18:53:12,314 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)

.
.   
    18:53:12,316 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)

    18:53:12,316 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)

    18:53:12,317 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:101)

    18:53:12,318 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)

    18:53:12,318 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)

    18:53:12,319 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)

    18:53:12,320 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)

    18:53:12,320 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153)

    18:53:12,321 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)

    18:53:12,322 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

    18:53:12,322 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

    18:53:12,323 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)

    18:53:12,324 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)

    18:53:12,325 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)

    18:53:12,326 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)

    18:53:12,327 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at java.lang.Thread.run(Unknown Source)

    18:53:12,328 ERROR [stderr] (http-localhost-127.0.0.1-8080-6) Caused by: org.hibernate.exception.GenericJDBCException: could not
extract ResultSet

    18:53:12,329 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)

    18:53:12,330 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:124)

    18:53:12,332 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)

    18:53:12,333 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:88)

    18:53:12,335 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.loader.Loader.getResultSet(Loader.java:2062)

    18:53:12,336 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1859)

    18:53:12,337 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1838)

    18:53:12,338 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.loader.Loader.doQuery(Loader.java:906)

    18:53:12,339 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:348)

    18:53:12,340 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.loader.Loader.doList(Loader.java:2550)

    18:53:12,340 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.loader.Loader.doList(Loader.java:2536)

    18:53:12,341 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2366)

    18:53:12,342 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.loader.Loader.list(Loader.java:2361)

    18:53:12,342 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:495)

    18:53:12,343 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:357)

    18:53:12,343 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:198)

    18:53:12,344 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1230)

    18:53:12,345 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)

    18:53:12,345 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.internal.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:909)

.
.

    18:53:12,350 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   ... 38 more

    18:53:12,351 ERROR [stderr] (http-localhost-127.0.0.1-8080-6) Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The
connection is closed.

    18:53:12,351 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:228)

    18:53:12,352 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at com.microsoft.sqlserver.jdbc.SQLServerConnection.checkClosed(SQLServerConnection.java:1007)

    18:53:12,353 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at com.microsoft.sqlserver.jdbc.SQLServerStatement.checkClosed(SQLServerStatement.java:1024)

    18:53:12,353 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:198)

    18:53:12,354 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:401)

    18:53:12,355 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:116)

    18:53:12,355 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79)

    18:53:12,356 ERROR [stderr] (http-localhost-127.0.0.1-8080-6)   ... 59 more

3 个答案:

答案 0 :(得分:1)

我认为这是一个Hibernate varbinary colum编码问题,需要进行如下更改 该表具有:ENGINE = InnoDB DEFAULT CHARSET = utf8;  休眠属性具有:

   <prop key="hibernate.connection.useUnicode">true</prop>
   <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
   <prop key="hibernate.connection.charSet">UTF-8</prop>

https://www.experts-exchange.com/questions/28131390/Hibernate-varbinary-colum-encoding-issue.html

答案 1 :(得分:1)

以下内容解决了检索问题,并在某些提交行(插入和刷新)中显示了该问题。从数据库向驱动程序检索数据似乎太多了,因为VARBINARY映射到Java中的LOB,并且由于是大型对象而打开了流,该流不会很快关闭,直到另一个检索击中数据库和驱动程序才导致此问题。这是解决方法

如果使用 cursor JDBC属性检索数据,解决了该问题的解决方案。正如GitHub上的Microsoft团队所清除的那样,直接从JDBC驱动程序抛出的异常并提供了有效的示例代码,直到现在,我一直无法复制问题。

使用游标只是将selectMethod=cursor添加到JDBC URL。要完全了解此选项的作用以及它如何影响数据的检索,特别是LOB类型,请参阅thisthis文档和文章。

摘自Microsoft文档

  

selectMethod,字符串,[“直接” | “光标”],默认值为direct

     

如果此属性设置为“ cursor”,则为   在连接上为TYPE_FORWARD_ONLY创建的每个查询,以及   CONCUR_READ_ONLY游标。通常仅在以下情况下才需要此属性   应用程序生成的大型结果集不能完全   包含在客户端内存中。当此属性设置为“光标”时,   客户端中仅保留有限数量的结果集行   记忆。

     

默认行为是将所有结果集行保留在   客户端内存。当   应用程序正在处理所有行。

来自问答文章

  

要考虑的一些问题:

     
      
  1. 应用程序是否使用可滚动结果集,仅转发结果集还是两者都使用?如果可滚动,它们是否获取所有   数据还是只滚动到并获取一些行?
  2.   
  3. 生成的结果集是大还是小?这包括行数和列数以及其中包含的数据(即   有没有LOB)?
  4.   
  5. 应用程序是在执行事务工作还是仅在自动提交模式下运行?
  6.   
  7. 应用程序一次连接一次是否打开了多个结果集?
  8.   
     

这些问题的答案应有助于确定哪种联系   参数最适合该应用程序。首先请注意   完全消除了您的连接网址中的选项是   与将选项设置为“ direct”相同,因为默认为“ direct”   设置。

     

接下来,看看我们对JDBC中此选项的描述   用户指南和参考手册。以下是一些关键点   此说明:

     

驱动程序提示,确定驱动程序是否请求   Select语句的数据库游标。的性能和行为   驱动程序受此属性影响,该属性定义为提示   因为驾驶员不一定总是能够满足要求   方法。

     

如果设置为direct(缺省值),则数据库服务器发送完整的信息。   在响应驾驶员对驾驶员的单一响应中设置的结果   查询。如果请求,则不会创建服务器端数据库游标   结果集类型是仅转发结果集。通常,响应是   驱动程序未缓存。使用此方法,驱动程序必须处理   提交另一个查询之前,对查询的整个响应。如果   提交另一个查询(对同一查询使用不同的语句   例如连接),驱动程序将响应缓存到第一个   提交第二个查询之前查询。通常,直接方法   比游标方法表现更好。

     

如果设置为游标,则请求服务器端游标。返回时   前向结果集,行从服务器中检索   块。 setFetchSize()方法可用于控制   仅向前结果集时为每个请求检索的行   返回。性能测试表明,仅返回时   结果集,Statement.setFetchSize()的值显着   影响性能。没有简单的规则来确定   应该使用的setFetchSize()值。我们建议您   试验不同的setFetchSize()值以确定哪个   值可为您的应用程序提供最佳性能。游标   该方法对于产生大量数据的查询很有用,   尤其是如果使用了多个开放结果集。

     

请参考以下“性能注意事项”部分的节选   用户指南和参考手册:

     

SelectMethod:在大多数情况下,使用服务器端数据库游标   对性能产生负面影响。但是,如果以下变量   对于应用程序是正确的,此属性的最佳设置是   游标,这意味着使用服务器端数据库游标:

     
      
  • 您的应用程序包含可检索大量数据的查询。
  •   
  • 您的应用程序在处理或关闭先前的大型结果集之前执行一条SQL语句,并执行多次。
  •   
  • 应用程序返回的大结果集使用仅前向游标。
  •   

答案 2 :(得分:1)

请注意,一旦查询了数据,就会将blob作为代理进行检索,并且可以从中读取流。在关闭连接之前,您可能需要检查是否从中读取了数据(可能是byte [])。当然,根据您的情况,您似乎有时会以某种方式关闭连接,这种方式尚不清楚,但读取要保存在内存中的数据而不是仅保留代理可以确保关闭会话/连接的安全不会导致此类问题代理,因为已经读取了数据。

在完成所有先前的数据检索之前检索大量数据并执行查询的情况下,游标解决方案很有用,这可能是这里的问题。因此,这也被视为另一种选择,无需在内存中急切加载数据并且完全避免代理。