@SelectKey generation at insert with SQL Server

1,755 views
Skip to first unread message

Hernán J. González

unread,
Oct 30, 2017, 7:09:13 PM10/30/17
to mybatis-user
How to make the insert with identity key setting work in SQL Server? 

one should rely on "SELECT SCOPE_IDENTITY()" for that, but it does not work for me

public class TestMapper {
    @Insert({ "insert into TEST (VAL_INT) values " +
          "(#{valInt,jdbcType=INTEGER})" })
    @SelectKey(statement = "SELECT SCOPE_IDENTITY()", keyProperty = "id", before = false, resultType = Integer.class)
    int insert(Test record);
}


that seems to conclude that MyBatis executes the insert and the select in different batches (strange!), and that's
why  SELECT SCOPE_IDENTITY() cannot work. 
If that is so, then MyBatisGenerator is wrong in recommending that way, no? Or am I doing something wrong?
Has this ever worked?

BTW, I've use this approach with Postgresql (reading the sequence, instead of SELECT SCOPE_IDENTITY() , of course), without problems.


Kazuki Shimizu

unread,
Nov 3, 2017, 10:46:07 PM11/3/17
to mybatis-user
I've reproduced this issue using SQLServer on Linux (using Docker image provided Microsoft).
In this case, using @@IDENTITY variable work fine. But we should be careful the specification that @@IDENTITY is returning the last identity on all scopes. 
FOR details for @@IDENTITY, please see reference document.

As an alternative method, I will suggest using the auto-generated keys feature provided JDBC 3.0 rather than the selectKey feature provided MyBatis.

How to use auto-generated Keys feature provided by JDBC 3.0 on MyBatis:

public interface TestMapper {

 
@Insert({ "insert into TEST (VAL_INT) values " +
     
"(#{valInt,jdbcType=INTEGER})" })

 
@Options(useGeneratedKeys = true) // Adding this line instread of @SelectKey
 
int insert(Test record);
}


Note:
I don't know why SCOPE_IDENTITY() return null via JDBC Driver. It works fine via "sqlcmd" (CUI tool provided the SQLServer).

Thanks.

Kazuki Shimizu

unread,
Nov 3, 2017, 11:36:19 PM11/3/17
to mybatis-user
If PreparedStatment is used, return null. I tried using Statement as follow:

public interface TestMapper {
 
@Insert("insert into TEST (VAL_INT) values (100)") // No use bind variable (=#{..}) in SQL
 
@Options(statementType = StatementType.STATEMENT) // Adding this line
 
@SelectKey(statement = "SELECT SCOPE_IDENTITY()", keyProperty = "id", before = false, resultType = Integer.class, statementType = StatementType.STATEMENT) // Set statementType = StatementType.STATEMENT
 
int insert(Test record);
}

However, this solution is not practical.
I propose confirming the specification of the SQLServer JDBC Driver.

Thanks.

Tim

unread,
Nov 4, 2017, 11:51:50 AM11/4/17
to mybati...@googlegroups.com
Try using just the generatedKeys

In xml I use:

insert id="insertFoo" useGeneratedKeys="true" keyProperty="id" keyColumn="id"

Note that keyProperty and keyColumn are important.

--
You received this message because you are subscribed to the Google Groups "mybatis-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mybatis-user+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tim

unread,
Nov 4, 2017, 10:21:37 PM11/4/17
to mybati...@googlegroups.com
The annotation equivalent would be similar to what Kazuki posted:

@Insert({ "insert into TEST (VAL_INT) values (#{valInt,jdbcType=INTEGER})" })
@Options(useGeneratedKeys=true, keyProperty="id", keyColumn="id")
This is what I use on SQL Server but if it's not working for you let me know what version of SQL server and which driver you are using (jtds or the official ms one?)

Hernán J. González

unread,
Nov 6, 2017, 8:06:10 PM11/6/17
to mybatis-user
This worked for me, thanks.
A pity that MyBatisGenerator does not generate this...
To unsubscribe from this group and stop receiving emails from it, send an email to mybatis-user...@googlegroups.com.

Jeff Butler

unread,
Nov 6, 2017, 8:09:21 PM11/6/17
to mybati...@googlegroups.com
Read the manual.  Set sqlStatament="JDBC"


Jeff Butler


Reply all
Reply to author
Forward
0 new messages