Spring application doesn't appear to be persisting data

后端 未结 6 2042
甜味超标
甜味超标 2021-01-20 13:07

I\'m trying to write something into my database but it\'s not working despite it reporting \"Successfully completed request\". After the success everything seems to work fin

相关标签:
6条回答
  • after creating transactionManager bean you should enable the transaction in Xml file,

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

    or

    < tx:annotation-driven />

    if u written 2nd one then you have to use @Transaction() in your DAO class,

    if any method required the transaction then before that write

    @Transactional(propagation=Propagation.REQUIRED, readOnly=false)

    it tell that transaction is require and readOnly=false means you can read and write the data.

    0 讨论(0)
  • 2021-01-20 13:48

    managed to find the problem. Spring Docu "@EnableTransactionManagement and only looks for @Transactional on beans in the same application context they are defined in." Meaing in my payment-servlet.xml i had no <tx:annotation-driven /> thats why there was no active transaction.

    0 讨论(0)
  • 2021-01-20 13:51

    It seems you miss the @Transactional annotation at the start of your DAO implementation class. It would explain why you don't have any transaction opened.

    If it is not enough to solve your problem, could you give us your complete DAO implementation class ?

    0 讨论(0)
  • 2021-01-20 13:57

    Looking at your applicationContext.xml again, I noticed you're not assigning an entityManager with your transactionManager declaration. I'm not sure if Spring will implicitly set it, but if it doesn't it would explain why your persists are not working.

    For example, change:

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

    UPDATE

    I've only configured Spring+JPA with Container-managed Entity (looks like your intention as well) - never really Application-managed. From what I know, in Container-managed with Spring, you don't really need to configure a Persistent Unit. I'm not 100% sure if this will help but try changing how your entityManagerFactory is declared in applicationContext.xml.

    <bean id="entityManagerFactory"
       class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    
       <property name="dataSource" ref="dataSource" />
    
       <property name="packagesToScan" value="com.app.payment" />   
    
       <property name="persistenceProvider">
          <bean class="org.hibernate.ejb.HibernatePersistence" />
       </property>
    
       <property name="jpaProperties">
          <props>
             <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
             <prop key="hiberate.show_sql">true</prop>
             ... //additional props
          </props> 
       </property>
    </bean>
    
    0 讨论(0)
  • 2021-01-20 13:58

    When using annotation-driven transactions, you should put @Transactional annotation before your methods which are working with database. It could be either your DAO or Service methods. I can see that you have put @Transactional on top of PaymentServiceImpl but that is not the right place for that annotation.

    0 讨论(0)
  • 2021-01-20 14:03

    Make sure that you don't have exact duplicate <context:component-scan .../> elements in both xml configurations. If you have this you are basically duplicating all your bean instances. What you initially had was all beans get loaded by the ContextLoaderListener and those are proxied due to the existence of <tx:annotation-driven />.

    Now if you have the same <context:component-scan .../> in your payment-servlet.xml this is going to scan again for all beans creating another instance, however due to the fact that there is no <tx:annotation-driven /> it will not be proxied and no transactions applied.

    What now happens is that as soon as you need one of your @Service annotated beans the DispatcherServlet looks first in its own ApplicationContext to see if there is bean to satisfy its needs. If there is it is going to be used (your current case) if there isn't it will consult the parent context (the one loaded by the ContextLoaderListener).

    What you need to do is configure the ContextLoaderListener to scan for everything BUT @Controller annotated beans and the DispatcherServlet to scan ONLY for @Controller annotated beans. This can be done by configuring the <context:component-scan .../> correctly.

    applicationContext.xml

    <context:component-scan base-package="com.appn.payment">
      <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
    

    payment-servlet.xml

    <context:component-scan base-package="com.appn.payment" use-default-filters="false">
      <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
    

    This will give you transactions and only single instances of your beans. You should remove the <tx:annotation-driven /> from the payment-servlet.xml file.

    There is still an open JIRA issue to have this included in the reference guide. Also a thread in the Spring Community Forums explaining this.

    0 讨论(0)
提交回复
热议问题