2010-03-11 14 views
14

ठीक बनाने नहीं, तो मैं अंत में दबाव सहकर्मी झुकाया है और शुरू कर दिया मेरी वेब अनुप्रयोग में वसंत का उपयोग कर: -) ...स्प्रिंग @Transactional आवश्यक लेनदेन

तो मैं लेन-देन से निपटने सामान पाने के लिए कोशिश कर रहा हूँ काम करने के लिए, और मैं बस इसे पाने के लिए प्रतीत नहीं कर सकता।

मेरे स्प्रिंग विन्यास इस तरह दिखता है:


<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:p="http://www.springframework.org/schema/p" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd 
          http://www.springframework.org/schema/tx 
          http://www.springframework.org/schema/tx/spring-tx.xsd"> 

    <bean id="groupDao" class="mil.navy.ndms.conops.common.dao.impl.jpa.GroupDao" lazy-init="true"> 
     <property name="entityManagerFactory" ><ref bean="entityManagerFactory"/></property> 
    </bean> 

<!-- enables interpretation of the @Required annotation to ensure that dependency injection actually occures --> 
    <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/> 

    <!-- enables interpretation of the @PersistenceUnit/@PersistenceContext annotations providing convenient 
     access to EntityManagerFactory/EntityManager --> 
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> 

    <!-- uses the persistence unit defined in the META-INF/persistence.xml JPA configuration file --> 
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="CONOPS_PU" /> 
    </bean> 

    <!-- transaction manager for use with a single JPA EntityManagerFactory for transactional data access 
     to a single datasource --> 
    <bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory"/> 
    </bean> 

    <!-- enables interpretation of the @Transactional annotation for declerative transaction managment 
     using the specified JpaTransactionManager --> 
    <tx:annotation-driven transaction-manager="jpaTransactionManager" proxy-target-class="true"/> 

</beans> 

persistence.xml:


    @Transactional(propagation=Propagation.REQUIRES_NEW) 
    protected final T saveOrUpdate (T model) 
    { 
     EntityManager em = emf.createEntityManager (); 
     EntityTransaction trans = em.getTransaction (); 

     System.err.println ("Transaction isActive() == " + trans.isActive ()); 

     if (em != null) 
     { 
      try 
      { 
       if (model.getId () != null) 
       { 
        em.persist (model); 
        em.flush(); 
       } 
       else 
       { 
        em.merge (model); 
        em.flush(); 
       } 
      } 
      finally 
      { 
       em.close(); 
      } 
     } 

     return (model); 
    } 

तो मैं:


<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> 

    <persistence-unit name="CONOPS_PU" transaction-type="RESOURCE_LOCAL"> 

    <provider>org.hibernate.ejb.HibernatePersistence</provider> 

    ... Class mappings removed for brevity... 

    <properties> 

     <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/> 

     <property name="hibernate.connection.autocommit" value="false"/> 
     <property name="hibernate.connection.username" value="****"/> 
     <property name="hibernate.connection.password" value="*****"/> 

     <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/> 
     <property name="hibernate.connection.url" value="jdbc:oracle:thin:@*****:1521:*****"/> 
     <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/> 
     <property name="hibernate.hbm2ddl.auto" value="create"/> 
     <property name="hibernate.show_sql" value="true"/> 
     <property name="hibernate.format_sql" value="true"/> 

    </properties> 

    </persistence-unit> 

</persistence> 

मेरे डोमेन वस्तु को बचाने के लिए डीएओ विधि इस तरह दिखता है मेरे परीक्षण मामले में निम्न कोड का उपयोग करके मेरे समूह ऑब्जेक्ट की एक प्रति सहेजने का प्रयास करें:

निम्नलिखित अपवाद के साथ

    context = new ClassPathXmlApplicationContext(configs); 
    dao = (GroupDao)context.getBean("groupDao"); 

    dao.saveOrUpdate (new Group()); 

यह बम:


javax.persistence.TransactionRequiredException: no transaction is in progress 
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:301) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) 
    at java.lang.reflect.Method.invoke(Method.java:600) 
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:341) 
    at $Proxy26.flush(Unknown Source) 
    at mil.navy.ndms.conops.common.dao.impl.jpa.GenericJPADao.saveOrUpdate(GenericJPADao.java:646) 
    at mil.navy.ndms.conops.common.dao.impl.jpa.GroupDao.save(GroupDao.java:641) 
    at mil.navy.ndms.conops.common.dao.impl.jpa.GroupDao$$FastClassByCGLIB$$50343b9b.invoke() 
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149) 
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622) 
    at mil.navy.ndms.conops.common.dao.impl.jpa.GroupDao$$EnhancerByCGLIB$$7359ba58.save() 
    at mil.navy.ndms.conops.common.dao.impl.jpa.GroupDaoTest.testGroupDaoSave(GroupDaoTest.java:91) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) 
    at java.lang.reflect.Method.invoke(Method.java:600) 
    at junit.framework.TestCase.runTest(TestCase.java:164) 
    at junit.framework.TestCase.runBare(TestCase.java:130) 
    at junit.framework.TestResult$1.protect(TestResult.java:106) 
    at junit.framework.TestResult.runProtected(TestResult.java:124) 
    at junit.framework.TestResult.run(TestResult.java:109) 
    at junit.framework.TestCase.run(TestCase.java:120) 
    at junit.framework.TestSuite.runTest(TestSuite.java:230) 
    at junit.framework.TestSuite.run(TestSuite.java:225) 
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196) 

