'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