2011-03-01 7 views
18

शुरू नहीं इस सरल हाइबरनेट परिदृश्य पर विचार करें:हाइबरनेट लेन-देन सफलतापूर्वक

org.hibernate.TransactionException: Transaction not successfully started 
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:100) 
    at com.bigco.package.Clazz.getSomeData(Clazz.java:1234) 

क्या हो रहा है:

session = getHibernateSession(); 
tx = session.beginTransaction(); 
SomeObject o = (SomeObject) session.get(SomeObject.class, objectId); 
tx.commit(); 

इस कोड को निम्नलिखित अपवाद पैदा करता है?

+0

क्या आप एक लेनदेन प्रबंधक का भी उपयोग कर रहे हैं? – Jeremy

+0

मुझे बिल्कुल यकीन नहीं है कि कॉन्फ़िगरेशन क्या है, लेकिन मान लीजिए कि हमारे पास एक लेनदेन प्रबंधक है, क्या यह व्यवहार को प्रभावित करेगा? –

+0

मैंने पढ़ा है कि कभी-कभी आपके जैसे लेन-देन को मैन्युअल रूप से एक लेनदेन प्रबंधक के साथ इस अपवाद को फेंकने का कारण बनता है। – Jeremy

उत्तर

38

ठीक है, ऐसा लगता है कि हम tx.commit() लाइन तक पहुंचने के बाद, लेनदेन पहले ही कर चुके हैं। मेरा एकमात्र अनुमान यह है कि ऑब्जेक्ट में get() जब हाइबरनेट पहले ही लेनदेन करता है।

इस के लिए ठीक सरल है:

// commit only if tx still hasn't been committed yet (by hibernate) 
if (!tx.wasCommitted()) 
    tx.commit(); 
+0

सुझाया गया समाधान मेरे लिए काम किया। जानना चाहेंगे कि क्या लेनदेन करने के लिए एक बुद्धिमान तरीका है? –

7

यह एक बहुत पुराने प्रश्न है और मैं समझ आप पहले से ही इसका समाधान कर लिया (या हाइबरनेट कर दिया), लेकिन इस सवाल का जवाब का दुखद अंत सरल है। मुझे आश्चर्य है कि किसी और ने इसे उठाया नहीं है।

आपने session.save (o) नहीं किया है, इसलिए लेनदेन में कुछ भी नहीं है। यदि आप ऑब्जेक्ट में कुछ भी नहीं बदलते हैं तो प्रतिबद्धता अभी भी काम नहीं कर सकती है, लेकिन अगर कुछ भी नहीं बदला है तो आप इसे क्यों सहेजना चाहते हैं?

बीटीडब्ल्यू: session.getgin()) सत्र से पहले पूरी तरह से स्वीकार्य है .beginTransaction()।

+0

तो, यदि मैं डेटाबेस में परिवर्तन नहीं करता हूं, तो मुझे टीएक्स शुरू नहीं करना चाहिए? – user2171669

+0

यह मेरे लिए चाल है! – rdmueller

+0

मैं इस दृष्टिकोण के साथ सावधानी बरतने की सलाह देते हैं। मुझे लगता है कि यह केवल ऑटोोकॉमिट के साथ स्वीकार्य है, जो हाइबरनेट दृढ़ता से हतोत्साहित करता है। Autocommit के बिना, सब कुछ एक लेनदेन के भीतर होना चाहिए - यहां तक ​​कि एकल चयन बयान। – shaddow

4

मुझे पता चला कि यह पहले ही हल हो चुका है; भले ही मैं अपना जवाब यहां पोस्ट कर रहा हूं।

मुझे लेनदेन पर wasCommitted() विधि नहीं मिली है।

लेकिन निम्नलिखित कोड मेरे लिए काम किया: जब कोड एक EJB में है

// commit only, if tx still hasn't been committed yet by Hibernate 
if (tx.getStatus().equals(TransactionStatus.ACTIVE)) { 
    tx.commit(); 
} 
+0

इससे मुझे भी मदद मिली !!! –

0

एक स्थिति इस में हो सकता है है/एमडीबी कंटेनर से प्रबंधित लेनदेन (CMT) के साथ या तो जानबूझकर या क्योंकि यह है चूक। सेम से प्रबंधित लेनदेन का उपयोग करने के लिए निम्न टिप्पणी जोड़ने:

@TransactionManagement (TransactionManagementType.BEAN)

उस की तुलना में यह करने के लिए अधिक है, लेकिन यह है कि कहानी की शुरुआत है।

संबंधित मुद्दे