MyBatis doesn't assign generated id into property on multi-row insert.
This mapping not working. id property is always null. But MyBatis doc tells that this mapping should work. So it's bug:
Method signature in mapper interface:
void insertTwitters(@Param("twitters") List<Twitter> twitters);
XML mapper:
<insert id="insertTwitters" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
INSERT INTO twitter.twitter (message_id, message_symbol_id)
VALUES
<foreach item="item" collection="twitters" separator=",">
(#{item.message.id}, #{item.messageSymbol.id})
</foreach>
</insert>
I found workaround which works. Just need to remove Param annotations from mapper interface and set parameterType="list" in insert and collection="list" in foreach nodes in XML mapper.
Method signature in mapper interface (without param anotation):
void insertTwitters(List<Twitter> twitters);
XML mapper:
<insert id="insertTwitters" parameterType="list" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
INSERT INTO twitter.twitter (message_id, message_symbol_id)
VALUES
<foreach item="item" collection="list" separator=",">
(#{item.message.id}, #{item.messageSymbol.id})
</foreach>
</insert>
So if I use old-fashioned way without Paramannotations and named arguments then MyBatis assign generated id into property. But if I'm using modern way with named arguments then id property is always null.
I'm using PostgreSQL 10, JDK 9 and MyBatis 3.4.5
Comment From: harawata
It is by design.
If you want to set the generated keys to a list parameter, the parameter name must be "list".
Adding @Param("list") works as well (this is mandatory when there are multiple parameters).
As we have received the same reports several times already, we should add a note on the document.
Comment From: EldarAgalarov
Seems it's bad design. I suggest to implement it as expected.
Comment From: harawata
What would you expect when there are multiple parameters?
void insert(
@Param("twitters") List<Twitter> twitters,
@Param("twinkies") List<Twinkie> twinkies);
<insert id="insert" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
...
Comment From: lovepoem
Seems it's bad design. I suggest to implement it as expected.
@EldarAgalarov , I think so .
What would you expect when there are multiple parameters?
@harawata , I expect like this:
List<Long> insert(
@Param("twitters") List<Twitter> twitters,
@Param("twinkies") List<Twinkie> twinkies);
<insert id="insert" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
insert into twitters (name,address) values
<foreach item="twitter" collection="twitters" separator=",">
(
#{twitter.name}, #{twitter.address}
)
</foreach>
</insert>
Comment From: harawata
@lovepoem ,
What I meant was, when there are multiple parameters, MyBatis cannot decide which parameter to set the generated keys to (i.e. is it Twitter.id? or Twinkie.id?).
Comment From: lovepoem
What I meant was, when there are multiple parameters, MyBatis cannot decide which parameter to set the generated keys to (i.e. is it Twitter.id? or Twinkie.id?).
For this problem, your handling is reasonable. But new comers often do not know the "list" configuration, how to clearly mark it in the document? @harawata
Comment From: dosanHoon
this problem is solved?
Comment From: lovepoem
@harawata Answered here. https://github.com/mybatis/mybatis-3/pull/1196
Comment From: harawata
Sorry about the lack of response.
I actually submitted a PR #1249 a while ago. But there are a few backward incompatible changes and I'm not so sure if it's a good patch or not. Comments and suggestions are welcome.
Comment From: lovepoem
Sorry about the lack of response. I actually submitted a PR #1249 a while ago. But there are a few backward incompatible changes and I'm not so sure if it's a good patch or not. Comments and suggestions are welcome.
I think it look good to me
Comment From: harawata
Thank you @lovepoem for the feedback! I have merged #1249 .
To all, Please test the change with the latest 3.5.0-SNAPSHOT and let us know if there is any problem.