在我的应用程序中,我正在生成一个SQL-INSERT。此插入将作为JPA本机查询(Hibernate)执行,并在我们的SQL Server中自动生成新的标识值。
如何收到生成的身份值?
我想避免再次选择@@IDENTITY
,因为第二个用户可能同时插入了一些内容,导致错误的结果。
(见Getting generated identifier for JPA native insert query)
使用@@ IDENTITY的代码如下所示:
Query statementInsert = entityManager.createNativeQuery("INSERT INTO x(colum1, column2) VALUES (:value1, :value2)");
// setting parameters...
statementInsert.executeUpdate();
Query statmentSelectId = entityManager.createNativeQuery("SELECT @@IDENTITY");
int generatedId = ((BigDecimal) statmentSelectId.getSingleResult()).intValueExact();
我更愿意将SELECT SCOPE_IDENTITY()
放在INSERT
- 声明后面(如图所示)
How to get Identity value from SQL server after insert record)。这需要为JPA本机查询进行某种“批量执行”。
我梦想着这样的事情:
Query statementInsertAndSelectId = entityManager.createNativeQuery("INSERT INTO x(colum1, column2) VALUES (:value1, :value2); SELECT SCOPE_IDENTITY();");
// setting parameters...
// ?????????
int generatedId = ((BigDecimal) statementInsert.getSingleResult()); // not working, JPA complains about "No ResultSet"
在我的项目中无法使用“条件构建器”或“命名查询”。
答案 0 :(得分:1)
即使您背靠背写,也可能会发生并发调用,使@@ IDENTITY返回错误的值。
您需要使用@@ SCOPE_INDENTITY来获取系统范围的最新值,而不是您范围内的最新值。 根据{{3}},如果两个语句在同一存储过程,函数或批处理中,则它们在同一范围内。
在JPA中批量获取2个语句可能会很棘手。批量插入可能是一项挑战,需要特定于环境或特定于hibernate(通过JPA)的代码。请参阅https://msdn.microsoft.com/en-us/library/ms190315.aspx以及有关批量插入的其他帖子。
商店程序可能是一种解决方案,但作为个人偏好,我远离存储过程。