Announcement Announcement Module
Collapse
No announcement yet.
Rollback doesn't work for my standalone Spring app Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Rollback doesn't work for my standalone Spring app

    Hello,

    I am working on a standalone spring/jpa/hibernate application.

    The problem I am experiencing is that my app won't rollback transactions even though a RuntimeException is raised.

    Here is my config:

    Code:
     <context:annotation-config />
        <context:component-scan base-package="com.jeanbaptistemartin"/>
        <context:property-placeholder location="classpath:application.properties"/>
        <bean id="gestionnaireMailing" class="com.jeanbaptistemartin.desktop.JFrameGestionnaireMailing" init-method="init" >
               
        </bean>
        
        <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
            <property name="configLocation" value="classpath:ehcache.xml"/>
            <property name="shared" value="true"/>
        </bean>
        
        <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
            <property name="host" value="${mail.server}"/>
            <property name="port" value="${mail.port}"/>
            <property name="javaMailProperties">
                <props>
                    <prop key="mail.smtp.connectiontimeout">2000</prop>    
                    <prop key="mail.smtp.timeout">2000</prop>    
                </props>    
            </property>
        </bean>
        <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
            <property name="velocityProperties">
                <value>
                resource.loader=class
                class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
                </value>
            </property>
        </bean>
        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="persistenceUnitName" value="jbmPU" />
            <property name="persistenceXmlLocation" value="classpath:/META-INF/persistence.xml" />
            <property name="dataSource" ref="dataSource" />
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="showSql" value="${database.showSql}" />
                    <property name="generateDdl" value="${database.generateDdl}"/>
                    <property name="databasePlatform" value="${database.dialect}"/>
                </bean>
            </property>
        </bean>
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${database.driver}"/>
            <property name="jdbcUrl" value="${database.url}"/>
            <property name="user" value="${database.username}"/>
            <property name="password" value="${database.password}"/>
            <property name="minPoolSize" value="5" />
            <property name="maxPoolSize" value="20" />
            <property name="idleConnectionTestPeriod" value="3000" />
            <property name="loginTimeout" value="300" />
        </bean>
        <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <tx:annotation-driven transaction-manager="transactionManager" />
    My transactional method:
    Code:
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {RuntimeException.class})
        public boolean mailAbonne(List<Sculpture> sculpturesChoisiesPourMailing, Abonne abonne) {
            try {
                for (Sculpture sculpture : sculpturesChoisiesPourMailing) {
                    MailingAbonnePK mapk = new MailingAbonnePK(sculpture.getSculptureID(), abonne.getAbonneID());
                    MailingAbonne ma = new MailingAbonne(mapk, new Date());
                    dao.persistMailingAbonnee(ma);
                }
                envoyerMail(sculpturesChoisiesPourMailing, abonne);//this method sometimes throws a RuntimeException.
                return true;
            } catch (RuntimeException e) {
                log.error("Exception");
                log.error(e);
                throw new RuntimeException();
            }
        }
    In my dao:
    Code:
    @PersistenceContext(type = PersistenceContextType.TRANSACTION)
        private EntityManager entityManager;

    Here is the only relevant info I found in the logs:
    Code:
     INFO [12:39:31,362] (TransactionFactoryFactory.java:62) - Transaction strategy: org.hibernate.transaction.JDBCTransactionFactory
     INFO [12:39:31,363] (TransactionManagerLookupFactory.java:80) - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
    ...
    DEBUG [13:09:07,250] (AbstractFallbackTransactionAttributeSource.java:106) - Adding transactional method 'mailAbonne' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '',-java.lang.RuntimeException
    Now a word about the current behaviour of my app:

    when a RuntimeException or a subclass thereof is raised by envoyerMail the apps just hangs indefinitely.

    Now another word about the desired behaviour of my app.

    My mailAbonne method is called in a loop as follows:
    Code:
     for (Abonne abonne : totalAbonnes) {
       mailAbonne(sculpturesChoisiesPourMailing, abonne);
    }
    Ideally I would like for one iteration of the loop to fail or succeed atomically i.e. if a RuntimeException is raised at iteration 3 out of a total of 5 iterations, I would then have in my database, data corresponding to the 4 successfull iterations and the data corresponding to the failed iteration would be rolledback.

    Can anyone please help?
    J.

  • #2
    you have this line in your code

    Code:
    <tx:annotation-driven transaction-manager="transactionManager" />
    but I can't see the actual transaction manager being created.

    Make sure you add the bean org.springframework.orm.hibernate3.HibernateTransa ctionManager

    fede

    Comment


    • #3
      thanks for your reply chiwi,
      I do have a transactionManager defined - have a look at my XML. Here it is:
      Code:
      <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
              <property name="entityManagerFactory" ref="entityManagerFactory" />
              <property name="dataSource" ref="dataSource"/>
          </bean>
      Any other idea?
      J.

      Comment

      Working...
      X