2010-11-11 16 views
9

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

<bean id="myDataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"> 
     <property name="targetDataSource" ref="targetDataSource"/> 
    </bean> 

    <bean id="targetDataSource" class="org.apache.commons.dbcp.BasicDataSource" 
      destroy-method="close" lazy-init="true" scope="singleton"> 
     <!-- settings here --> 
    </bean> 

myDataSource सेम कोड में प्रयोग किया जाता है:

@Transactional 
void update() { 
    jdbcUpdate1(); 
    hibernateupdate1(); 
    jdbcUpdate2(); // results of hibernateupdate1() are not visible here  
} 

सभी कार्यों में एक ही डेटा स्रोत का उपयोग करने के लिए कॉन्फ़िगर कर रहे हैं। myDataSource.getConnection() JDBC कार्यों में कनेक्शन के साथ काम करने के लिए प्रयोग किया जाता है और

getHibernateTemplate().execute(new HibernateCallback() { 
      public Object doInHibernate(Session session) throws HibernateException, SQLException { 
       ... 
      } 
     }); 

हाइबरनेट समारोह में प्रयोग किया जाता है। धन्यवाद।

उत्तर

10

सबसे पहले, हाइबरनेट का उपयोग करते समय जेडीबीसी का उपयोग करने से बचें।

फिर, यदि आपको वास्तव में इसकी आवश्यकता है, तो Session.doWork(..) पर उपयोग करें। यदि आपके हाइबरनेट संस्करण में अभी तक यह विधि नहीं है, तो session.connection() से Connection प्राप्त करें।

+2

उन लोगों के लिए, जो Google से यहां आएंगे, इस समस्या के लिए मेरा समाधान। मैंने हाइबरनेट फ्लश फ़ंक्शन के अंत में session.flush() जोड़ा। इसके बाद, इसका परिणाम परिणाम अगले जेडीबीसी रीड फ़ंक्शन (उसी लेनदेन में) में उपलब्ध है। – alex543

2

आप JDBC का उपयोग करें और एक ही लेन-देन में हाइबरनेट यदि आप सही स्प्रिंग सेटअप का उपयोग कर सकते हैं:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory"/> 
</bean> 

<bean id="myDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager" ref="transactionManager"/> 
    <property name="target"> 
     <bean class="MyDaoImpl"> 
      <property name="dataSource" ref="dataSource"/> 
      <property name="sessionFactory" ref="sessionFactory"/> 
     </bean> 
    </property> 
    <property name="transactionAttributes"> 
     <props> 
      <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop> 
      <prop key="*">PROPAGATION_REQUIRED</prop> 
     </props> 
    </property> 
</bean> 

यह है कि आपके डीएओ की JDBC भाग JdbcTemplate का उपयोग करता है मान लिया गया है। एक कनेक्शन

  • लपेटें डेटा स्रोत आप जरूरी नहीं कि आप एक अपने डीएओ को पारित (लेकिन पाने के लिए

    • उपयोग DataSourceUtils.getConnection (javax.sql.DataSource): यह आपके पास कुछ विकल्प नहीं है, तो एक TransactionAwareDataSourceProxy

    उत्तरार्द्ध पसंद किया जाता है क्योंकि यह प्रॉक्सी डेटा स्रोत के अंदर DataSourceUtils.getConnection hidse साथ SessionFactory) को भेजना।

    यह निश्चित रूप से एक्सएमएल पथ है, इसे एनोटेशन के आधार पर परिवर्तित करना आसान होना चाहिए।

  • 2

    समस्या यह है कि, हाइबरनेट इंजन पर संचालन तत्काल SQL निष्पादन में का परिणाम नहीं है। आप इसे हाइबरनेट सत्र पर मैन्युअल रूप से flush पर कॉल कर सकते हैं। फिर हाइबरनेट में किए गए परिवर्तन समान लेनदेन के भीतर SQL कोड के लिए दृश्यमान होंगे। जब तक आप DataSourceUtils.getConnection कर के रूप में SQL कनेक्शन प्राप्त करने के लिए है, क्योंकि उसके बाद ही आप उन्हें ही लेन-देन में चला होगा ...

    विपरीत दिशा में, यह अधिक मुश्किल है, क्योंकि आप 1nd स्तर कैश है (सत्र कैश), और संभवतः दूसरे स्तर के कैश भी। द्वितीय स्तर के कैश के साथ डेटाबेस में किए गए सभी परिवर्तन हाइबरनेट के लिए अदृश्य होंगे, यदि पंक्ति कैश की जाती है, तब तक कैश समाप्त हो जाती है।

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