'Mybatis foreach mapper item exception
I am using foreach
for SELECT IN
clause.
Item has not been found by mapper.
Here is part of exception.
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [ids, param1]] with root cause
org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [ids, param1]
at org.apache.ibatis.binding.MapperMethod$ParamMap.get(MapperMethod.java:212) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.reflection.wrapper.MapWrapper.get(MapWrapper.java:45) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:122) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.executor.BaseExecutor.createCacheKey(BaseExecutor.java:219) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.executor.CachingExecutor.createCacheKey(CachingExecutor.java:146) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:88) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145) ~[mybatis-3.5.9.jar:3.5.9]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140) ~[mybatis-3.5.9.jar:3.5.9]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
Param ids is found, but also param1 that does not exist.
Below is sql used in @Select
annotation.
select a.* from ACTOR
<if test="ids != null and ids.size > 0">
where a.ID in
<foreach collection="ids" item="id" separator="," close=")" open="(">
#{id}
</foreach>
</if>
Interface method is defined as
public List<Actor> listByIds(@Param("ids")List<Long> ids);
I am already using foreach
on other places and other sql queries, this is the only one making issue.
Solution 1:[1]
Select annotation MUST include script
tag if e.g. foreach
is going to be used, as in example below.
@Select("""
<script>
select a.* from ACTOR
<if test="ids != null and ids.size > 0">
where a.ID in
<foreach collection="ids" item="id" separator="," close=")" open="(">
#{id}
</foreach>
</if>
</script>
""")
public List<Actor> listByIds(@Param("ids")List<Long> ids);
Otherwise, parameter mapper will try to find id
param in function signature instead of foreach, because it does not know it is script.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | EnterSB |