HANA Cloud JDBC驱动不支持closeOnCompletion()?MyBatis Cursor兼容疑问
MyBatis Cursor 与HANA配合使用时的兼容性问题
我尝试用MyBatis的Cursor接收HANA查询结果,代码如下:
@Mapper @Repository public interface XXXRepository { org.apache.ibatis.cursor.Cursor<XXXEntity> getData(); }
执行时出现如下错误:
Cause: com.sap.db.jdbc.exceptions.SQLFeatureNotSupportedExceptionSapDB: Method closeOnCompletion() of Statement is not supported. ; Method closeOnCompletion() of Statement is not supported. ; nested exception is com.sap.db.jdbc.exceptions.SQLFeatureNotSupportedExceptionSapDB: Method closeOnCompletion() of Statement is not supported. at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:96) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:79) at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:88) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440) at com.sun.proxy.$Proxy91.selectCursor(Unknown Source) at org.mybatis.spring.SqlSessionTemplate.selectCursor(SqlSessionTemplate.java:199) at org.apache.ibatis.binding.MapperMethod.executeForCursor(MapperMethod.java:167) at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:84) at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:145) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) at com.sun.proxy.$Proxy251.getReqSlipPrintCount(Unknown Source) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) at com.sun.proxy.$Proxy252.getReqSlipPrintCount(Unknown Source)
请问MyBatis的Cursor是否不被HANA支持?使用的JDBC驱动版本为com.sap.cloud.db.jdbc:ngdbc:2.11.14。
问题分析与解决方案
这个问题并非MyBatis Cursor本身不被HANA支持,而是HANA的ngdbc驱动2.11.14版本未实现JDBC 4.1规范中的Statement.closeOnCompletion()方法,而MyBatis在处理Cursor逻辑时会调用该方法,导致抛出不支持的异常。
可行解决方案:
- 升级JDBC驱动版本:ngdbc驱动2.15.x及以上版本已经修复了这个兼容性问题,实现了
closeOnCompletion()方法,升级后即可正常使用Cursor。 - 替换结果接收方式:如果暂时无法升级驱动,可以改用
List<XXXEntity>接收查询结果,这种方式无需依赖Cursor的特定逻辑,兼容性更好,但需要注意超大数据集可能带来的内存占用问题。 - 自定义MyBatis扩展:通过自定义
StatementHandler拦截器,绕过closeOnCompletion()方法的调用,但这种方式需要对MyBatis底层逻辑有一定了解,实现复杂度较高。
内容的提问来源于stack exchange,提问作者Anson
相关产品推荐
相关产品推荐

