2011-02-27 9 views
10

में हाइबरनेट लेनदेन प्रबंधक कॉन्फ़िगरेशन मेरी प्रोजेक्ट में मैं प्रोग्रामेटिक लेनदेन सीमांकन के साथ हाइबरनेट का उपयोग करता हूं। हर बार मेरी सेवा विधियों में मैं कुछ इसी तरह लिखता हूं।स्प्रिंग

Session session = HibernateUtil.getSessionFactory().openSession(); 
session.beginTransaction(); 
.. perform operation here 
session.getTransaction().commit(); 

अब मैं घोषणात्मक लेनदेन प्रबंधन के साथ अपने कोड को दोबारा करने जा रहा हूं। क्या मैं अब मिल गया ...

<context:component-scan base-package="package.*"/> 

    <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> 
    <property name="configurationClass"> 
     <value>org.hibernate.cfg.AnnotationConfiguration</value> 
    </property> 
    </bean> 

    <tx:annotation-driven transaction-manager="txManager"/> 


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

सेवा वर्ग:

@Service 
public class TransactionalService { 

    @Autowired 
    private SessionFactory factory; 

    @Transactional 
    public User performSimpleOperation() { 
     return (User)factory.getCurrentSession().load(User.class, 1L); 
    } 
} 

और साधारण परीक्षण - Lazy

@Test 
public void useDeclarativeDem() { 
    FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("spring-config.xml"); 
    TransactionalService b = (TransactionalService)ctx.getBean("transactionalService"); 
    User op = b.performSimpleOperation(); 
    op.getEmail(); 

जब मैं लेन-देन की विधि के बाहर मौजूद उपयोगकर्ता ईमेल प्राप्त करने की कोशिश, मुझे मिल गया प्रारंभिक अपवाद, ईमेल मेरा मामला एक साधारण स्ट्रिंग है। हाइबरनेट एसक्यूएल क्वेरी भी नहीं करता है, जब तक कि मैं अपने POJO पर किसी भी गेटर्स को कॉल नहीं करता।

1) मैं यहां क्या गलत कर रहा हूं?

2) क्या यह दृष्टिकोण मान्य है?

3) क्या आप किसी भी ओपन सोर्स प्रोजेक्ट का सुझाव दे सकते हैं जो एनोटेशन आधारित कॉन्फ़िगरेशन के साथ वसंत/हाइबरनेट पर काम करता है?

अद्यतन

किसी कारण से अगर मैं getCurrentSession की जगह openSession के साथ इस कोड ठीक काम करता है। क्या कोई इसे समझा सकता है?

धन्यवाद

+0

क्या एक उपयोगकर्ता के लिए एक अलग तालिका में ईमेल है? –

+0

उसी तालिका में सरल स्ट्रिंग – user12384512

उत्तर

10

ठीक है, अंततः मुझे एहसास हुआ कि समस्या क्या थी। उपरोक्त कोड में मैंने प्राप्त करने के बजाय लोड का उपयोग किया। सत्र.लोड वास्तव में डेटाबेस हिट नहीं किया था।यही वजह है कि मुझे @ ट्रान्सएक्शनल विधि

के बाहर आलसी-प्रारंभिक अपवाद क्यों मिलता है यदि मैं getCurrentSession के बजाय ओपनसेशन का उपयोग करता हूं, तो स्कोप वसंत कंटेनर के बाहर सत्र खोला जाता है। अगर वहाँ कोई मिलता-जुलता डेटाबेस पंक्ति है

पता है कि लोड() एक अप्राप्य अपवाद फेंक करेंगे: जैसा कि परिणाम सत्र बंद नहीं था और यह मेरे @Transactional विधि

2

कारण हाइबरनेट किसी भी एसक्यूएल प्रश्नों प्रदर्शन नहीं करता जब तक आप ही टिककर खेल फोन है, क्योंकि मेरा मानना ​​है कि FetchType आलसी को तैयार है। इस समस्या को दूर करने के लिए आप अपने POJO में उत्सुक करने के लिए FetchType बदलने के लिए की आवश्यकता होगी:

@Entity 
@Table(name = "user") 
public class User { 

    /*Other data members*/ 

    @Basic(fetch = FetchType.EAGER) 
    private String email; 

} 

