我們運行Spring 3.1/Hibernate 4/Java 7/Tomcat 7/MSSQL 2008 R2 Web應用程序。我們必須處理遺留數據和歸檔數據。從檔案中提取數據時,我們需要使用原始的唯一標識符,以便其他(非歸檔)記錄能夠正確地重新提供水分。這些標識符存儲在主鍵/自動增量字段中。Hibernate 3.5 vs 4 IDENTITY_INSERT問題
到現在,當我們在使用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。下面是來自探查器跟蹤的一些示例輸出(我把它換成我們的實際模式與<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
現在,我們專門設置IMPLICIT_TRANSACTIONS爲OFF,通過連接.setAutoCommit(false)在我們的事務中(事務正在通過Spring @Transactional和Hibernate事務管理器進行管理)。顯然,這不起作用,但除了使用setAutoCommit之外,還有什麼替代方法,以及爲什麼它可以在Spring3.0/Hibernate 3.5中工作,而不是在Spring 3.1/Hibernate 4中工作?
感謝您的任何想法或建議 - 我們難住。
非常感謝,當然,這節省了我很多時間。 –