首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从原生JPA插入中获取生成的标识值?

如何从原生JPA插入中获取生成的标识值?
EN

Stack Overflow用户
提问于 2015-05-28 02:26:56
回答 1查看 5.2K关注 0票数 2

在我的应用程序中,我正在生成一个SQL-INSERT。此插入将作为JPA原生查询(Hibernate)执行,并在SQL Server中自动生成一个新的标识值。

如何接收生成的identity值?

我希望避免对@@IDENTITY执行第二次select,因为第二个用户可能在此期间插入了某些内容,从而导致错误的结果。(在Getting generated identifier for JPA native insert query中可见)

使用@@IDENTITY的代码如下所示:

代码语言:javascript
复制
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-Statement后面(如How to get Identity value from SQL server after insert record所示)。这将需要对JPA原生查询执行某种类型的“批处理”。

我的梦想是这样的:

代码语言:javascript
复制
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"

在我的项目中不能使用"criteria builder“或"named”。

EN

回答 1

Stack Overflow用户

发布于 2015-05-28 02:51:04

即使您是背靠背地编写它,您也可能会得到并发调用,这将使@@标识返回错误的值。

您需要使用@@SCOPE_INDENTITY来获取系统范围内的最新值,而不是您作用域内的最新值。根据https://msdn.microsoft.com/en-us/library/ms190315.aspx,如果两个语句位于相同的存储过程、函数或批处理中,则它们位于相同的作用域中。

在JPA中,在批处理中获取2条语句可能比较棘手。批量插入可能是一个挑战,它需要特定于环境或特定于hibernate (通过JPA)代码。参见How to do the BATCH insert in JPA?和其他有关批量插入的帖子。

存储过程可能是一种解决方案,但出于个人喜好,我远离存储过程。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30490364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档