在我的应用程序中,我正在生成一个SQL-INSERT。此插入将作为JPA原生查询(Hibernate)执行,并在SQL Server中自动生成一个新的标识值。
如何接收生成的identity值?
我希望避免对@@IDENTITY执行第二次select,因为第二个用户可能在此期间插入了某些内容,从而导致错误的结果。(在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-Statement后面(如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"在我的项目中不能使用"criteria builder“或"named”。
发布于 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?和其他有关批量插入的帖子。
存储过程可能是一种解决方案,但出于个人喜好,我远离存储过程。
https://stackoverflow.com/questions/30490364
复制相似问题