Page 2 of 2 FirstFirst 12
Results 11 to 16 of 16

Thread: no rollback

  1. #11
    Join Date
    Mar 2009
    Posts
    9

    Default

    First of all, I dare to ask a simple question: did you hit the reload/refresh button of your database tool?


    Otherwise, please post your code (JUNIT-Test and application).

  2. #12
    Join Date
    May 2008
    Posts
    10

    Default

    Hi, First of all, apologies for a late response. I was out sick.

    Here is the scenario I was testing. I have two tables. User and Roles. Whenver a new user is created, one new record is inserted into the User table and one into the role table. (A user has a role (1:1)).

    Both the insert operations are called one afrer the another in the same method.

    JUnit Test Case:
    I throw an exception on the insert role method in my Junit test case. It works fine. When I refresh the database tool, I dont a user object inserted into the database.

    Application Environment:

    I use the same code, same application context xml file and same hibernate properties. But when I refresh, I see no records are inserted to role table, which is as expected, but a new record is inserted into user table. This means, the rolback is not happening.

    Code:
    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
    public boolean createUser(Object userObject) {
            try{
                insertUser(userObject);
                insertRole(userObject);
            catch(Exception e) {
                throw e;
            }
    }
    The insertUser and insertRole methods have the transactional annotation as well as defined below:
    Code:
    @Transactional(propagation=Propagation.REQUIRED)
    public void insertRole(Object object) throws Exception{
    .....
    }
    The logs are:
    Code:
    2009-04-03 13:11:42,656 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] - <Could not synchronize database state with session>
    org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
    	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
    	at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
    	at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
    	at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)
    	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2252)
    	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2688)
    	at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
    	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
    	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    	at org.springframework.orm.hibernate3.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:135)
    	at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:72)
    	at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:905)
    	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:715)
    	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:701)
    	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 $Proxy6.createUser(Unknown Source)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)

  3. #13
    Join Date
    May 2008
    Posts
    10

    Default

    Any ideas any body. I really need some help here. I have been struggling for past couple of days to solve this issue. I have tried several variations of different configurations and nothing seems to work.

    Any help would be really appreciated.

    Thanks..

  4. #14
    Join Date
    Mar 2009
    Posts
    9

    Default

    Maybe the corresponding class XY of the method createUser was not instantiated via an Interface, i.e.

    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext .xml");
    IXYService s = (IXYService)ctx.getBean("nameOfClassXY");

  5. #15
    Join Date
    May 2008
    Posts
    10

    Default

    Well, the class is being instantiated via an interface.

    Here is the complete application code.

    ApplicationContext.xml file. For the sake of brevity and testing, I had included all beans in one xml file.

    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: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/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">
    
    	<!-- Transaction Management -->
    	<tx:annotation-driven transaction-manager="txManager"/>
    
    	<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactory"/>
    	</bean>
    	
    	<bean id="smartDaoTarget" class="com.package.dao.impl.SmartWorkDaoImpl">
    		<property name="sessionFactory" ref="sessionFactory"/>
    	</bean>
    
    	<bean id="smartBaseBO" class="org.springframework.aop.framework.ProxyFactoryBean">
    		<property name="proxyInterfaces" value="com.package.core.dao.SmartBaseBO" />
    		<property name="target" ref="smartDaoTarget"/>
    	</bean>
    	
    	<bean id="userManager" class="org.springframework.aop.framework.ProxyFactoryBean">
    		<property name="proxyInterfaces" value="com.package.core.users.UserManager"/>
    		<property name="target" ref="userManagerTarget"/>
    	</bean>
    	
    	<bean id="userManagerTarget" class="com.package.core.users.impl.UserManagerImpl">
    		<property name="smartBaseBO" ref="smartBaseBO"/>
    	</bean>
    	
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		
    		<property name="dataSource" ref="dataSource"/>
    
    		<property name="mappingLocations">
    			<list>
    				<value>/WEB-INF/hbm/security/Authorities.hbm.xml</value>
    				<value>/WEB-INF/hbm/security/Users.hbm.xml</value>
    			</list>
    		</property>
    
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
    				<prop key="hibernate.show_sql">true</prop>
    				<prop key="hibernate.max_fetch_depth">3</prop>
    				<prop key="hibernate.connection.release_mode">auto</prop>
    			</props>
    		</property>
    	</bean>
    	
    	<bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy" destroy-method="close">
    		<property name="targetDataSource" ref="dataSourceTarget"/>
    		<property name="defaultAutoCommit" value="false"/>
    	</bean>
    	
    	<bean id="dataSourceTarget" class="oracle.jdbc.pool.OracleConnectionPoolDataSource" destroy-method="close">
    		<property name="URL" value="jdbc:oracle:thin:@192.168.1.100:1521:test"/>
    		<property name="user" value="testuser" />
    		<property name="password" value="testpwd" />
    	</bean>	
    	
    </beans>
    DAO Code
    ========
    Code:
    //SmartBaseBO.java interface definition file.
    public interface SmartBaseBO {
    	public boolean add(Object aObject);
    }
    
    public class SmartWorkDaoImpl implements SmartBaseBO {
    
    	private SessionFactory sessionFactory;
    
    	public boolean add(Object aObject) {
    		boolean bRetVal = false;
    		Session session = getSession();
    		try {
    			session.save(aObject);
    			bRetVal = !bRetVal;
    		} catch (HibernateException e) {
    			throw SessionFactoryUtils.convertHibernateAccessException(e);
    		} finally {
    			session.flush();
    		}
    		return bRetVal;
    	}
    
    	private Session getSession() {
    		return SessionFactoryUtils.getSession(getSessionFactory(), true);
    	}
    
    	public void setSessionFactory(SessionFactory sessionFactory) {
    		this.sessionFactory = sessionFactory;
    	}
    
    	public SessionFactory getSessionFactory() {
    		return this.sessionFactory;
    	}
    }
    
    //UserManager Interface
    package com.package.core.users;
    
    public interface UserManager {
    	void createUser(Users user, String role) throws Exception;
    }
    
    //UserManager Implementation
    
    package com.package.core.users.impl;
    
    public class UserManagerImpl implements UserManager {
    
    	private final static Log LOG = LogFactory.getLog(UserManagerImpl.class);
    
    	private SmartBaseBO smartBaseBO;
    
    	@Transactional(propagation=Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
    	public void createUser(Users user, String role) throws Exception {
    		try {
    			smartBaseBO.add(user);
    			Authorities auth = new Authorities();
    			auth.setAuthority(role);
    			auth.setUsername(user.getUsername());
    			auth.setUsers(user);
    			smartBaseBO.add(auth);
    		} catch (Exception e) {
    			LOG.error("------------------------------   EXCEPTION ----------");
    			throw e;
    		}
    	}
    
    	public void setSmartBaseBO(SmartBaseBO smartBaseBO) {
    		this.smartBaseBO = smartBaseBO;
    	}
    }
    
    //JUnit Test Case
    
    public class UserManagerTest {
    
    	@Test
    	public void testAdd() {
    		try {
    			ApplicationContext appCtx = new ClassPathXmlApplicationContext("applicationContext.xml");
    			UserManager userManager = (UserManager) appCtx.getBean("userManager");
    			Users user = new Users();
    			user.setUsername("junittest3");
    			user.setFirstName("junittest1");
    			user.setLastName("junittest1");
    			user.setPassword("test");
    			user.setUpdated(new Date());
    			user.setPrimaryEMail("test@email.com");
    			userManager.createUser(user, "DEFAULT_ROLE");
    		} catch (Exception e) {
    			System.out.println(e);
    		}
    	}
    }
    The Unit test case works fine. It doesn't create a user, if the role creation for the user fails. It rolls back properly. The database doesn't contain the record as expected. (the tool was refreshed).

    But, same code doesnt work when used in the application. The logs show that the rollback was done, but the database has the new record, whereas the new record should not have been inserted. (again, the tool was refreshed).

    My guess, is it has something to do with Spring Transaction Synchronization and Spring Session management.

    Database: Oracle 10g
    AppServer: Tomcat 6.0.18
    Spring 2.5.6
    Hibernate 3.3.1 GA

    Thanks for the help.
    Last edited by ritesh; Apr 9th, 2009 at 12:35 PM.

  6. #16
    Join Date
    May 2008
    Posts
    10

    Default

    Well.. my problem is not resolved. It's a strange problem, and I am not able to figure out the cause of the problem.

    In my log4j.properties file, when I set

    lo4j.logger.org.hibernate=INFO

    the rollback doesnt work. But when I set

    log4j.logger.org.hibernate-DEBUG

    then the rollback works fine. I know it sounds crazy, but this is what I am seeing on my setup.

    The application works fine and rollback and transactions happen as expected when the log level is set to DEBUG, but when the log level is set to INFO, it doesn't work.

    This leads me to think that there is some kind of bug in hibernate code and setting of rolback flag is somehow made dependent on the log level. I am not sure, but I am still digging into this. If someone has seen this behavior before, I would be thankful, if they can provide some insight into this.

    Thanks.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •