Wir betreiben eine Spring 3.1/Hibernate 4/Java 7/Tomcat 7/MSSQL 2008 R2 Webanwendung. Wir müssen mit Altdaten und archivierten Daten umgehen. Beim Extrahieren von Daten aus einem Archiv müssen wir den ursprünglichen eindeutigen Bezeichner verwenden, damit andere (nicht archivierte) Datensätze richtig hydriert werden. Diese Bezeichner werden im Feld Primärschlüssel/Autoinkrement gespeichert.Hibernate 3.5 vs 4 IDENTITY_INSERT Probleme
Vor jetzt, wo wir Frühling mit wurden 3.0/3.5 Hibernate, der folgende Code verarbeitet, um einen extrahierten Datensatz wieder in die entsprechende Tabelle einzufügen (wir haben bereits die Variablen session
, entity
und fullTableName
in scope):
Wie schon erwähnt, hat dies alles in Hibernate 3.5 funktioniert, aber jetzt, wo wir auf Hibernate 4 aktualisiert haben, funktioniert es nicht mehr. Gibt es etwas mit dem Unterschied zwischen Work und IsolatedWork?
In dem Bemühen, das Problem zu lösen, und alle Arbeits Schnittstelle Probleme zu vermeiden, haben wir versucht, die folgenden:
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();
Dies ist jedoch entweder nicht funktioniert hat. Genauer gesagt, die Ausnahme, die ausgelöst wird, ist java.sql.SQLException: Cannot insert explicit value for identity column in table 'Employee' when IDENTITY_INSERT is set to OFF.
. Es sollte jedoch klar sein, dass wir uns Mühe geben, es AN zu setzen.
Wir haben eine SQL Server Profiler Spur der Situation, und etwas interessantes gefunden. Etwas setzt IMPLICIT_TRANSACTIONS in jedem unserer Transaktionskörper auf ON. Hier einige Beispielausgabe des Profiler-Ablaufverfolgung (Ich habe unsere tatsächlichen Schema mit <schema>
ersetzt, und einige große Daten-Bits mit kürzeren Etiketten):
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
Nun sind wir speziell IMPLICIT_TRANSACTIONS Einstellung OFF sein, über den Verbindungs .setAutoCommit (false) in unserer Transaktion (Transaktionen werden über Spring @Transactional und Hibernate Transaction Manager verwaltet). Offensichtlich funktioniert das nicht, aber was sind die Alternativen abgesehen von der Verwendung von setAutoCommit, und warum würde es in Spring3.0/Hibernate 3.5 funktionieren, aber nicht in Spring 3.1/Hibernate 4?
Danke für irgendwelche Gedanken oder Vorschläge - wir sind ratlos.
Vielen Dank, das hat mir sehr viel Zeit gespart. –