【问题标题】:How to get generated Identity value from a native JPA INSERT?如何从本机 JPA INSERT 获取生成的标识值?
【发布时间】:2015-08-10 00:07:44
【问题描述】:

在我的应用程序中,我正在生成一个 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-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"

在我的项目中无法使用“条件生成器”或“命名查询”。

【问题讨论】:

标签: java sql-server hibernate jpa


【解决方案1】:

即使您将其背靠背写入,您也可能会得到并发调用,这会使@@IDENTITY 返回错误的值。

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

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

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

【讨论】:

  • 根据stackoverflow.com/questions/12827496/…,@@SCOPE_IDENTITY 如果在同一个事务中就可以工作......但它会先测试它!
  • 首先,它是Scope_Identity() 而不是@@Scope_identity。其次,你有什么理由不使用存储过程?
  • 存储过程、触发器等中的任何代码都是隐藏代码。如果您在小型开发团队中工作,那没关系。在一个更大的团队中,如果您的初级团队成员不知道 DB 在现场做了一些技巧,这可能会导致一些重大的时间浪费。我不是说它不好,我说它是个人喜好。
  • 不必隐藏。 IMO,使用 sql server 而不使用它的内置工具,如存储过程等,就像以 10 英里/小时的速度驾驶一艘渡轮。
猜你喜欢
  • 2012-11-14
  • 2023-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-30
  • 1970-01-01
相关资源
最近更新 更多