开发中遇到一个奇怪的问题:
Caused by: org.apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.ArrayList and java.lang.String ### Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.ArrayList and java.lang.String at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:172) at org.apache.ibatis.session.defaults.DefaultSqlSession.delete(DefaultSqlSession.java:185) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:386) ... 132 common frames omitted Caused by: java.lang.IllegalArgumentException: invalid comparison: java.util.ArrayList and java.lang.String at ognl.OgnlOps.compareWithConversion(OgnlOps.java:92) at ognl.OgnlOps.isEqual(OgnlOps.java:142) at ognl.OgnlOps.equal(OgnlOps.java:794) at ognl.ASTNotEq.getValueBody(ASTNotEq.java:53) at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) at ognl.SimpleNode.getValue(SimpleNode.java:258) at ognl.ASTAnd.getValueBody(ASTAnd.java:61) at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) at ognl.SimpleNode.getValue(SimpleNode.java:258) at ognl.Ognl.getValue(Ognl.java:494) at ognl.Ognl.getValue(Ognl.java:458) at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:44) at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateBoolean(ExpressionEvaluator.java:32) at org.apache.ibatis.scripting.xmltags.IfSqlNode.apply(IfSqlNode.java:34) at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:33) at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:41) at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:280) at org.apache.ibatis.executor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:64) at org.apache.ibatis.executor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:39) at org.apache.ibatis.executor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:45) at org.apache.ibatis.session.Configuration.newStatementHandler(Configuration.java:490) at org.apache.ibatis.executor.ReuseExecutor.doUpdate(ReuseExecutor.java:49) at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:115) at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:75) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63) at com.sun.proxy.$Proxy136.update(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63) at com.sun.proxy.$Proxy136.update(Unknown Source) at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:170) ... 138 common frames omitted
所用 mybatis版本:3.4.4。
以下是mapper中对应的sql:
<delete id="deleteById"> delete from table1 where DEF_DB_ID = #{defDbId} <if test="refDbIds != null and refDbIds != '' "> and REF_DB_ID in <foreach collection="refDbIds" item="refDbId" open="(" close=")" separator=","> #{refDbId} </foreach> </if> </delete>
感觉应该是类型不符合的问题,网上查找资料,发现问题应该出现在:
<if test="refDbIds != null and refDbIds != '' ">
其中 refDbIds 参数的类型为ArrayList,调用时传入的refDbIds内容是空的,即refDbIds!=null 并且 refDbIds.length等于0,
因此在执行此sql时,类型为ArrayList的refDbIds与空字符串''进行比较就会出现异常。处理方法是去掉上面代码中的
refDbIds != ''
即将:
<if test="refDbIds != null and refDbIds != '' "> and REF_DB_ID in <foreach collection="refDbIds" item="refDbId" open="(" close=")" separator=","> #{refDbId} </foreach> </if>修改为:
<if test="refDbIds != null"> and REF_DB_ID in <foreach collection="refDbIds" item="refDbId" open="(" close=")" separator=","> #{refDbId} </foreach> </if>