Reputation: 1128
I try to make batch insert into table at Oracle database using MyBatis (integrated with Spring) .
It is a definition of method in mapper interface:
public void savePayments(@Param("payments") List<MassPaymentItem> payments);
It is a MyBatis XML mapper code:
<insert id="savePayments" parameterType="MassPaymentFileItem" useGeneratedKeys="false">
INSERT INTO mass_payments
(payment_id, file_id, msisdn, amount, status)
<foreach collection="payments" item="payment" index="index" separator=" UNION ALL ">
SELECT SEQ_MASS_PAYMENT.nextval, #{payment.fileId}, #{payment.msisdn}, #{payment.amount}, 0 FROM DUAL
</foreach>
</insert>
When I execute this I receive MyBatisSystemException with message "nested exception is org.apache.ibatis.builder.BuilderException: Improper inline parameter map format. Should be: #{propName,attr1=val1,attr2=val2}"
What is wrong? How to fix it?
Upvotes: 0
Views: 3920
Reputation: 2370
I found that the first answer doesn't work for me, then i find another solution as below:
<insert id="savePayments" parameterType="java.util.List" useGeneratedKeys="true">
<selectKey resultType="java.lang.Integer" keyProperty="payment_id"
order="BEFORE">
SELECT SEQ_MASS_PAYMENT.nextval as payment_id FROM DUAL
</selectKey>
INSERT INTO mass_payments
(payment_id, file_id, msisdn, amount, status)
select SEQ_MASS_PAYMENT.nextval, A.* from (
<foreach collection="payments" item="payment" index="index" separator="UNION ALL">
SELECT
#{payment.fileId} as file_id,
#{payment.msisdn} as msisdn,
#{payment.amount} as amount,
0 as status
FROM DUAL
</foreach> ) A
</insert>
Upvotes: 1
Reputation: 1128
I found solution here
<insert id="savePayments">
INSERT ALL
<foreach collection="payments" item="payment">
INTO
mass_payments_t (payment_id, file_id, msisdn, amount)
VALUES
(seq_mass_payment.nextval, #{payment.fileId, javaType=Integer, jdbcType=NUMERIC}, #{payment.msisdn, javaType=String, jdbcType=VARCHAR}, #{payment.amount, javaType=BigDecimal, jdbcType=NUMERIC})
</foreach>
SELECT * FROM dual
</insert>
Upvotes: 1
Reputation: 8057
Take a close look at your select statement. Where one would expect column name or function, you pass parameter. You should change it to something like (notice the location of from
:
<foreach collection="payments" item="payment" index="index" separator=" UNION ALL ">
(SELECT SEQ_MASS_PAYMENT.nextval from DUAL), #{payment.fileId}, #{payment.msisdn}, #{payment.amount}, 0
</foreach>
Upvotes: 0