3.4.5.
mysql-5.5.48-winx64
The result is present after upgrading from 3.4.4 to 3.4.5. It was working fine before.
During a batch insert I was using ON DUPLICATE KEY UPDATE. For example:
<insert id="createAll" parameterType="com.company.Machines">
INSERT INTO merchant_machine (merchant_account_id, product_id, description, lock_version, created_on, updated_on) values
<foreach collection="machineList" item="machine" separator="," close="" open="">
(#{machine.merchantAccountId},
#{machine.productId},
#{machine.description},
1,
SYSDATE(),
SYSDATE())
</foreach>
ON DUPLICATE KEY
UPDATE
description = #{machine.description},
product_id = #{machine.productId},
lock_version = 1 + lock_version,
updated_on = SYSDATE()
</insert>
Machines object looks like this:
public class Machines{
private List<Machine> machineList;
@Override
public List<Machine> getMachineList() {
if (machineList == null) {
machineList = new ArrayList<>();
}
return machineList;
}
@Override
public void setMachineList(List<Machine> machineList) {
this.machineList = machineList;
}
}
It was working as expected, inserting the list in a foreach loop and on duplicate, it was updating the rows. After updating to version 3.4.5, following exception is thrown:
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'machine' in 'com.company.Machines'
Basically item name is not accessible outside foreach block. Could you fix or suggest a workaround?
@giorgimode try parameterType="list"
Probably, this issues related with #966.
I am not familiar with the MySQL, but I think your sql is wrong.
Could you try following solution(= using values(column_name) phrase into update statement)?
<insert id="createAll" parameterType="com.company.Machines">
INSERT INTO merchant_machine (merchant_account_id, product_id, description, lock_version, created_on, updated_on) values
<foreach collection="machineList" item="machine" separator="," close="" open="">
(#{machine.merchantAccountId},
#{machine.productId},
#{machine.description},
1,
SYSDATE(),
SYSDATE())
</foreach>
ON DUPLICATE KEY
UPDATE
- description = #{machine.description},
+ description = values(description),
- product_id = #{machine.productId},
+ product_id = values(product_id),
lock_version = 1 + lock_version,
updated_on = SYSDATE()
</insert>
About values(column_name) , phrase see https://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html.
@kazuki43zoo is right about both the reason and the resolution.
It was wrong that a loop variable was accessible after the loop.
@kazuki43zoo is right. His suggestion works. I am wondering, was it a bug in previous version. Loop variable probably should not have been accessible outside loop
Most helpful comment
Probably, this issues related with #966.
I am not familiar with the MySQL, but I think your sql is wrong.
Could you try following solution(= using
values(column_name)phrase into update statement)?About
values(column_name), phrase see https://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html.