- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们运行 Spring 3.1/Hibernate 4/Java 7/Tomcat 7/MSSQL 2008 R2 Web 应用程序。我们必须处理遗留数据和存档数据。从存档中提取数据时,我们需要使用原始的唯一标识符,以便其他(非存档)记录能够正确重新水合。这些标识符存储在主键/自动增量字段中。
在此之前,当我们使用 Spring 3.0/Hibernate 3.5 时,以下代码用于将提取的记录插入到相应的表中(我们已经在其中包含变量 session
、 entity
和 fullTableName
)范围):
session.doWork( new Work()
{
@Override
public void execute(Connection connection) throws SQLException
{
PreparedStatement statement = null;
try
{
statement = connection.prepareStatement(String.format("SET IDENTITY_INSERT %s ON", fullTableName));
statement.execute();
session.save(entity);
statement = connection.prepareStatement(String.format("SET IDENTITY_INSERT %s OFF", fullTableName));
statement.execute();
}
finally
{ /* close the statement */ }
}
});
就像我提到的,这一切在 Hibernate 3.5 中都工作得很好,但现在我们已经升级到 Hibernate 4,它已经停止工作了。 Work 和isolatedwork 之间有什么区别吗?
为了解决问题并避免任何工作界面问题,我们尝试了以下操作:
session.createSQLQuery(String.format("SET IDENTITY_INSERT %s ON", fullTableName)).executeUpdate();
session.save(entity);
session.createSQLQuery(String.format("SET IDENTITY_INSERT %s OFF", fullTableName)).executeUpdate();
但是,这也不起作用。具体来说,抛出的异常是 java.sql.SQLException: Cannot insert explicit value for identity column in table 'Employee' when IDENTITY_INSERT is set to OFF.
然而,应该清楚的是,我们正在努力将其设置为ON。
我们对情况进行了 SQL Server Profiler 跟踪,并发现了一些有趣的事情。在我们的每个事务主体中都设置了 IMPLICIT_TRANSACTIONS ON。以下是 Profiler 跟踪的一些示例输出(我已将实际架构替换为 <schema>
,以及一些带有较短标签的大量数据):
SET IMPLICIT_TRANSACTIONS ON
go
declare @p1 int
set @p1=55
exec sp_prepare @p1 output,N'',N'SET IDENTITY_INSERT <schema>.Employee ON',1
select @p1
go
exec sp_execute 55
go
declare @p1 int
set @p1=56
exec sp_prepare @p1 output,N'<parameters for the INSERT>',N'insert into <schema>.Employee (<all the column names>) values ( <all the parameters> )',1
select @p1
go
exec sp_execute 56,<the actual values to insert>
go
IF @@TRANCOUNT > 0 ROLLBACK TRAN
go
IF @@TRANCOUNT > 0 COMMIT TRAN
SET IMPLICIT_TRANSACTIONS OFF
go
exec sp_execute 54,N'Error writing EMPLOYEE archive record. ',<an id>,N'1'
go
现在,我们在事务中通过 Connection.setAutoCommit(false) 特别将 IMPLICIT_TRANSACTIONS 设置为 OFF(事务通过 Spring @Transactional 和 Hibernate Transaction Manager 进行管理)。显然,这是行不通的,但是除了使用 setAutoCommit 之外还有什么其他选择,为什么它可以在 Spring3.0/Hibernate 3.5 中工作,但不能在 Spring 3.1/Hibernate 4 中工作?
感谢您的任何想法或建议 - 我们很难过。
最佳答案
嗯,这是一个微妙的解决方案......
我们的 Work 调用在内部使用了 java.sql.PreparedStatement
,然后调用了 execute()
方法。显然,这告诉 SQL Server 将命令包装在它自己的存储过程中,如一些代码示例所示。
我们从使用 PreparedStatement
更改为简单的 java.sql.Statement
并调用其 execute()
方法:
session.doWork( new Work()
{
@Override
public void execute(Connection connection) throws SQLException
{
Statement statement = null;
try
{
statement = connection.createStatement();
statement.execute(String.format("SET IDENTITY_INSERT %s ON", fullTableName));
session.save(entity);
statement = connection.createStatement();
statement.execute(String.format("SET IDENTITY_INSERT %s OFF", fullTableName));
}
finally
{ /* close the statement */ }
}
});
那么,有什么区别呢?据我们所知,PreparedStatement
生成预编译的 SQL,而 Statement
生成静态 SQL...正是我们调用 IDENTITY_INSERT 所需的内容
!
教训:败类和恶行层出不穷……我们必须小心谨慎!
关于Hibernate 3.5 与 4 IDENTITY_INSERT 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12921560/
我在数据库中有一张表 Foo命名 Bar ,其中有一列名为 ID ,它是主键,这个数据库存在于开发 SQL Server 上。 我正在尝试将数据从我们的生产服务器复制到开发服务器,以便我可以使用所述数
这个问题在这里已经有了答案: Set start value for column with autoincrement (4 个回答) 3年前关闭。 我在 SQL Server 上工作,我想将一些行
我在 SQL Server 2012 和 2008 R2 中运行存储过程时遇到问题,而它在 SQL Server 2000 和 2005 中运行良好。 请参阅下面的代码: SELECT * INTO
是否可以在表触发器中打开它? 我尝试创建一个触发器SET IDENTITY_INSERT 表名打开 但是当我打开触发器定义时,我发现该语句不存在.... 这是我更改触发器以添加 IDENTITY_IN
我有一个脚本,可以创建整个数据库并将所有记录插入到几十个表中。它工作得很好,除非在处理过程中出现一些问题,并且当脚本在插入期间失败且在再次设置为 OFF 之前,表会保持 IDENTITY_INSERT
我的数据库中有几个表只包含“元数据”。例如,我们有不同的组类型、contentItemTypes、语言等。 问题是,如果您使用自动编号,则可能会产生间隙。id 在我们的代码中使用,因此数字非常重要。
我不太熟悉 SQL Server,但我正在编写一个脚本,该脚本在 IDENTITY ON 的表上显式设置插入值。由于一些计划不周的架构 - 看起来我将不得不显式插入一些任意高的数字(例如 10,000
我有一个 MVC Web 应用程序,模型中有一个表,我想添加到其中。我设置了主键和其他数据字段,但每次尝试添加到表中时,都会出现以下错误: “当 IDENTITY_INSERT 设置为 OFF 时,无
这是我的数据库脚本, CREATE TABLE [dbo].[MyTable]( [ID] [int] IDENTITY(1,1) NOT NULL, [Code] [nvarchar](25) NU
我目前正在从事一个数据迁移项目,对于与性能相关的问题,我想预定义一组身份,而不是让表生成它们。 我发现将 identity 属性添加到列中并不容易,所以我想使用 IDENTITY_INSERT ON
我正在使用数据集插入从旧数据库转换而来的数据。要求是维护当前的 Order_ID 编号。 我尝试过使用: SET IDENTITY_INSERT orders ON; 当我在 SqlServer Ma
我有一个已删除的文件存档数据库,用于存储已删除文件的 ID,我希望管理员能够恢复该文件(以及用于链接文件的相同 ID)。我不想将 Identity_insert 从整个表中删除,因为增量 1 效果很好
我正在尝试使用带有服务引用的 Silverlight C# 在 SQL 表中创建一个包含数据的新行。我收到以下错误: IDENTITY_INSERT is set to OFF. 但我希望自动提供 C
数据库中的“类别”表定义如下: CategoryID - PK ,identity specification ON (only this column has identity) Descri
我不熟悉 postgresql 脚本。 我已经在 ms sql server 中使用了这个脚本: SET IDENTITY_INSERT my_table ON INSERT INTO my_tabl
情况 我有一个 SQL 脚本,我需要将一些基本数据推送到我的数据库。因此,我使用以下脚本(和其他脚本)。我想为我手动创建的行手动提供一个主键。 问题 如果我执行脚本,它会提示我需要启用 IDENTIT
我正在尝试将订单详细信息插入我的数据库,但它一直在说: Cannot insert explicit value for identity column in table 'Orders' when
首先,我要求管理员删除此帖子: '我如何制作主键作为自动增量在 vb-net-2008/959787#959787' 因为我遇到了评论问题,当我尝试添加评论时,错误消息很明显:“评论需要 50 个声望
我有一个存储过程,我想授予它插入身份的权限,同时不授予调用它的受限用户 ALTER TABLE 权限。这可能吗? 这是我的存储过程: CREATE PROCEDURE [dbo].[AddIntern
我想将表 Equipment 从一个数据库 MyDBQA 复制到我们的测试数据库 MyDB。表中有一个标识列,它是主键(int,不为空)。 但是我得到了一个错误: Msg 8101, Level 16
我是一名优秀的程序员,十分优秀!