इसके अलावा, मैं निम्नलिखित चेतावनी जब वसंत पहले शुरू होता है मिलता है। इन संदर्भ entityManagerFactory और transactionManager के बाद से, वे शायद समस्या पर कुछ प्रभाव पड़ता है, लेकिन मैं नहीं पता है कि उन्हें पर्याप्त समझने के लिए कर लिया है:


Mar 11, 2010 12:19:27 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization 
INFO: Bean 'entityManagerFactory' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 
Mar 11, 2010 12:19:27 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization 
INFO: Bean 'entityManagerFactory' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 
Mar 11, 2010 12:19:27 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization 
INFO: Bean 'jpaTransactionManager' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 
Mar 11, 2010 12:19:27 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization 
INFO: Bean '(inner bean)' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 
Mar 11, 2010 12:19:27 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization 
INFO: Bean '(inner bean)' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 
Mar 11, 2010 12:19:27 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization 
INFO: Bean 'org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 
Mar 11, 2010 12:19:27 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization 
INFO: Bean 'org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 
Mar 11, 2010 12:19:27 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 
INFO: Pre-instantiating singletons in org.s[email protected]37003700: defining beans [groupDao,org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor,entityManagerFactory,jpaTransactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor]; root of factory hierarchy 

है किसी को भी किसी भी विचार है कि मैं क्या याद कर रहा हूँ ? मैं पूरी तरह स्टम्प्ड हूँ ...

धन्यवाद

उत्तर

16

EntityManagerFactory.createEntityManager() से प्राप्त इकाई प्रबंधक का उदाहरण वसंत-प्रबंधित लेन-देन में भाग नहीं लेता है।

@PersistenceContext 
public void setEntityManager(EntityManager em) { ... } 
+1

मैंने अपने डीएओ कक्षा में @PersistenceContext जोड़ा। जब मैं इसे चलाता हूं तो मुझे मिलता है: java.lang.IllegalStateException: साझा EntityManager पर लेनदेन बनाने की अनुमति नहीं है - इसके बजाय org.springframework.orm.jpa पर स्प्रिंग लेनदेन या ईजेबी सीएमटी का उपयोग करें। शेरएन्टिटी मैनेजर क्रिएटर $ SharedEntityManagerInvocationHandler.invoke (SharedEntityManagerCreator.java:155) mil.navy.ndms.conops.common.dao पर $ proxy27.getTransaction (अज्ञात स्रोत) पर mil.navy.ndms.conops.common.dao.impl.jpa.GenericJPADao.saveOrUpdate (GenericJPADao.java:634) पर। impl.jpa.GroupDao.save (GroupDao.java:645) – Steve

+4

@Steve: आपको इस 'EntityManager' – axtavt

+1

पर 'getTransaction' को कॉल नहीं करना चाहिए। मुझे लगता है कि मैं कम से कम वर्तमान लेनदेन का निरीक्षण कर सकता हूं कि यह निर्धारित करने के लिए कि @ ट्रान्सएक्शनल एनोटेशन लेनदेन बना रहा था या नहीं। यह बस डीबगिन उद्देश्यों के लिए था, इसलिए जब मैंने इसे हटा दिया, तो मुझे अपना लेनदेन मिला। धन्यवाद ... – Steve

5

समस्या होने की संभावना आप का एक संयोजन के कारण होता है एक संरक्षित विधि व्याख्या, और proxy-target-class="true" का उपयोग कर। यह एक बुरा मिश्रण है। वसंत द्वारा उत्पन्न लेनदेन संबंधी प्रॉक्सी केवल सार्वजनिक एनोटेटेड विधियों के साथ ठीक से काम करेगी, लेकिन अगर वे नहीं हैं तो यह शिकायत नहीं करेगा।

या तो saveOrUpdate() विधि सार्वजनिक या बेहतर बनाने की कोशिश करें, अभी तक अपने डीएओ के लिए एक इंटरफ़ेस परिभाषित करें, और proxy-target-class="true" सेटिंग को हटा दें। यह सबसे सुरक्षित, सबसे अनुमानित तकनीक है।

+0

विधि के लिए स्कैन नहीं होगा विधि भी 'अंतिम' है। यह 'प्रॉक्सी-लक्ष्य-वर्ग = "सत्य" के उपयोग को रोकता है। – axtavt

+0

विधि बनाना सार्वजनिक रूप से उसी तरह विफल रहता है। – Steve

+0

फाइनल को हटाने से भी कोई प्रभाव नहीं पड़ा। – Steve

0

मेरे मामले में:

एक इकाई प्रबंधक प्राप्त करने के लिए हमेशा की तरह @PersistenceContext -annotated संपत्ति का उपयोग कर इसकी सुई है

वसंत MVC के साथ जेपीए का उपयोग करना - मेरी परीक्षण और कोड के सभी भाग गया बिना त्रुटि के ठीक - लक्षण यह था कि काम करता है कि मैं डेटाबेस की बचत नहीं करता, इससे कोई फर्क नहीं पड़ता कि मैंने क्या किया।

मैं मेरे मामले में ठीक मेरी applicationContext.xml और cglib-nodep-2.1_3.jar aopalliance-1.0.jar

निश्चित रूप से करने के लिए जोड़ने के लिए किया था। एनोटेशन-संचालित स्प्रिंग के बिना @ ट्रान्सएक्शनल एनोटेशन

+1

उन निर्भरताओं के अलावा आपका एप्लिकेशन Context.xml कैसे समाप्त हुआ? – Marcelo