Announcement Announcement Module
Collapse
No announcement yet.
no rollback in transaction problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • no rollback in transaction problem

    Hi,

    I'm using JPA managed by spring, and I'm new in this domain.

    I'm facing a problem that I'm trying to manage some runtime exception on my service from a dao merge action. I want to manage mainly duplicate entry.

    The thing is that i tryed many solutions but I have a problem.

    I catched the EntityExistException on my dao and i return MyException with a throw MyException from the interface of my dao.
    My service seems to manage correctly this exception by try to insert a new entity with a new data (with increment). And it try to make a new merge wich seems to succeed, expect it doesn't commit and i get this error :

    Code:
    Exception in thread "main" org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
    	at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:465)
    	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
    	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
    	at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    	at $Proxy63.findValidLogin(Unknown Source)
    	at org.esco.sarapis.db.domain.gestion.impl.InsertManagerImpl.main(InsertManagerImpl.java:116)
    Caused by: javax.persistence.RollbackException: Transaction marked as rollbackOnly
    	at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:51)
    	at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:456)
    	... 8 more
    Also here is my LOG :
    Code:
    7828 DEBUG  [main] AbstractBeanFactory           - Returning cached instance of singleton bean 'loginAliasManagerImpl'
    7828 DEBUG  [main] AbstractBeanFactory           - Returning cached instance of singleton bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
    7844 DEBUG  [main] AbstractPlatformTransactionManager     - Using transaction object [org.springframework.orm.jpa.JpaTransactionManager$JpaTransactionObject@1bca1c3]
    7844 DEBUG  [main] AbstractPlatformTransactionManager     - Creating new transaction with name [org.esco.sarapis.db.domain.gestion.ILoginAliasManager.findValidLogin]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
    7859 DEBUG  [main] JpaTransactionManager         - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@1b38cdc] for JPA transaction
    7922 DEBUG  [main] DriverManagerDataSource       - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/JSarapis]
    7953 DEBUG  [main] JpaTransactionManager         - Exposing JPA transaction as JDBC transaction [SimpleConnectionHandle: com.mysql.jdbc.Connection@101fa9e]
    7953 DEBUG  [main] TransactionSynchronizationManager     - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@14560cf] for key [[email protected]7] to thread [main]
    7969 DEBUG  [main] TransactionSynchronizationManager     - Bound value [org.springframework.orm.jpa.EntityManagerHolder@1071e12] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@4745cf] to thread [main]
    7969 DEBUG  [main] TransactionSynchronizationManager     - Initializing transaction synchronization
    7969 DEBUG  [main] TransactionAspectSupport      - Getting transaction for [org.esco.sarapis.db.domain.gestion.ILoginAliasManager.findValidLogin]
    7969 INFO   [main] LoginAliasManagerImpl         - Create new Login : aaaaa
    7969 INFO   [main] LoginAliasManagerImpl         - Try to insert Login
    7969 DEBUG  [main] GenericDaoImpl                - Merging org.esco.sarapis.db.entity.personne.Login instance
    7969 DEBUG  [main] TransactionSynchronizationManager     - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@1071e12] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@4745cf] bound to thread [main]
    Hibernate: insert into Login (nom) values (?)
    8016 ERROR  [main] JDBCExceptionReporter         - Duplicate entry 'aaaaa' for key 2
    8016 ERROR  [main] GenericDaoImpl                - Merge failed - Entity already exists : org.hibernate.exception.ConstraintViolationException: could not insert: [org.esco.sarapis.db.entity.personne.Login]
    8016 DEBUG  [main] GenericDaoImpl                - ====>>> duplicate entry.
    8016 DEBUG  [main] LoginAliasManagerImpl         - Interception de l'erreur : org.hibernate.exception.ConstraintViolationException: could not insert: [org.esco.sarapis.db.entity.personne.Login]
    8016 DEBUG  [main] TransactionAspectSupport      - Completing transaction for [org.esco.sarapis.db.domain.gestion.ILoginAliasManager.findValidLogin]
    8016 DEBUG  [main] AbstractPlatformTransactionManager     - Triggering beforeCommit synchronization
    8016 DEBUG  [main] AbstractPlatformTransactionManager     - Triggering beforeCompletion synchronization
    8016 DEBUG  [main] AbstractPlatformTransactionManager     - Initiating transaction commit
    8016 DEBUG  [main] JpaTransactionManager         - Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@1b38cdc]
    8047 DEBUG  [main] AbstractPlatformTransactionManager     - Triggering afterCompletion synchronization
    8062 DEBUG  [main] TransactionSynchronizationManager     - Clearing transaction synchronization
    8062 DEBUG  [main] TransactionSynchronizationManager     - Removed value [org.springframework.orm.jpa.EntityManagerHolder@1071e12] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@4745cf] from thread [main]
    8062 DEBUG  [main] TransactionSynchronizationManager     - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@14560cf] for key [[email protected]7] from thread [main]
    8062 DEBUG  [main] JpaTransactionManager         - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@1b38cdc] after transaction
    8062 DEBUG  [main] EntityManagerFactoryUtils     - Closing JPA EntityManager
    I tryed also with an aop config but I have the same problem...

    I'm using spring 2.5.5 with hibernate-entityManager-3.3.2GA

    Is there someone who has an idea of my problem ? If you need some code ask me the part that you want.

    Thanks

  • #2
    nobody has any idea ?

    This is the exact trace log :

    Code:
    12765 DEBUG  [main] AbstractBeanFactory           - Returning cached instance of singleton bean 'loginAliasManagerImpl'
    12765 DEBUG  [main] AbstractBeanFactory           - Returning cached instance of singleton bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
    12765 DEBUG  [main] AbstractFallbackTransactionAttributeSource     - Adding transactional method [findValidLogin] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT]
    12781 DEBUG  [main] AbstractPlatformTransactionManager     - Using transaction object [org.springframework.orm.jpa.JpaTransactionManager$JpaTransactionObject@15e8aa5]
    12781 DEBUG  [main] AbstractPlatformTransactionManager     - Creating new transaction with name [org.esco.sarapis.db.domain.gestion.ILoginAliasManager.findValidLogin]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
    12796 DEBUG  [main] JpaTransactionManager         - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@117b450] for JPA transaction
    12843 DEBUG  [main] SessionImpl                   - opened session at timestamp: 12174076545
    12843 DEBUG  [main] JDBCTransaction               - begin
    12843 DEBUG  [main] ConnectionManager             - opening JDBC connection
    12843 DEBUG  [main] DriverManagerDataSource       - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/JSarapis]
    12859 DEBUG  [main] JDBCTransaction               - current autocommit status: true
    12859 DEBUG  [main] JDBCTransaction               - disabling autocommit
    12859 DEBUG  [main] JDBCContext                   - after transaction begin
    12875 DEBUG  [main] JpaTransactionManager         - Exposing JPA transaction as JDBC transaction [SimpleConnectionHandle: com.mysql.jdbc.Connection@1332109]
    12875 DEBUG  [main] TransactionSynchronizationManager     - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@1bde3d2] for key [[email protected]c9] to thread [main]
    12875 DEBUG  [main] TransactionSynchronizationManager     - Bound value [org.springframework.orm.jpa.EntityManagerHolder@856d3b] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@1c67b54] to thread [main]
    12875 DEBUG  [main] TransactionSynchronizationManager     - Initializing transaction synchronization
    12875 DEBUG  [main] TransactionAspectSupport      - Getting transaction for [org.esco.sarapis.db.domain.gestion.ILoginAliasManager.findValidLogin]
    12875 INFO   [main] LoginAliasManagerImpl         - Create new Login : aaaaa
    12875 INFO   [main] LoginAliasManagerImpl         - Try to insert Login
    12875 DEBUG  [main] GenericDaoImpl                - Merging org.esco.sarapis.db.entity.personne.Login instance
    12890 DEBUG  [main] TransactionSynchronizationManager     - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@856d3b] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@1c67b54] bound to thread [main]
    12906 DEBUG  [main] IdentifierValue               - id unsaved-value: 0
    12906 DEBUG  [main] AbstractSaveEventListener     - transient instance of: org.esco.sarapis.db.entity.personne.Login
    12906 DEBUG  [main] DefaultMergeEventListener     - merging transient instance
    12906 DEBUG  [main] AbstractSaveEventListener     - saving [org.esco.sarapis.db.entity.personne.Login#<null>]
    12921 DEBUG  [main] AbstractSaveEventListener     - executing insertions
    12921 DEBUG  [main] AbstractSaveEventListener     - executing identity-insert immediately
    12921 DEBUG  [main] AbstractEntityPersister       - Inserting entity: org.esco.sarapis.db.entity.personne.Login (native id)
    12921 DEBUG  [main] AbstractBatcher               - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
    12921 DEBUG  [main] AbstractBatcher               - insert into Login (nom) values (?)
    Hibernate: insert into Login (nom) values (?)
    12921 DEBUG  [main] AbstractBatcher               - preparing statement
    12937 DEBUG  [main] AbstractEntityPersister       - Dehydrating entity: [org.esco.sarapis.db.entity.personne.Login#<null>]
    12937 DEBUG  [main] NullableType                  - binding 'aaaaa' to parameter: 1
    12937 DEBUG  [main] AbstractBatcher               - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
    12937 DEBUG  [main] AbstractBatcher               - closing statement
    12953 DEBUG  [main] JDBCExceptionReporter         - could not insert: [org.esco.sarapis.db.entity.personne.Login] [insert into Login (nom) values (?)]
    com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Duplicate entry 'aaaaa' for key 2
    	....
    12953 WARN   [main] JDBCExceptionReporter         - SQL Error: 1062, SQLState: 23000
    12968 ERROR  [main] JDBCExceptionReporter         - Duplicate entry 'aaaaa' for key 2
    12968 DEBUG  [main] AbstractEntityManagerImpl     - mark transaction for rollback
    12968 ERROR  [main] GenericDaoImpl                - Merge failed - Entity already exists : org.hibernate.exception.ConstraintViolationException: could not insert: [org.esco.sarapis.db.entity.personne.Login]
    12968 DEBUG  [main] GenericDaoImpl                - ====>>> duplicate entry.
    12968 DEBUG  [main] LoginAliasManagerImpl         - Interception de l'erreur : org.hibernate.exception.ConstraintViolationException: could not insert: [org.esco.sarapis.db.entity.personne.Login]
    12968 INFO   [main] LoginAliasManagerImpl         - Create new Login : aaaaa0
    12968 INFO   [main] LoginAliasManagerImpl         - Try to insert Login
    12968 DEBUG  [main] GenericDaoImpl                - Merging org.esco.sarapis.db.entity.personne.Login instance
    12968 DEBUG  [main] TransactionSynchronizationManager     - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@856d3b] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@1c67b54] bound to thread [main]
    12968 DEBUG  [main] IdentifierValue               - id unsaved-value: 0
    12968 DEBUG  [main] AbstractSaveEventListener     - transient instance of: org.esco.sarapis.db.entity.personne.Login
    12968 DEBUG  [main] DefaultMergeEventListener     - merging transient instance
    12968 DEBUG  [main] AbstractSaveEventListener     - saving [org.esco.sarapis.db.entity.personne.Login#<null>]
    12968 DEBUG  [main] AbstractSaveEventListener     - executing insertions
    12968 DEBUG  [main] AbstractSaveEventListener     - executing identity-insert immediately
    12968 DEBUG  [main] AbstractEntityPersister       - Inserting entity: org.esco.sarapis.db.entity.personne.Login (native id)
    12968 DEBUG  [main] AbstractBatcher               - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
    12968 DEBUG  [main] AbstractBatcher               - insert into Login (nom) values (?)
    Hibernate: insert into Login (nom) values (?)
    12968 DEBUG  [main] AbstractBatcher               - preparing statement
    12968 DEBUG  [main] AbstractEntityPersister       - Dehydrating entity: [org.esco.sarapis.db.entity.personne.Login#<null>]
    12968 DEBUG  [main] NullableType                  - binding 'aaaaa0' to parameter: 1
    12984 DEBUG  [main] IdentifierGeneratorFactory     - Natively generated identity: 4
    12984 DEBUG  [main] AbstractBatcher               - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
    12984 DEBUG  [main] AbstractBatcher               - closing statement
    12984 DEBUG  [main] GenericDaoImpl                - Merge successful.
    12984 INFO   [main] LoginAliasManagerImpl         - insert OK
    12984 DEBUG  [main] TransactionAspectSupport      - Completing transaction for [org.esco.sarapis.db.domain.gestion.ILoginAliasManager.findValidLogin]
    12984 DEBUG  [main] AbstractPlatformTransactionManager     - Triggering beforeCommit synchronization
    12984 DEBUG  [main] AbstractPlatformTransactionManager     - Triggering beforeCompletion synchronization
    12984 DEBUG  [main] AbstractPlatformTransactionManager     - Initiating transaction commit
    12984 DEBUG  [main] JpaTransactionManager         - Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@117b450]
    12984 DEBUG  [main] JDBCTransaction               - rollback
    13078 DEBUG  [main] JDBCTransaction               - re-enabling autocommit
    13078 DEBUG  [main] JDBCTransaction               - rolled back JDBC Connection
    13078 DEBUG  [main] JDBCContext                   - after transaction completion
    13078 DEBUG  [main] ConnectionManager             - aggressively releasing JDBC connection
    13078 DEBUG  [main] ConnectionManager             - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
    13078 DEBUG  [main] SessionImpl                   - after transaction completion
    13078 DEBUG  [main] AbstractPlatformTransactionManager     - Triggering afterCompletion synchronization
    13078 DEBUG  [main] TransactionSynchronizationManager     - Clearing transaction synchronization
    13078 DEBUG  [main] TransactionSynchronizationManager     - Removed value [org.springframework.orm.jpa.EntityManagerHolder@856d3b] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@1c67b54] from thread [main]
    13078 DEBUG  [main] TransactionSynchronizationManager     - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@1bde3d2] for key [[email protected]c9] from thread [main]
    13078 DEBUG  [main] JpaTransactionManager         - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@117b450] after transaction
    13078 DEBUG  [main] EntityManagerFactoryUtils     - Closing JPA EntityManager
    13078 DEBUG  [main] SessionImpl                   - closing session
    13078 DEBUG  [main] ConnectionManager             - connection already null in cleanup : no action
    Last edited by nean; Jul 30th, 2008, 04:06 AM.

    Comment


    • #3
      I found a solution but i need to make all without JPA Spring management. I need to manage manualy all trasaction...

      Do you think the best is to let the managment to Spring or to manage all manualy ?

      I would prefer to let it to spring but i can't manage any exception in this case ...

      Is there someone who can give some advices ?
      Last edited by nean; Jul 30th, 2008, 09:21 AM.

      Comment


      • #4
        So I post some exemple of my code :

        My generic dao :
        Code:
        public abstract class GenericDaoImpl<T> implements IGenericDao<T> {
        
            static final Logger LOGGER = Logger.getLogger(GenericDaoImpl.class);
        
            private Class<T> entityBeanType;
        
            @PersistenceContext(type = PersistenceContextType.TRANSACTION) 
            private EntityManager entityManager;
          
            
            public GenericDaoImpl(final Class<T> classe) {
                this.entityBeanType = classe;
            }
        
            public T merge(final T entity) { 
                LOGGER.debug("Merging " + this.entityBeanType.getName() + " instance");		
                T res = null;
                res = entityManager.merge(entity);
                LOGGER.debug("Merge successful.");   
                return res;
            }
        my Dao for the object (not very interesting)

        Code:
        @Repository
        public class LoginDaoImpl extends GenericDaoImpl<Login> implements ILoginDao {
        
        public LoginDaoImpl() {
                super(Login.class);
            }
        
        }
        and my service :
        Code:
        @Service
        @Scope("singleton")
        public class LoginAliasManagerImpl implements ILoginAliasManager {
        
            private static final Logger LOGGER = Logger.getLogger(LoginAliasManagerImpl.class);
        
            @Resource
            private ILoginDao loginDao;
        
         public LoginAliasManagerImpl() {
                // TODO Auto-generated constructor stub
            }
        
         @Transactional(readOnly = false, propagation = Propagation.REQUIRED, 
                    noRollbackFor =  com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException.class)
            public Login findValidLogin(final String possibleValue) {
                Login login = null;
                int i = -1;
                while (login == null) {
                login = findLogin(possibleValue, i);
                  i++;
                }
                return login;
            }
        
         private Login findLogin(final String possibleValue, final int i) {
                Login login = null;
                try {          
                    
                    if (i == -1) {
                        LOGGER.info("Create new Login : " + possibleValue);
                        login = new Login(possibleValue);
                    } else {
                        LOGGER.info("Create new Login : " + possibleValue + i);
                        login = new Login(possibleValue + i);
                    }
                    LOGGER.info("Try to insert Login");
                    login = loginDao.merge(login);
                    LOGGER.info("insert OK");
                } catch (org.springframework.dao.DataIntegrityViolationException e) {
                    LOGGER.debug("Interception de l'erreur : " + e.getMessage());
                    return null;
                }
        
                return login;
            }
        and my spring config :
        Code:
        <?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:context="http://www.springframework.org/schema/context"
        	xmlns:aop="http://www.springframework.org/schema/aop"
        	xmlns:tx="http://www.springframework.org/schema/tx"
        	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
        
        	<bean name="propertyPlaceholder"		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        		<property name="locations">
        			<value>classpath:db.properties</value>
        		</property>
        	</bean>
        
        	<bean id="dataSource"		class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        		p:driverClassName="${db.driver}" p:url="${db.url}"
        		p:username="${db.username}" p:password="${db.password}" />
        
        	<bean id="persistenceUnitManager"		class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
        			<property name="persistenceXmlLocations">
        			<list>				<value>classpath*:META-INF/Persistence.xml</value>
        			</list>
        		</property>
        	
        		<property name="dataSources">
        			<map>
        				<entry key="localDataSource" value-ref="dataSource" />
        			</map>
        		</property>
        		<property name="defaultDataSource" ref="dataSource" />
        	</bean>
        
        
        	<bean id="entityManagerFactory"		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        		p:dataSource-ref="dataSource"
        		p:persistenceUnitManager-ref="persistenceUnitManager">
        		<property name="jpaVendorAdapter">
        			<bean
        				class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
        				p:databasePlatform="${db.dialect}" p:database="${db.database}"
        				p:showSql="true" p:generate-ddl="true" />
        		</property>
        		<property name="loadTimeWeaver">
        			<bean				class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        		</property>
        		<property name="jpaDialect">
        			<bean				class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
        		</property>
        	</bean>
        
        	<bean id="transactionManager"
        		class="org.springframework.orm.jpa.JpaTransactionManager"
        		p:entityManagerFactory-ref="entityManagerFactory">
        		<property name="jpaDialect">
        			<bean				class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
        		</property>
        	</bean>
        
        	<tx:annotation-driven transaction-manager="transactionManager"/>
        
        	<context:annotation-config />
        
        	<context:component-scan base-package="org.esco.sarapis.db" />
        
        
        	<bean		class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
        
        	<bean		class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
        
        </beans>
        If someone could help me before that i go for manual managment it would be great. It makes around 2 days that I'm after this problem and i don't understand the problem

        thanks in advance

        Comment


        • #5
          Can you post your IGenericDao class?

          Comment


          • #6
            it's a simple Interface which expose my method merge, but here is the code :
            Code:
            public interface IGenericDao<T> {
            	
            	...
            	T merge(final T entity);
                   ...
            }
            Just to tell what i want... I want to manage duplicate entry and some other exception that i could launch in some merge instruction... To be able to replay the merge with a new entry.

            Comment


            • #7
              It's ok that you want to handle exceptions, it's just that you can't commit afterwards. The exception marks the transaction as rollbackOnly:

              [main] AbstractEntityManagerImpl - mark transaction for rollback

              What you need to do is separate each try in a new transaction.

              Comment


              • #8
                In this case i have only to modify my service like that :
                Code:
                @Service
                @Scope("singleton")
                public class LoginAliasManagerImpl implements ILoginAliasManager {
                
                    private static final Logger LOGGER = Logger.getLogger(LoginAliasManagerImpl.class);
                
                    @Resource
                    private ILoginDao loginDao;
                
                    public LoginAliasManagerImpl() {
                        // TODO Auto-generated constructor stub
                    }
                
                    @Transactional
                    public Login findLogin(final String possibleValue, final int i) {
                        Login login = null;
                        try {             
                            if (i == -1) {
                                LOGGER.info("Create new Login : " + possibleValue);
                                login = new Login(possibleValue);
                            } else {
                                LOGGER.info("Create new Login : " + possibleValue + i);
                                login = new Login(possibleValue + i);
                            }
                            LOGGER.info("Try to insert Login");
                            login = loginDao.merge(login);
                            LOGGER.info("insert OK");
                        } catch (org.springframework.dao.DataIntegrityViolationException e) {
                            LOGGER.debug("Interception de l'erreur : " + e.getMessage());
                            return null;
                        }
                
                        return login;
                    }
                  
                   public Login findValidLogin(final String possibleValue) {
                        Login login = null;
                        int i = -1;
                        while (login == null) {
                        login = findLogin(possibleValue, i);
                          i++;
                        }
                        return login;
                    }
                }

                and i request the method findValidLogin which should request findLogin until that findValidLogin find a login...
                But the problem is that it doesn't create a transaction and so it doesn't commit.

                Code:
                16016 DEBUG  [main] AbstractBeanFactory           - Returning cached instance of singleton bean 'loginAliasManagerImpl'
                16016 INFO   [main] LoginAliasManagerImpl         - Create new Login : aaaaa
                16016 INFO   [main] LoginAliasManagerImpl         - Try to insert Login
                16016 DEBUG  [main] GenericDaoImpl                - Merging org.esco.sarapis.db.entity.personne.Login instance
                16031 DEBUG  [main] SharedEntityManagerCreator$SharedEntityManagerInvocationHandler     - Creating new EntityManager for shared EntityManager invocation
                16125 DEBUG  [main] SessionImpl                   - opened session at timestamp: 12175131299
                16141 DEBUG  [main] IdentifierValue               - id unsaved-value: 0
                16141 DEBUG  [main] AbstractSaveEventListener     - transient instance of: org.esco.sarapis.db.entity.personne.Login
                16141 DEBUG  [main] DefaultMergeEventListener     - merging transient instance
                16141 DEBUG  [main] AbstractSaveEventListener     - saving [org.esco.sarapis.db.entity.personne.Login#<null>]
                16156 DEBUG  [main] AbstractSaveEventListener     - delaying identity-insert due to no transaction in progress
                16156 DEBUG  [main] EntityManagerFactoryUtils     - Closing JPA EntityManager
                16156 DEBUG  [main] SessionImpl                   - closing session
                16156 DEBUG  [main] ConnectionManager             - connection already null in cleanup : no action
                16156 DEBUG  [main] GenericDaoImpl                - Merge successful.
                16156 INFO   [main] LoginAliasManagerImpl         - insert OK
                16156 INFO   [main] LoginAliasManagerImpl         - Create new Login : aaaaa
                16156 INFO   [main] LoginAliasManagerImpl         - Try to insert Login
                16156 DEBUG  [main] GenericDaoImpl                - Merging org.esco.sarapis.db.entity.personne.Login instance
                16156 DEBUG  [main] SharedEntityManagerCreator$SharedEntityManagerInvocationHandler     - Creating new EntityManager for shared EntityManager invocation
                16156 DEBUG  [main] SessionImpl                   - opened session at timestamp: 12175131300
                16172 DEBUG  [main] IdentifierValue               - id unsaved-value: 0
                16172 DEBUG  [main] AbstractSaveEventListener     - transient instance of: org.esco.sarapis.db.entity.personne.Login
                16172 DEBUG  [main] DefaultMergeEventListener     - merging transient instance
                16172 DEBUG  [main] AbstractSaveEventListener     - saving [org.esco.sarapis.db.entity.personne.Login#<null>]
                16172 DEBUG  [main] AbstractSaveEventListener     - delaying identity-insert due to no transaction in progress
                16172 DEBUG  [main] EntityManagerFactoryUtils     - Closing JPA EntityManager
                16172 DEBUG  [main] SessionImpl                   - closing session
                16172 DEBUG  [main] ConnectionManager             - connection already null in cleanup : no action
                16172 DEBUG  [main] GenericDaoImpl                - Merge successful.
                16172 INFO   [main] LoginAliasManagerImpl         - insert OK
                It doesn't make any commit finaly ...

                How can i make separate transaction in this case ? or how could I solve this problem ?

                Comment


                • #9
                  Now you have no transactions at all.

                  For transactions to work you need proxies and proxies are not invoked if you call the method from the same class. You can:

                  a) split your class in 2, so that transactional method will be invoked through the proxy
                  b) use transactiontemplate instead of proxies
                  c) use aspectj weaving instead of proxies

                  Comment


                  • #10
                    I'm a bit new

                    What is the best solution ? And do you have some example ? I never use aspectj and i don't know transactionTemplate... And for the first one I'm trying to get it but it seems that it doesn't work for me...

                    But anyway thanks for your help, i understand now my problem at least.
                    Last edited by nean; Jul 31st, 2008, 11:05 AM.

                    Comment


                    • #11
                      The best solution is what suits you the best. They all work and do the same thing. If you don't mind using programmatic transactions solution b) is very easy and you can find the an example in reference docs here.

                      Comment


                      • #12
                        Thanks for all

                        I will watch better on the documentation but this isn't very clear in my mind on how to do that

                        Comment


                        • #13
                          it seems that doesn't works I have always the same error... I mofified my code like that :

                          Code:
                          @Service
                          @Scope("singleton")
                          public class LoginAliasManagerImpl implements ILoginAliasManager {
                          
                              private static final Logger LOGGER = Logger.getLogger(LoginAliasManagerImpl.class);
                          
                              @Resource
                              private ILoginDao loginDao;
                          
                              private TransactionTemplate transactionTemplate;
                          
                              public LoginAliasManagerImpl() {
                                  super();
                              }
                          
                              public Login findLogin(final String possibleValue, final int i) {
                                  Login login = null;
                          
                                  if (i == -1) {
                                      LOGGER.info("Create new Login : " + possibleValue);
                                      login = new Login(possibleValue);
                                  } else {
                                      LOGGER.info("Create new Login : " + possibleValue + i);
                                      login = new Login(possibleValue + i);
                                  }
                                  LOGGER.info("Try to insert Login");
                                  final Login flogin = login;
                                  transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 
                                  login =  (Login) transactionTemplate.execute(new TransactionCallback() {
                          
                                      
                                      public Object doInTransaction(final TransactionStatus status) {
                                          try {
                                              return  loginDao.merge(flogin);
                                          } catch (org.springframework.dao.DataIntegrityViolationException e) {
                                              LOGGER.debug("Interception de l'erreur : " + e.getMessage());
                                              return null;
                                          }
                                      }
                          
                                  });
                                  LOGGER.info("insert OK");
                                  return login;
                              }
                          
                            
                              public Login findValidLogin(final String possibleValue) {
                                  Login login = null;
                          
                                  int i = -1;
                                  while (login == null) {
                                       final int j = i;
                                                 transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 
                                      login =  (Login) transactionTemplate.execute(new TransactionCallback() {      
                                          public Object doInTransaction(final TransactionStatus status) {
                                              return findLogin(possibleValue, j);
                                          }
                                      });
                                      i++;
                                  }
                                  return login;
                              }
                          
                              public TransactionTemplate getTransactionTemplate() {
                                  return this.transactionTemplate;
                              }
                          
                              public void setTransactionTemplate(final TransactionTemplate transactionTemplate) {
                                  this.transactionTemplate = transactionTemplate;
                              }
                          
                          }
                          and my spring config is like that now :
                          Code:
                          <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:context="http://www.springframework.org/schema/context"
                          	xmlns:aop="http://www.springframework.org/schema/aop"
                          	xmlns:tx="http://www.springframework.org/schema/tx"
                          	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
                              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 
                              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                              http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
                          
                          	<bean name="propertyPlaceholder"		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                          		<property name="locations">
                          			<value>classpath:db.properties</value>
                          		</property>
                          	</bean>
                          
                          	<bean id="dataSource"		class="org.springframework.jdbc.datasource.DriverManagerDataSource"
                          		p:driverClassName="${db.driver}" p:url="${db.url}"
                          		p:username="${db.username}" p:password="${db.password}" />
                          	<bean id="persistenceUnitManager"
                          		class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
                          		<property name="persistenceXmlLocations">
                          			<list>
                          				<value>classpath*:META-INF/varPersistence.xml</value>
                          			</list>
                          		</property>
                          		<property name="dataSources">
                          			<map>
                          				<entry key="localDataSource" value-ref="dataSource" />
                          			</map>
                          		</property>
                          		<property name="defaultDataSource" ref="dataSource" />
                          	</bean>
                          
                          	<bean id="entityManagerFactory"
                          		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
                          		p:dataSource-ref="dataSource"
                          		p:persistenceUnitManager-ref="persistenceUnitManager">	
                          		<property name="jpaVendorAdapter">
                          			<bean				class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
                          				p:databasePlatform="${db.dialect}" p:database="${db.database}"
                          				p:showSql="true" p:generate-ddl="true" />
                          		</property>
                          		<property name="loadTimeWeaver">
                          			<bean				class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
                          		</property>
                          		<property name="jpaDialect">
                          			<bean				class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
                          		</property>
                          	</bean>
                          
                          	<bean id="transactionManager"
                          		class="org.springframework.orm.jpa.JpaTransactionManager"
                          		p:entityManagerFactory-ref="entityManagerFactory">
                          		<property name="jpaDialect">
                          			<bean				class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
                          		</property>
                          	</bean>
                          
                          	<tx:annotation-driven transaction-manager="transactionManager" />
                          
                          	<bean id="sharedTransactionTemplate"
                          		class="org.springframework.transaction.support.TransactionTemplate">
                          		<property name="timeout" value="30" />
                          		<property name="transactionManager" ref="transactionManager"></property>
                          	</bean>
                          <bean id="serviceLoginAliasManager"
                          		class="org.esco.sarapis.db.domain.gestion.impl.LoginAliasManagerImpl">
                          		<property name="transactionTemplate" ref="sharedTransactionTemplate" />
                          	</bean>
                          Did i make something wrong ?

                          Comment


                          • #14
                            You need status.setRollbackOnly() in the catch block. Also, you don't need transactions in your findValidLogin method the one in findLogin is enough. PROPAGATION_REQUIRED is default, you don't need to set it.

                            Comment


                            • #15
                              thanks a lot you were very helpfull for me...

                              I didn't read in the doc that " status.setRollbackOnly() " was needed, if you weren't here i would be again looking for a solution. I thougth this was needed only for the WithoutResult part.

                              All works now thanks for your help

                              Comment

                              Working...
                              X