Announcement Announcement Module
Collapse
No announcement yet.
Spring web flow and transactions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring web flow and transactions

    Hi

    I'm using sping 3.0.2, web flow 2.0.9, richfaces and hibernate on Jboss Web.
    My problem is that I cannot run my methods in transactions. This are some parts of my configuration.

    Code:
    	<tx:annotation-driven />
    	
    	<bean id="entityManagerFactory"
    		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    		<property name="jpaVendorAdapter">
    			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    				<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
                    <property name="generateDdl" value="false" />
    			</bean>
    		</property>
            <property name="jpaProperties">
             <props>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.use_query_cache">true</prop>
                <prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>
                <prop key="hibernate.cache.generate_statistics">false</prop>
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
                <prop key="net.sf.ehcache.configurationResourceName">broker_ehcache.xml</prop>
             </props>
    		</property>
    	</bean>
    
    	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        	<property name="jndiName" value="java:comp/env/jdbc/BrokerDB" />
    	</bean>
    
    	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"/>
    I'm using a tomcat provided connection pool

    Code:
    <Resource name="jdbc/BrokerDB" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000"
                   ... driverClassName="org.gjt.mm.mysql.Driver" url="..."/>
    Code:
    	<webflow:flow-executor id="flowExecutor">
    	    <webflow:flow-execution-repository  
                max-executions="5" max-execution-snapshots="10" />
                <webflow:flow-execution-attributes>
                    <webflow:always-redirect-on-pause value="true"/>            
                </webflow:flow-execution-attributes>
    		<webflow:flow-execution-listeners>
    			<webflow:listener ref="jpaFlowExecutionListener" />
    			<webflow:listener ref="securityFlowExecutionListener" />
    			<webflow:listener ref="methodLockFlowExecutionListener" />
    		</webflow:flow-execution-listeners>
    	</webflow:flow-executor>
    ...
    	<bean id="jpaFlowExecutionListener"
    		class="org.springframework.webflow.persistence.JpaFlowExecutionListener">
    		<constructor-arg ref="entityManagerFactory" />
    		<constructor-arg ref="transactionManager" />
    	</bean>
    I'm using <persistence-context/> in my flow definitions to avoid the LazyInitializationException

    Also something that might be important is that I'm using in my web.xml the contextConfigLocation parameter to load all the configurations and the configuration for the spring servlet is empty
    Code:
     <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/config/main.xml</param-value>
     </context-param>
     <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
     </listener>
    ...
     <servlet>
      <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>/WEB-INF/config/empty.xml</param-value>
      </init-param>
      <load-on-startup>2</load-on-startup>
     </servlet>
    When I press a button I call this transition
    Code:
            <transition on="save">
                <evaluate expression="agencyContractsService.save(contract)" />        
                <render fragments="contract-buttons"/>
            </transition>
    And this is the definition of the method

    Code:
        @Transactional
        public String save(AgencyContract entity) {
            agenciesService.save(entity.getAgency());
            return super.save(entity);
        }
    I put the transaction log to DEBUG and what I can see when invoking the method is this:
    Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''

    When I remove the <persistence-context/> from my flow definition the debug message doesn't occure.

    My real problem is that if the super.save(entity) throws an exception, swill the agenciesService.save(entity.getAgency()); makes changes to the DB and if the entity is attached and there are modifications on some fields in that entity they are saved in the DB also.

    I completely don't have idea what is my problem or if I'm using the <persistence-context/> right

    Thanks for the help.

  • #2
    I am not quite sure about your problem
    But I think it will be helpful if you take a look at the ACID principals and transaction levels in hibernate.
    You may need to raise your level of transaction.

    Comment


    • #3
      My problem is that the methods are not executed is transactions. If I have my methods in transactions then probably the rollback will work and in case of exception the changes to the attached entities will not affect the DB.

      I guess that it is configuration problem.
      I read some posts with similar problems and there was some issue with that the configurations are loaded with the configuration listener, not with the spring servlet. I tried and this is not my case.

      Comment


      • #4
        I found my problem.

        First all the time I have had transactions. The reason I was not seeing them in the log was the log4j configuration:
        Code:
        log4j.logger.org.springframework=DEBUG
        log4j.logger.org.springframework.transaction=DEBUG
        shows them and
        Code:
        log4j.logger.org.springframework=INFO
        log4j.logger.org.springframework.transaction=DEBUG
        doesn't.

        Second my problem was that when I call a method and I validation error occurs I throw a specific runtime exception, which is caught in aspect (the aspect displays the error message on the current page). Since the exception is caught no rollback occurs. I put TransactionAspectSupport.currentTransactionStatus( ).setRollbackOnly(); in the aspect and now it is working. I guess that my aspect is invoked after the transaction aspect, which I don't know how to configure.

        Thanks for the help and sorry for the wasted time.

        Comment

        Working...
        X