2010-10-06 17 views
6

सारांश: अपवाद मुझे बता रहा है कि लेनदेन केवल पढ़ने के लिए है; एक डीबग println इंगित करता है कि मैं केवल पढ़ने के लिए मोड में नहीं हूँ।HIbernate InvalidDataAccessApiUsageException - केवल-पढ़ने के लिए मोड

कक्षाओं को इंटरनेट प्रकाशन के लिए संपादित किया गया - खेद है कि अगर मैंने कुछ गलत टाइप किया है लेकिन यह मुझे समस्या देने वाले कोड का जस्ट है। SaveOrUpdate अन्य ऑब्जेक्ट प्रकारों पर कॉल करते समय काम करता है लेकिन इस पर नहीं। मैंने डिफगिंग के रूप में saveOrUpdate को सहेजने के लिए println जोड़ा। मैंने अमूर्त वर्ग नहीं लिखा, मैं बस इसका उपयोग करने की कोशिश कर रहा हूं (और अब इसे डीबग करें)।

कोड के नीचे प्रासंगिक आउटपुट। कुछ निश्चित नहीं कि यहाँ से कहाँ जाना है।

जांच के बाद अद्यतन: मैं वसंत कॉन्फ़िगरेशन के कुछ अपडेट करने के बीच में भी रहा हूं और एक सहकर्मी ने इंगित किया है कि एक विधि जिसे मैंने अपडेटपैमरेटर कहा था, वसंत का उपयोग एक तरह से कर रहा था, और टूटी हुई विधि इसका उपयोग कर रही थी एक अन्य तरीके से। दुर्भाग्य से टूटा रास्ता जिस तरह से मैं कोशिश करने की कोशिश कर रहा था।

तो समस्या जिसे मैं अब समझता हूं वह यह है कि यदि मैं एक बीन प्राप्त करके विधि में "मैन्युअल रूप से" DataObjectDAOImpl को तुरंत चालू करता हूं, तो यह मुझे सही ढंग से हाइबरनेट पर लिखने की अनुमति देता है। यदि मैं उस बीन के लिए क्लास वेरिएबल सेट करने के लिए वसंत का उपयोग करता हूं तो मुझे इसे हर विधि में तुरंत चालू करने की आवश्यकता नहीं है, तो जब मैं एक ऐसी विधि तक पहुंचता हूं जो हाइबरनेट को लिखने का प्रयास करता है, तब भी यह रिपोर्ट करता है कि यह रिपोर्ट नहीं करता है केवल पढ़ने के लिए मोड। मेरे सहकर्मी के पास इस विषय पर एक सिद्धांत था लेकिन मुझे समझ में नहीं आया कि वह क्या कहने की कोशिश कर रहा था - नमूना क्लास से एक इंटरफ़ेस निकालने के बारे में कुछ।

// Old way that works. 
public class SampleClass { 
public void someMethod { 
ApplicationContext ac = ApplicationContextFactory.getApplicationContext(); 
DataObjectDAOImpl dodi = ((DataObjectDAOImpl) ac.getBean("dodi")); 
//this works 
dodi.updateAParameter("foo", exampleDataObject); 
} 
} 

//New way that doesn't work but I would like it to. 
public class SampleClass { 
private DataObjectDAOImpl dodi = null; 
//'dodi' has getter and setter methods that I am not pasting here for simplicity 
public void someMethod {  
//causes Exception 
dodi.updateAParameter("foo", exampleDataObject); 
} 
} 

और यहाँ वसंत config

<bean id="sampleclass" class="com.service.SampleClass" scope="prototype"> 
    <property name="dodi" ref="doDAOimpl"/> 
</bean> 
यहाँ

से प्रासंगिक सेम है DAOImpl जो पुराने और नए तरह से अनुप्रयोग सर्वर से

public class DataObjectDAOImpl extends AbstractSpringDaoStuff { 

... 

public void updateAParameter(String parameter, DataObject do) { 
    do.setAParameter(parameter); 
    super.saveOrUpdate(do); 
} 

} 


public abstract class AbstractSpringDaoStuff extends HibernateDaoSupport { 

    ... 

    @Transactional(readOnly=false) 
    protected void saveOrUpdate(Object obj) { 
    System.out.println ("Read-only?: " + TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 

     getHibernateTemplate().saveOrUpdate(obj); 
    }   
} 

आउटपुट के लिए एक ही है:

 [java] Read-only?: false 
    [java] - Method execution failed: 
    [java] org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition. 
    [java]  at org.springframework.orm.hibernate3.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1186) 
    [java]  at org.springframework.orm.hibernate3.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:750) 
    [java]  at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419) 
    [java]  at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374) 
    [java]  at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:748) 
    [java]  at com.est.dao.AbstractSpringDaoStuff.saveOrUpdate(AbstractSpringDaoMDA.java:24) 
etc 
+0

मैं ही सत्र संपत्ति बदल दिया है। समस्या सुलझ गयी। http://stackoverflow.com/a/13726254/159837 –

+0

getHibernateTemplate() getSessionFactory() getCurrentSession() setFlushMode (FlushMode.AUTO)।।। –

उत्तर

3

था ई एक संभावित समस्या यह है कि मैं यहां देख सकता हूं कि आप उसी बीन से @Transactional विधि को कॉल कर रहे हैं। मुझे यकीन नहीं है कि यह आपके अपवाद से कैसे संबंधित हो सकता है, लेकिन चूंकि स्प्रिंग के घोषणात्मक लेनदेन प्रबंधन प्रॉक्सी-आधारित एओपी के माध्यम से लागू किया गया है, इसका मतलब है कि यह एनोटेशन प्रभावी नहीं होता है।

यह भी देखें:

+0

धन्यवाद। मुझे एक ही त्रुटि मिल रही थी। मैंने अपनी विधि में '@ ट्रांसेक्शनल (readOnly = false) 'जोड़ा, और यह अब काम करता है। –

+0

प्रतिक्रिया पोस्ट करने के लगभग 2.5 साल बाद यह वास्तव में सहायक था। धन्यवाद एक टन, @axtavt। – Sid

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