2010-09-29 3 views
9

मान लीजिए कि आप स्प्रिंग के साथ जेपीए का उपयोग करते हैं, जिसमें हाइबरनेट को जेपीए कार्यान्वयन के रूप में उपयोग किया जाता है। जेपीए लेनदेन मोड "जेटीए" है, इसलिए आपको कंटेनर लेनदेन प्रबंधक को हाइबरनेट में पास करने की आवश्यकता है। शास्त्रीय उत्तर hibernate.transaction.manager_lookup_class को आपके सर्वर के लिए मेल खाने वाले वर्ग में सेट करना है।जेपीए/हाइबरनेट में स्प्रिंग परिभाषित लेनदेन प्रबंधक का उपयोग

हालांकि, मुझे लगता है कि यह सर्वर विशिष्ट कॉन्फ़िगरेशन पर निर्भर होने के लिए शर्म की बात है क्योंकि आपको स्प्रिंग में <tx:jta-transaction-manager> के साथ लेनदेन प्रबंधक मिल गया है।

वहाँ एक रास्ता तरह

<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceUnitName" value="persistence_unit_name"/> 
    <property name="jpaVendorAdapter"> 
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> 
    </property> 
    <property name="jpaProperties"> 
    <props> 
    <prop key="hibernate.transaction.manager_lookup_class"> 
    org.hibernate.transaction.SunONETransactionManagerLookup 
    </prop> 
    </props> 
    </property> 
</bean> 

<tx:jta-transaction-manager/> 

लक्ष्य org.hibernate.transaction.SunONETransactionManagerLookup संपत्ति से छुटकारा पाने के लिए है एक विन्यास के साथ हाइबरनेट को यह transactionManager दे रहा है। वैसे, मेरे मन में वास्तव में दो अलग-अलग सर्वर कार्यान्वयन हैं।

संपादित करें: लेन-देन प्रबंधक विन्यास के बिना, हाइबरनेट chokes जब EntityManagerFactory बनाने:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in URL [file:/C:/configuration/afoCuad-metier-ear/entitymanager-base-context.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: fr.tm.ima.cuad-afoCuad-metier-ejb-PU] Unable to build EntityManagerFactory 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291) 
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) 
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:529) 
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:495) 
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:656) 
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:629) 
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:147) 
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) 
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:338) 
... 80 more 
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: fr.tm.ima.cuad-afoCuad-metier-ejb-PU] Unable to build EntityManagerFactory 
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:901) 
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:74) 
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225) 
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417) 
... 93 more 
Caused by: org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager 
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:401) 
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385) 
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954) 
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:892) 
... 98 more 

उत्तर

1

दुर्भाग्य से अगर एक कई अन्य JBoss उत्पादों की तरह हाइबरनेट एपीआई पर लग रहा है वे यदि सभी मुख्य config सामान नहीं सबसे धारण करने के लिए एक एक वर्ग आम तौर पर कहा जाता है विन्यास है। दुर्भाग्यवश वे (जेबॉस) उदाहरणों का पता लगाने के लिए पैरामीटर और कक्षा के लिए "स्ट्रिंग्स" पकड़ना पसंद करते हैं। लगभग हमेशा एक वास्तविक प्रीमियर सेट अप करने के लिए तैयार करना असंभव है।

मैं के बारे में बहुत ही कारण है कि आप उल्लेख कर रहे हैं के लिए निम्न जैसा कुछ कोशिश कर रहा हूँ।

  • TransactionManagerLookup
  • के एक कार्यान्वयन बनाएँ सेटर जो एक टीएम लेता है और एक धागा स्थानीय चर + उदाहरण सेट शामिल हैं।
  • आपके द्वारा कॉन्फ़िगरेशन में पास की गई संपत्तियों के अंदर TML का नाम पास करें।
  • जब आपका टीएमएल स्टार्टअप थ्रेड स्थानीय चर को आपके इंस्टेंस में कॉपी करता है fie.d.
  • सबकुछ पूरा होने के बाद थ्रेडलोकल साफ़ करें।
+0

ठीक है, धन्यवाद, मुझे लगता है कि सही anwser हाइबरनेट के लिए एक बग खोलना होगा, क्योंकि यह उनकी तरफ से कॉन्फ़िगर करने योग्यता है जो गलती है। – mleduque

0

मैं हाल ही में जेपीए/Grails और विन्यास मैं प्रयोग किया जाता के साथ कुछ सामान कर रहा हूँ इन पंक्तियों के साथ किया गया था:

क्या यह मदद करता है?

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="entityManagerFactory" ref="entityManagerFactory"/> 
</bean> 

