ibatis执行存储过程,java.lang.ArrayIndexOutOfBoundsException: 0

在项目开发中遇到一个问题,ibatis执行存储过程时报错

<procedure id="insertStatisticsResult_settle" parameterClass="String"> 

  <![CDATA[

     {call proc_stats_$statisticsType$()}

  ]]>

</procedure>

 

错误日志如下:

 

--- The error occurred in com/aspire/prm/dmplt/statistics/dao/ibatis/maps/StatisticsSQL.xml.  
--- The error occurred while applying a parameter map.  
--- Check the insertStatisticsResult_settle-InlineParameterMap.  
--- Check the output parameters.  
--- Cause: java.lang.ArrayIndexOutOfBoundsException: 0; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred in com/aspire/prm/dmplt/statistics/dao/ibatis/maps/StatisticsSQL.xml.  
--- The error occurred while applying a parameter map.  
--- Check the insertStatisticsResult_settle-InlineParameterMap.  
--- Check the output parameters.  
--- Cause: java.lang.ArrayIndexOutOfBoundsException: 0
Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred in com/aspire/prm/dmplt/statistics/dao/ibatis/maps/StatisticsSQL.xml.  
--- The error occurred while applying a parameter map.  
--- Check the insertStatisticsResult_settle-InlineParameterMap.  
--- Check the output parameters.  
--- Cause: java.lang.ArrayIndexOutOfBoundsException: 0
	at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeUpdate(GeneralStatement.java:94)
	at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.insert(SqlMapExecutorDelegate.java:447)
	at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.insert(SqlMapSessionImpl.java:82)
	at org.springframework.orm.ibatis.SqlMapClientTemplate$9.doInSqlMapClient(SqlMapClientTemplate.java:370)
	at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:194)
	at org.springframework.orm.ibatis.SqlMapClientTemplate.insert(SqlMapClientTemplate.java:368)
	at com.aspire.prm.dmplt.statistics.dao.ibatis.StatisticsDaoImpl.doStatistics(StatisticsDaoImpl.java:63)
	at com.aspire.prm.dmplt.statistics.biz.impl.StatisticsBizImpl.doStatistics(StatisticsBizImpl.java:64)
	at com.aspire.prm.app.statistics.manager.impl.StatisticsManagerImpl.doStatistics(StatisticsManagerImpl.java:62)
	at com.aspire.prm.app.statistics.manager.impl.StatisticsManagerImpl.doStatistics(StatisticsManagerImpl.java:50)
	at com.aspire.prm.app.statistics.manager.impl.StatisticsManagerImpl$$FastClassByCGLIB$$c1412355.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:696)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:631)
	at com.aspire.prm.app.statistics.manager.impl.StatisticsManagerImpl$$EnhancerByCGLIB$$7f8146a6.doStatistics(<generated>)
	at com.aspire.prm.app.statistics.job.StatisticsJob.execute(StatisticsJob.java:40)
	at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
	at com.ibatis.sqlmap.engine.exchange.PrimitiveDataExchange.setData(PrimitiveDataExchange.java:51)
	at com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMap.refreshParameterObjectValues(BasicParameterMap.java:140)
	at com.ibatis.sqlmap.engine.mapping.statement.ProcedureStatement.postProcessParameterObject(ProcedureStatement.java:26)
	at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeUpdate(GeneralStatement.java:82)
	... 22 more

 

 

在网上查了资料没有有效的解决方案,所以只能跟踪日志来。

--- The error occurred while applying a parameter map.  
--- Check the insertStatisticsResult_settle-InlineParameterMap.

观察这个日志是由于传入参数错误,我看网上demo都是传入的map,而我的是string,

问题出在这,存储过程参数都以map的形式传入。

将传入参数改为hashmap就ok了

<procedure id="insertStatisticsResult_settle" parameterClass="java.util.HashMap"> 

  <![CDATA[

     {call proc_stats_$statisticsType$()}

  ]]>

</procedure>

 

这个错误的根本原因是 Java 从 JDK 9 开始引入了模块化系统(Project Jigsaw)。该系统的目的是增强 Java 平台的安全性和稳定性,但它也限制了一些以前可以随意访问的操作。具体来说,`java.lang.String.value` 是一个私有的成员变量,在新版本的 JDK 中不允许外部程序通过反射直接访问它。 以下是对此问题的具体分析和解决办法: --- ### 错误原因剖析 1. **JDK 模块化的安全机制** - 在 JDK 9+ 中,默认情况下模块不会向所有其他模块公开其内部包。只有显式声明为“open”的包才允许被反射访问。 - 当前问题的核心在于 MyBatis 的某个组件试图通过反射访问 `java.lang.String.value`,而这违反了模块化规则。 2. **MyBatis 插件或工具的行为不当** - 一些 MyBatis 扩展插件可能会利用反射技术操作对象实例,例如深度拷贝、序列化反序列化等功能。 - 如果这些插件未适配最新的 JDK 版本,就会触发此异常。 3. **潜在的依赖版本不兼容** - 如果使用的 MyBatis 或相关库版本较低,并且它们尚未完全支持 JDK 9+,也可能导致这个问题。 --- ### 解决方案 #### 方案一:修改 JVM 启动参数 可以在启动应用程序时添加以下 VM 参数,强制打开对特定包的访问权限: ```bash --add-opens java.base/java.lang=ALL-UNNAMED ``` 这会让 `java.lang` 包的所有内容都可以被非命名模块访问。适用于临时解决问题的情况,但在生产环境中并不推荐长期使用这种方法。 #### 方案二:升级 MyBatis 和相关依赖 确保所使用的 MyBatis 库及其扩展插件已经更新到最新版本。很多流行的开源项目都已解决了与 JDK 9+ 兼容性有关的问题。 #### 示例 Maven 配置: ```xml <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.x.x</version> <!-- 确保是支持 JDK 9+ 的版本 --> </dependency> ``` #### 方案三:替换引起问题的功能代码 如果确定是由某个自定义插件引起的,请检查是否有替代方法完成同样的任务而不涉及敏感字段操作。尽量减少对于底层实现细节(如 `String.value`)的直接操控需求。 --- ### 注意事项 尽管可以通过命令行选项轻松绕过这一限制,但这并非长久之计。最佳实践仍是尽可能地迁移到更现代化的技术栈上来消除隐患。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值