Spring 3.1 / Hibernate 4 / Java 7 / Tomcat 7 / MSSQL 2008R2Webアプリケーションを実行します。レガシーデータとアーカイブデータを処理する必要があります。アーカイブからデータを抽出するときは、他の(アーカイブされていない)レコードが正しく再水和されるように、元の一意の識別子を使用する必要があります。これらの識別子は、主キー/自動増分フィールドに格納されます。
これまで、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の違いに何か問題はありますか?
問題を解決し、Workインターフェイスの問題を回避するために、次のことを試みました。
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.
まだですが、それをオンに設定するのに苦労していることは明らかです。
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
現在、トランザクションのConnection.setAutoCommit(false)を介してIMPLICIT_TRANSACTIONSをOFFに設定しています(トランザクションはSpring@TransactionalおよびHibernateTransaction Managerを介して管理されています)。明らかに、それは機能していませんが、setAutoCommitを使用する以外の選択肢は何ですか?また、Spring3.0 /Hibernate3.5では機能するのにSpring3.1/ Hibernate4では機能しないのはなぜですか?
考えや提案をありがとう-私たちは困惑しています。