<bean id="entityManagerFactory" class="org.hibernate.ejb.EntityManagerFactoryImpl"> 
<constructor-arg index="0" ref="sessionFactory"/> 
<constructor-arg index="1"> 
    <bean id="javax.persistence.spi.PersistenceUnitTransactionType.RESOURCE_LOCAL" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" /> 
</constructor-arg> 
<constructor-arg index="2" value="true"/> 
<constructor-arg index="3"><null/></constructor-arg> 
</bean> 
+0

ठीक है, तुम सच में एक ही बात JTA साथ नहीं कर सकते। – mleduque

5

सबसे पहले - आप वास्तव में जरूरत JTA करते हैं? आमतौर पर वसंत + हाइबरनेट को इसकी आवश्यकता नहीं होती है। आप एक साधारण JpaTransactionManager/HibernateTransactionManager का उपयोग कर सकते हैं।

यदि आप वास्तव में जेटीए चाहते हैं, तो आपको एक जेटीए प्रदाता की आवश्यकता होगी। यदि किसी अनुप्रयोग सर्वर में नहीं चल रहा है, तो Servlet कंटेनर में JTA का उपयोग करने के लिए this question देखें। कंटेनर से प्रबंधित लेनदेन के लिए (इसके अलावा this question पर एक नज़र डालें)

अंत में, hibernate docs कि निर्दिष्ट करते हैं,:

घोषणात्मक लेनदेन सीमांकन EJB, भी कंटेनर से प्रबंधित लेनदेन के रूप में जाना एक मानक सुविधा है (CMT) । ईजेबी 2.x में आप अपनी लेनदेन असेंबली बनाने के लिए एक्सएमएल परिनियोजन वर्णनकर्ताओं का उपयोग करेंगे। ईजेबी 3.x में आप सीधे अपने स्रोत कोड में जेडीके 5.0 एनोटेशन मेटाडेटा का उपयोग कर सकते हैं, बहुत कम वर्बोज़ दृष्टिकोण। हाइबरनेट विन्यास में EJBs के लिए CMT लेनदेन सीमांकन सक्षम करने के लिए:

  • अपने जेईई कंटेनर
  • org.hibernate.transaction.CMTTransactionFactory

दूसरी बात करने के लिए सेट hibernate.transaction.factory_class के लिए निर्धारित hibernate.transaction.manager_lookup_class एक देखने रणनीति के लिए शायद आप कुछ है ' क्या चूक गया

उस (अगले खंड) के अलावा दस्तावेज़ क्या कहता है कि यदि आप घोषणात्मक लेनदेन चाहते हैं, तो हाइबरनेट वह जगह नहीं है जहां आपको देखना चाहिए। आपको एक इंटरसेप्टर बनाना होगा। वसंत लेनदेन प्रबंधक वास्तव में क्या हैं। और यह मेरी पसंद होगी कि आपकी तकनीक का ढेर (वसंत) दिया जाए।

यदि आप एक जेटीए प्रदाता पर भरोसा नहीं करना चाहते हैं, तो दो बिल्ड करें।उदाहरण के लिए मेवेन में "मैवेन प्रोफाइल" है, जो विभिन्न वातावरणों के लिए निर्माण करने की अनुमति देता है।

+0

हां, जेटीए आवश्यक है। मुझे आश्चर्य है कि लोग हमेशा मानते हैं कि तत्वों में से किसी एक को छोड़कर किसी प्रश्न का उत्तर देना संभव है। 'Lookup_class' और 'factory_class' के लिए, मुझे उस भाग को याद नहीं आया, लेकिन मुझे * जेईई कंटेनर पर निर्भर नहीं होना चाहिए, एप्लिकेशन को कम से कम दो अलग-अलग एप्लिकेशन सर्वर पर तैनात किया जाना चाहिए। – mleduque

+0

@mleduque लोग प्रौद्योगिकी पर व्यापक दृष्टिकोण वाले लोगों को अपने अनुभव के कारण कुछ चीजें मानते हैं। उदाहरण के लिए मैंने शायद ही कभी जेटीए के साथ एक वसंत ऐप देखा है, जबकि मैंने कई मामलों को देखा है जब लोग इसे वास्तव में आवश्यकता के बिना इसमें फेंक देते हैं। आपकी बाकी टिप्पणी के लिए - मेरा अपडेट देखें। – Bozho

+0

कोई भी स्प्रिंग टीएम परत का उपयोग क्यों नहीं करेगा ... यह अलग-अलग विधि नामों के साथ बस एक और परत नहीं करता है और जेटीए पर कोई नई या बेहतर कार्यक्षमता नहीं जोड़ता है। अंत में यह एक जेएनडीआई लुकअप करने जा रहा है (यदि कोई जेटीए इम्प्लस का उपयोग करता है) जो जादू स्ट्रिंग्स और सिंगलेट्स की एक ही समस्या में समाप्त होता है। –