-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Hibernate Transactions
PostPosted: Mon Sep 13, 2010 8:51 pm 
Newbie

Joined: Mon Sep 13, 2010 2:12 am
Posts: 4
Hi,

Can anyone help me with this please?
I am trying to develop a small hibernate application to learn hibernate features.
I tried transferring funds from one a/c to another, in which one a/c is debited and the other is credited.
1. debit txn
2. credit txn
Everything works fine and transaction goes well. However, if some exception occurs in second txn, both txns should get rolled back.
But debit txn is going successful and credit txn is failing, which should not happen. I am not getting any idea how to do this.

Please help me. I have given some of my code below. Let me know if u need any other details as well.

package hibernateapp.dao;

import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import hibernateapp.entity.CASAEntity;
import hibernateapp.util.SessionFactoryUtil;

public class CasaDao {

final static Logger logger = Logger.getLogger(CasaDao.class);

public void transferFunds(String fromCustId, double amt, String toCustId){
Session session = SessionFactoryUtil.getInstance().getCurrentSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
try{
debitAcct(fromCustId, amt);
creditAcct(toCustId, amt);
}catch(Exception e){
if(tx != null){ //&& tx.isActive()){
try{
tx.rollback();
}catch(HibernateException he){
logger.debug("Error in rolling back the txn");
}
//throw e;
}
}
tx.commit();
}catch(RuntimeException re){
if(tx != null){
try{
tx.rollback();
}catch(HibernateException he){
logger.debug("Error in rolling back the txn");
}
throw re;
}
}
}

private void debitAcct(String custId, double amtToDebit){
Session session = SessionFactoryUtil.getInstance().getCurrentSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
double bal = 0.0;
List list = session.createQuery("select ce from CASAEntity as ce where custId=:CustId").
setString("CustId",custId).list();
Iterator iter = list.iterator();
while(iter.hasNext()){
CASAEntity casa = (CASAEntity)iter.next();
logger.info("List of Customers");
logger.debug("{"+casa+" }");
bal = casa.getBalance() - amtToDebit;
casa.setBalance(bal);
updateEntity(casa);
}
tx.commit();
}catch(RuntimeException re){
if(tx != null){
try{
tx.rollback();
}catch(HibernateException he){
logger.debug("Error in rolling back the txn");
}
throw re;
}
}
}

private void creditAcct(String custId, double amtToCredit){
Session session = SessionFactoryUtil.getInstance().getCurrentSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
double bal = 0.0;
List list = session.createQuery("select ce from CASAEntity as ce where custId=:CustId").
setString("CustId",custId).list();
Iterator iter = list.iterator();
while(iter.hasNext()){
CASAEntity casa = (CASAEntity)iter.next();
logger.info("List of Customers");
logger.debug("{"+casa+" }");
bal = casa.getBalance() + amtToCredit;
casa.setBalance(bal);
updateEntity(casa);
}
try{
throw new Exception("Exception while crediting the account");
}catch(Exception e){
if(tx != null){ //&& tx.isActive()){
try{
tx.rollback();
}catch(HibernateException he){
logger.debug("Error in rolling back the txn");
}
//throw e;
}
}
tx.commit();
}catch(RuntimeException re){
if(tx != null){
try{
tx.rollback();
}catch(HibernateException he){
logger.debug("Error in rolling back the txn");
}
throw re;
}
}
}

}

And this is my table:
mysql> select * from casatrans;
+--------+--------------+--------------+
| CustId | CustomerName | Acct_Balance |
+--------+--------------+--------------+
| 2001 | John | 9000 |
| 2002 | Dent | 15000 |
| 2003 | Benz | 27000 |
+--------+--------------+--------------+
3 rows in set (0.00 sec)



Thanks


Top
 Profile  
 
 Post subject: Re: Hibernate Transactions
PostPosted: Tue Sep 14, 2010 3:04 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
You are using too many transactions. Get rid of the transactions in the debitAcct and creditAcct methods.


Top
 Profile  
 
 Post subject: Re: Hibernate Transactions
PostPosted: Tue Sep 14, 2010 12:21 pm 
Newbie

Joined: Mon Sep 13, 2010 2:12 am
Posts: 4
Thanks a lot for your response
I have removed transactions in both the methods and still the same thing is happening. I am not understanding where is the mistake.
And even if I throw some exception in the debitAcct method, still the acct is getting debited instead of rolling back txn.
I have pasted the modified code. Please give me some clue. Thanks in Advance

public void transferFunds(String fromEntity, double amt, String toEntity){
Session session = SessionFactoryUtil.getInstance().getCurrentSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
try{
debitAcct(fromEntity, amt);
creditAcct(toEntity, amt);
}catch(Exception e){
if(tx != null){ //&& tx.isActive()){
try{
tx.rollback();
}catch(HibernateException he){
logger.debug("Error in rolling back the txn");
}
//throw e;
}
}
tx.commit();
}catch(RuntimeException re){
if(tx != null){
try{
tx.rollback();
}catch(HibernateException he){
logger.debug("Error in rolling back the txn");
}
throw re;
}
}
}

private void debitAcct(String custId, double amtToDebit){
Session session = SessionFactoryUtil.getInstance().getCurrentSession();
try{
double bal = 0.0;
List list = session.createQuery("select ce from CASAEntity as ce where custId=:CustId").
setString("CustId",custId).list();
Iterator iter = list.iterator();
while(iter.hasNext()){
CASAEntity casa = (CASAEntity)iter.next();
logger.info("List of Customers");
logger.debug("{"+casa+" }");
bal = casa.getBalance() - amtToDebit;
casa.setBalance(bal);
updateEntity(casa);

}catch(RuntimeException re){
throw re;
}
}

private void creditAcct(String custId, double amtToCredit){
Session session = SessionFactoryUtil.getInstance().getCurrentSession();
try{
double bal = 0.0;
List list = session.createQuery("select ce from CASAEntity as ce where custId=:CustId").
setString("CustId",custId).list();
Iterator iter = list.iterator();
try{
while(iter.hasNext()){
CASAEntity casa = (CASAEntity)iter.next();
logger.info("List of Customers");
logger.debug("{"+casa+" }");
bal = casa.getBalance() + amtToCredit;
casa.setBalance(bal);
updateEntity(casa);
throw new Exception("Exception while crediting the account");
}
}catch(Exception e){
e.printStackTrace();
}
}catch(RuntimeException re){
throw re;
}
}


Top
 Profile  
 
 Post subject: Re: Hibernate Transactions
PostPosted: Tue Sep 14, 2010 1:56 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Are you using a database that supports transactions? For example, MySQL with MyISAM tables doesn't.

What does the updateEntity() method do? I don't see any reason to call this method. Hibernate will automatically detect the changes you have made and save them when you commit the transaction.

The error handling in your creditAcct seems a bit strange... There is a 'catch (Exception ex)' but all you do is printing the stacktrace and let the code continue... no rollback here... The rest of your code is also a bit overloaded with error handling and it is hard to follow exactly what is catched were. Sometimes you catch Exception and sometimes RuntimeException and sometimes HibernateException. I suggest that you look at http://docs.jboss.org/hibernate/stable/ ... nonmanaged in the documentation for a simple template that you can use.

It is also really hard to read the pasted code since it doesn't have proper indentation... Please use the 'Code' button when you post code and it will look much better.


Top
 Profile  
 
 Post subject: Re: Hibernate Transactions
PostPosted: Tue Sep 14, 2010 5:17 pm 
Newbie

Joined: Mon Sep 13, 2010 2:12 am
Posts: 4
Hi,

Thanks again for your response.
I have made changes to my code by following the link you provided. Now the code is working properly.
The txn is getting rolled back if any of the methods fail. I have pasted the code again. Please suggest me if I have to implement anything to make my code work much better.

Code:
public void transferFunds(String fromEntity, double amt, String toEntity){
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        Transaction tx = null;
        try{
            tx = session.beginTransaction();
            debitAcct(fromEntity, amt);
            creditAcct(toEntity, amt);
            tx.commit();
        }catch(Exception e){
            if(tx != null){
                try{
                    tx.rollback();
                }catch(HibernateException he){
                    logger.debug("Error in rolling back the txn");
                }
            }
        }
    }
   
    private void debitAcct(String custId, double amtToDebit)
                                  throws Exception{
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        try{
            double bal = 0.0;
            List list = session.createQuery("select ce from CASAEntity as ce where custId=:CustId").
                        setString("CustId",custId).list();
            Iterator iter = list.iterator();
                while(iter.hasNext()){
                    CASAEntity casa = (CASAEntity)iter.next();
                    logger.info("List of Customers");
                    logger.debug("{"+casa+" }");
                    bal = casa.getBalance() - amtToDebit;
                    casa.setBalance(bal);
//                    throw new Exception("Exception while debiting the account");
                }
        }catch(Exception e){
                throw e;
        }
    }
   
    private void creditAcct(String custId, double amtToCredit) throws Exception{
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        try{
            double bal = 0.0;
            List list = session.createQuery("select ce from CASAEntity as ce where custId=:CustId").
                        setString("CustId",custId).list();
            Iterator iter = list.iterator();
                while(iter.hasNext()){
                    CASAEntity casa = (CASAEntity)iter.next();
                    logger.info("List of Customers");
                    logger.debug("{"+casa+" }");
                    bal = casa.getBalance() + amtToCredit;
                    casa.setBalance(bal);
//                    throw new Exception("Exception while crediting the account");
                }
        }catch(Exception e){
                throw e;
        }
    }


Thanks,
Alice


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.