Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MyBatis useGeneratedKeys for nested object in batch insert

While batch insertion and getting the generated key, getting the error. Batch insertion works fine.

Object Structure:

Object 1:

Long id, String name, Obj2 obj 

Object 2: (Obj2)

Long id, String value

Both the objects are stored in different tables.

Table object1

id | name  | object2_id (Foreign Key)

Table object2

id | value

Now I have a list of Object 1 to insert.

The process will be insert Object 2 get the id, and insert Object 1 with " id " of Object2 (as foreign key).

While inserting Object2, the insert block in Mapper.xml

Case 1:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj1s.obj2.id">
<!-- obj1s is name of the list --> 
    insert into object2 (value) values 
        <foreach collection="obj1s" item="obj1" separator=",">
            (#{obj1.obj2.id})
        </foreach>
</insert>

ERROR: Error getting generated key or setting result to parameter object.

Case 2:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj1.obj2.id">
<!-- obj1 so as to access the object of foreach loop --> 
    insert into object2 (value) values 
        <foreach collection="obj1s" item="obj1" separator=",">
            (#{obj1.obj2.id})
        </foreach>
</insert>

ERROR: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'obj1' not found. Available parameters are [obj1s, param1]

Case 3:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj2.id">
<!-- obj2 is the object with variable id to store generated key --> 
    insert into object2 (value) values 
        <foreach collection="obj1s" item="obj1" separator=",">
            (#{obj1.obj2.id})
        </foreach>
</insert>

ERROR: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'obj2' not found. Available parameters are [obj1s, param1]

Is there anyway to achieve this? Maybe using selectKey, but selectkey is used for DBs not supporting Autogenerated key.

Using MyBatis 3.3.1 and Mysql.

like image 616
Shuddh Avatar asked Nov 25 '25 12:11

Shuddh


1 Answers

So, I figured it out. There is this bug with MyBatis for multi-row insert and useGenerated key. The Bug is the list variable name must be "list" when doing batch insertion and getting generated key. Then access the object accordingly. So for above emxample the code will look like this:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj2.id">
<!-- obj2 is the object with variable id to store generated key --> 
insert into object2 (value) values 
    <foreach collection="list" item="obj1" separator=",">
        (#{obj1.obj2.id})
    </foreach>

and the mapper.java method declaration will look like this:

public Integer batchInsert(@Param("list")List<Obj1> obj1);

The name of Variable must be list. Nothing else.

And thanks @blackwizard, I got to revisit and check the bug, which landed me to this answer.

like image 197
Shuddh Avatar answered Nov 28 '25 02:11

Shuddh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!