मैं व्यक्तिगत रूप से नहीं था एक उत्सुक FetchType के लिए बुनियादी प्रकार निर्दिष्ट करने के लिए तो मैं पूरी तरह से यकीन है कि क्यों आपके विन्यास इस आवश्यकता नहीं हूँ। यदि यह केवल आपके परीक्षणों में है तो यह आपके JUnit परीक्षणों को कॉन्फ़िगर करने के तरीके के कारण हो सकता है।

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({"/test-app-config.xml"}) 
@Transactional 
public class UserServiceTest { 

} 

एक अच्छा संसाधन मैं हमेशा SpringByExample खोजने के मददगार के रूप में: यह वर्ग घोषणा पर कुछ इस तरह होना चाहिए।

संपादित

तो मैं पूरी तरह से यकीन है कि क्या आपके विन्यास के साथ कुछ गलत है नहीं कर रहा हूँ। यह मेरे द्वारा स्थापित किए गए तरीके से अलग है, इसलिए यह मेरी सामान्य विन्यास है कि यह मदद करता है कि यह मदद करता है। hibernate.transaction.factory_class एक प्रमुख संपत्ति हो सकती है जो आप गायब हैं। मैं AnnotationSessionFactoryBean:

<!-- DataSource --> 
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" 
    p:driverClassName="com.mysql.jdbc.Driver" 
    p:url="jdbc:mysql://localhost/dbname" 
    p:username="root" 
    p:password="password"/> 

<!-- Hibernate session factory --> 
<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" 
    p:dataSource-ref="dataSource"> 
    <property name="packagesToScan" value="com.beans"/> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> 
      <prop key="hibernate.show_sql">true</prop> 
      <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop> 
     </props> 
    </property> 
</bean> 

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

<tx:annotation-driven transaction-manager="transactionManager"/> 
+0

उत्तर के लिए धन्यवाद, वास्तव में उपयोगकर्ता के किसी भी क्षेत्र में कोई आलसी प्रारंभ नहीं है, और निश्चित रूप से मैंने सरल स्ट्रिंग के लिए फ़ेच रणनीति निर्दिष्ट नहीं की है। मेरा मानना ​​है कि समस्या वसंत विन्यास में है – user12384512

+0

क्या आप कृपया अपने LazyInitializationException के स्टैक ट्रेस पोस्ट कर सकते हैं? ऐसा लगता है कि अगर आप अपवाद प्राप्त कर रहे हैं तो आलसी प्रारंभिकता का कुछ रूप नहीं होगा। –

+0

त्रुटि org.hibernate.LazyInitializationException - प्रॉक्सी सक्रिय नहीं कर सका - कोई सत्र org.hibernate.LazyInitializationException: प्रॉक्सी सक्रिय नहीं कर सका - कोई सत्र \t org.hibernate.proxy.AbstractLazyInitializer.initialize पर (AbstractLazyInitializer.java:132) \t org.hibernate.proxy.AbstractLazyInitializer.getImplementation (AbstractLazyInitializer.java:174) \t org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke (JavassistLazyInitializer.java:190) पर – user12384512

0

के बाहर वस्तु गुण पढ़ने के लिए हाइबरनेट प्रलेखन https://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html/ch11.html#objectstate-loading से अनुमति देते हैं । यदि वर्ग को प्रॉक्सी से मैप किया गया है, तो लोड() केवल एक अनियमित प्रॉक्सी देता है और जब तक आप प्रॉक्सी की विधि नहीं ले लेते तब तक डेटाबेस को वास्तव में हिट नहीं करते हैं। यह उपयोगी है यदि आप किसी ऑब्जेक्ट को वास्तव में डेटाबेस से लोड किए बिना किसी संगठन को बनाना चाहते हैं। क्लास मैपिंग के लिए बैच-आकार परिभाषित होने पर यह कई उदाहरणों को बैच के रूप में लोड करने की अनुमति देता है।

आपके मामले में उपरोक्त दस्तावेज से बीन वसंत प्रॉक्सी के साथ मैप किया गया है, इसलिए लोड केवल रिटर्न। इसलिए आपको लोड() के बजाय get() का उपयोग करने की आवश्यकता है जो हमेशा डेटाबेस को हिट करता है।