我被迫使用createSQLQuery
使用hibernate将值插入到具有Identity列(第一列和主键)的表中。使用hibernate类不是一种选择,因为表是为添加到系统的每个客户动态创建的。我已运行查询并成功插入表中。然后我执行一个" select scope_identity()"它总是返回null。 "选择@@ Identity"有效,但不能保证是正确的。我还尝试追加"选择scope_identity()"到插入查询。然后我尝试query.list()
和query.uniqueResult()
这两个都抛出了"没有结果的休眠异常..."
Session session = DatabaseEngine.getSessionFactory().openSession();
String queryString = "insert into table1 (dataid) values (1)"
SQLQuery query = session.createSQLQuery(insertQueryString);
query.executeUpdate();
query = session.createSQLQuery("select scope_identity()");
BigDecimal entryID = (BigDecimal)query.uniqueResult();
简单示例表定义如下:
"CREATE TABLE table1 (EntryID int identity(1,1) NOT NULL," +
"DataID int default 0 NOT NULL, " +
"PRIMARY KEY (EntryID))";
我是否有办法将scope_identity()与createSQLQuery
一起使用?
答案 0 :(得分:1)
实际上,Hibernate使用的SQLServerDialect
类也使用相同的“scope_identity()”。
它无法工作的原因是因为您需要在同一语句或存储过程中执行它们。 如果在单独的语句中执行scope_identity()调用,SQL Server将无法为您提供上次插入的标识值。
你不能用SQLQuery
来做,即使Hibernate使用JDBC来完成这个任务。我在GitHub上写了一个测试来模拟它,它的工作方式如下:
Session session = entityManager.unwrap(Session.class);
final AtomicLong resultHolder = new AtomicLong();
session.doWork(connection -> {
try(PreparedStatement statement = connection.prepareStatement("INSERT INTO post VALUES (?) select scope_identity() ") ) {
statement.setString(1, "abc");
if ( !statement.execute() ) {
while ( !statement.getMoreResults() && statement.getUpdateCount() != -1 ) {
// do nothing until we hit the resultset
}
}
try (ResultSet rs = statement.getResultSet()) {
if(rs.next()) {
resultHolder.set(rs.getLong(1));
}
}
}
});
assertNotNull(resultHolder.get());
代码使用Java 8 lambdas而不是匿名类,但您也可以轻松将其移植到Java 1.7。