Announcement Announcement Module
Collapse
No announcement yet.
Transaction rolling back - What's wrong ?? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Transaction rolling back - What's wrong ??

    Hi everyone,

    I am trying to maintain a parent-child relationship in the form of country-state.

    The problem is that at my transaction is rolling back automatically, when I try
    to add a child to a parent and call the saveOrUpdate method on the parent.

    Can anyone help me indicate what's wrong in my code? I am using MySQL v4.1, Hibernate v3.0.5
    and Spring v1.2.3.

    If this is not the right way, what's the right way... will appreciate if somebody indicates
    with changes in my source code.

    Thanks,
    Vaibhav

    Console Snapshot

    The first mark (>>) points that their is an attempt to insert the child, as the ID is incrementing,
    everytime I execute the code.
    The second mark indicates the rollback.

    Code:
    	[java] DEBUG - AbstractFlushingEventListener.flushCollections(203) | Processing unreferenced collections
    	[java] DEBUG - AbstractFlushingEventListener.flushCollections(217) | Scheduling collection removes/(re)creates/updates
    	[java] DEBUG - AbstractFlushingEventListener.flushEverythingToExecutions(79) | Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects
    	[java] DEBUG - AbstractFlushingEventListener.flushEverythingToExecutions(85) | Flushed: 0 (re)creations, 1 updates, 0 removals to 1 collections
    	[java] DEBUG - Printer.toString(83) | listing entities:
    	[java] DEBUG - Printer.toString(90) | com.csam.ccp.cdc.persistence.Country{states=[com.csam.ccp.cdc.persistence.State#4], countryID=1, label=India}
    >>	[java] DEBUG - Printer.toString(90) | com.csam.ccp.cdc.persistence.State{country=com.csam.ccp.cdc.persistence.Country#1, label=Uttar Pradesh, stateID=4}
    	[java] DEBUG - AbstractFlushingEventListener.performExecutions(267) | executing flush
    	[java] DEBUG - AbstractFlushingEventListener.postFlush(294) | post flush
    >>	[java] DEBUG - JDBCTransaction.rollback(132) | rollback
    	[java] DEBUG - JDBCContext.beforeTransactionCompletion(278) | before transaction completion
    	[java] DEBUG - SessionImpl.beforeTransactionCompletion(372) | before transaction completion
    	[java] DEBUG - JDBCTransaction.toggleAutoCommit(173) | re-enabling autocommit
    	[java] DEBUG - JDBCTransaction.rollback(143) | rolled back JDBC Connection
    	[java] DEBUG - JDBCContext.afterTransactionCompletion(283) | after transaction completion
    	[java] DEBUG - SessionImpl.afterTransactionCompletion(403) | after transaction completion
    	[java] DEBUG - SessionImpl.close(269) | closing session
    	[java] DEBUG - ConnectionManager.closeConnection(317) | closing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
    	[java] DEBUG - JDBCContext.afterTransactionCompletion(283) | after transaction completion
    	[java] DEBUG - SessionImpl.afterTransactionCompletion(403) | after transaction completion
    	[java] java.lang.StackOverflowError
    	&#91;java&#93; at java.util.HashMap$KeyIterator.<init>&#40;HashMap.java&#58;816&#41;
    Here's my DAO target

    Code:
    public class TerritorialDataServiceProvider implements TerritorialDataService 
    &#123;	
    	private SessionFactory sessionFactory;
    	
    	public void setSessionFactory&#40;SessionFactory sessionFactory&#41; 
    	&#123;
    		this.sessionFactory = sessionFactory;
    	&#125;
    
    	public String addCountry&#40;&#41; 
    	&#123;
    		Session session = 
    			SessionFactoryUtils.getSession&#40; this.sessionFactory, false &#41;;
    		
    		try
    		&#123;
    			Country bharat = new Country&#40;&#41;;
    			
    			bharat.setLabel&#40;"Bharat"&#41;;
    			
    			session.saveOrUpdate&#40; bharat &#41;;
    			
    			return bharat.getCountryID&#40;&#41;.toString&#40;&#41;;
    		&#125;
    		catch&#40; HibernateException excp &#41;
    		&#123;
    			throw SessionFactoryUtils.convertHibernateAccessException&#40; excp &#41;;
    		&#125;
    	&#125;
    
    	public String addState&#40;String countryID, String label&#41; 
    	throws NonExistentParentException 
    	&#123;
    		Session session = 
    			SessionFactoryUtils.getSession&#40; this.sessionFactory, false &#41;;
    		
    		try
    		&#123;
    			final Country bharat =  
    				&#40;Country&#41; session.load&#40; Country.class, Long.valueOf&#40;countryID&#41; &#41;;
    			
    			if&#40; bharat != null &#41;
    			&#123;
    				State stateToBeAdded = new State&#40;&#41;;
    				
    				stateToBeAdded.setLabel&#40; label &#41;;
    				
    				//Set states = bharat.getStates&#40;&#41;; // Not Working &#58;-&#40;
    				
    				bharat.addState&#40; stateToBeAdded &#41;;
    				
    				session.save&#40; stateToBeAdded &#41;;
    				
    				session.saveOrUpdate&#40; bharat &#41;;
    			
    				// Uncomment and you get NullPointerException
    				return null;//stateToBeAdded.getStateID&#40;&#41;.toString&#40;&#41;;
    			&#125;
    			else
    			&#123;
    				throw new NonExistentParentException&#40;"Non Existent"&#41;;
    			&#125;
    		&#125;
    		catch&#40; HibernateException excp &#41;
    		&#123;
    			throw SessionFactoryUtils.convertHibernateAccessException&#40; excp &#41;;
    		&#125;
    	&#125;
    
    	public Country getCountry&#40; String countryID &#41; 
    	&#123;
    		Session session = 
    			SessionFactoryUtils.getSession&#40; this.sessionFactory, false &#41;;
    		
    		try
    		&#123;
    			final Country bharat =  
    				&#40;Country&#41; session.load&#40; Country.class, Long.valueOf&#40;countryID&#41; &#41;;
    			
    			return bharat;
    		&#125;
    		catch&#40; HibernateException excp &#41;
    		&#123;
    			throw SessionFactoryUtils.convertHibernateAccessException&#40; excp &#41;;
    		&#125;
    	&#125;
    &#125;
    And here's my Spring Config File

    Code:
        <!-- This bean implements the functionality. 
        	It might depend upon other beans, as the application scope increase -->
    	<bean id="territorialDataServiceProvider" 
        	class="com.csam.ccp.cdc.service.realization.TerritorialDataServiceProvider">
             <property name="sessionFactory">
            	<ref local="sessionFactory"/>
            </property>
        </bean>
        
    	<!-- This bean is the interface -->
        <bean id="territorialDataService" 
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager">
            	<ref local="transactionManager"/>
            </property>
            <property name="target">
            	<ref local="territorialDataServiceProvider"/>
            </property>
            <property name="transactionAttributes">
            	<props>
    			<prop key="add*">PROPAGATION_REQUIRED</prop>
    			<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
    		</props>
            </property>
            <property name="postInterceptors">
            	<list>
            		<bean class="org.springframework.orm.hibernate3.HibernateInterceptor">
            			<property name="sessionFactory">
            				<ref local="sessionFactory"/>
            			</property>
            		</bean>
            	</list>
            </property>
        </bean>
    And here's my client application.

    Code:
    ...
    	public static void main&#40;String&#91;&#93; args&#41; 
    	&#123;
    		System.out.println&#40;"Starting Geographical Service Client"&#41;;
    		
    		SessionFactory sessionFactory = 
    			&#40;SessionFactory&#41;getBean&#40;"sessionFactory"&#41;;
    		
    		Session session = 
    			SessionFactoryUtils.getSession&#40; sessionFactory, true &#41;;
    		
    	    TransactionSynchronizationManager
    	    	.bindResource&#40;sessionFactory, new SessionHolder&#40;session&#41;&#41;;
    	    
    	    try
    	    &#123;
    	    	TerritorialDataService service = 
    				&#40;TerritorialDataService&#41; applicationContext
    					.getBean&#40;"territorialDataService"&#41;;
    	    	
    	    	String countryID = service.addCountry&#40;&#41;;
    	    	
    	    	System.out.println&#40;"Country ID = " + countryID &#41;;
    	    	
    	    	Country country = service.getCountry&#40; countryID &#41;;
    	    	
    	    	if&#40; country != null &#41;
    		&#123;
    			System.out.println&#40;"Country Label&#58; " + country.getLabel&#40;&#41; &#41;;
    			
    			System.out.println&#40;"Trying to add a State"&#41;;
    			
    			String stateID = 
    				service.addState&#40; countryID, "Uttar Pradesh" &#41;;
    			
    			System.out.println&#40; "State Id = " + stateID &#41;;
    ...

  • #2
    I think this errors forces the rollback:
    Code:
       &#91;java&#93; java.lang.StackOverflowError
       &#91;java&#93; at java.util.HashMap$KeyIterator.<init>&#40;HashMap.java&#58;816&#41;
    Inside your code you are doing probably an infinite cycle on a map which causes a StackOverFlow which is a RuntimeException that gets cought by the TransactionInterceptor that rolls back the whole transaction.

    Comment


    • #3
      Thanks Costin,

      As you can see in my client code, nowhere I am trying to access the HashSet of children (States). Can you help me in pointing-out what should I change my source code.

      This problem has been baffling me for the past 5 days... and I still don't know what modification to make

      Please help !!!

      Comment


      • #4
        Got the Solution !!

        I found my mistake !!

        My POJO base class overrided Java's toString/equals/hashCode methods to supply implementation as provided by Apache commons... This was causing all the problem...

        Thanks costin, your comment helped me a lot... Thanks a lot !!

        Comment


        • #5
          Can you print out the full stack trace so we can see where the overflow is occuring

          Comment


          • #6
            Most probably by using the reflective methods from commons - it has two sets, on in the child, one in the parent - the equals calls takes the set and calls the equals on the objects (the child) which in turn call the parent equals - there you go.

            Comment

            Working...
            X