हम एक स्प्रिंग 3.1/हाइबरनेट 4/जावा 7/टॉमकैट 7/एमएसएसक्यूएल 2008 आर 2 वेब एप्लिकेशन चलाते हैं। हमें विरासत डेटा और संग्रहीत डेटा से निपटना होगा। किसी संग्रह से डेटा निकालने पर, हमें मूल अद्वितीय पहचानकर्ता का उपयोग करने की आवश्यकता होती है ताकि अन्य (गैर-संग्रहित) रिकॉर्ड सही ढंग से फिर से हाइड्रेट हो जाएंगे। ये पहचानकर्ता प्राथमिक कुंजी/ऑटो वृद्धि क्षेत्र में संग्रहीत हैं।हाइबरनेट 3.5 बनाम 4 IDENTITY_INSERT मुद्दे
पहले अब, जब हम वसंत 3.0 उपयोग कर रहे थे/हाइबरनेट करने के लिए 3.5, निम्न कोड एक निकाले रिकॉर्ड अपने उचित तालिका में वापस INSERT के लिए काम किया (हम पहले से ही चर 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 */ }
}
});
जैसे कि मैंने उल्लेख किया है, यह सब हाइबरनेट 3.5 में ठीक काम किया, लेकिन अब है कि हम हाइबरनेट करने के लिए 4 अपग्रेड किया है, यह काम करना बंद कर चुका है। क्या कार्य और पृथक कार्य के बीच अंतर के साथ कुछ है?
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 सर्वर प्रोफाइलर ट्रेस किया, और कुछ दिलचस्प पाया। कुछ हमारे लेनदेन निकायों में IMPLICIT_TRANSACTIONS चालू कर रहा है।
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 सेट कर रहे हैं बंद हो सकता है, अब कनेक्शन के माध्यम से: यहाँ प्रोफाइलर का पता लगाने से कुछ नमूना उत्पादन (मैं बदल दिया है छोटे लेबल के साथ डेटा के कुछ बड़े बिट्स <schema>
साथ हमारी वास्तविक स्कीमा, और) है हमारे लेनदेन में .setAutoCommit (झूठा) (लेनदेन स्प्रिंग @ ट्रान्सैक्शनल और हाइबरनेट लेनदेन प्रबंधक के माध्यम से प्रबंधित किया जा रहा है)। जाहिर है, यह काम नहीं कर रहा है, लेकिन setAutoCommit का उपयोग करने के अलावा विकल्प क्या हैं, और यह Spring3.0/Hibernate 3.5 में क्यों काम करेगा लेकिन वसंत 3.1/हाइबरनेट 4 नहीं?
किसी भी विचार या सुझाव के लिए धन्यवाद - हम स्टंप हो गए हैं।
आपको बहुत धन्यवाद, निश्चित रूप से, यह मुझे बहुत समय बचाता है। –