4

A week before we migrated the application from hibernate3 to hibernate4 every thing worked fine in hibernate3 but after migrating to hibernate4. I keep getting nested transactions not supported.

Below is my service layer which is calling the dao

public class LeaveApplicationService implementsSerializable,LeaveApplicationInterfaceService{
    @Autowired
    private LeaveApplicationInterfaceDao _leavApplicationInterfaceDao;
       //getter setter
    @Override
    public synchronized void clickOnAddLeaveButton(LeaveApplicationViewBean leaveApplicationViewBean) {
    SessionFactory sessionFactory=(SessionFactory) ObjectFactory.getBean("sessionFactory");
    sessionFactory.getCurrentSession().beginTransaction();


        try{
                leaveApplicationViewBean.get_employeeListObj().clear();
                leaveApplicationViewBean.get_leaveTypelist().clear();
                leaveApplicationViewBean.get_leaveApproveers().clear();
                //leaveApplicationViewBean.set_employeeListObj(get_leavApplicationInterfaceDao().getEmployeeList());
                leaveApplicationViewBean.set_leaveTypelist(get_leavApplicationInterfaceDao().getLeaveType());
                leaveApplicationViewBean.set_leaveApproveers(get_leavApplicationInterfaceDao().getLeaveApprover(CmsUtil.getSession("userId").toString()));

        }catch(Exception e){
            CmsLogger.errorLog(LeaveApplicationService.class, e);
        }finally{
            sessionFactory.getCurrentSession().close();
        }
}

The Dao layer

public class LeaveApplicationDao extends TransactionService implements Serializable,LeaveApplicationInterfaceDao{
    private static final long serialVersionUID = 6237725881698448330L;

    public List<LeaveApprover> getLeaveApprover(String userId) throws Exception {
      List<LeaveApprover> _leavApprovers=new ArrayList<LeaveApprover>();
      Iterator it=getSessionFactory().getCurrentSession().createQuery(sql.toString()).setParameter("practiceAreaId",CmsUtil.getSession("practiceAreaId").toString())                                            .setParameter("userId",userId).setCacheable(true)
                                                                                    .list().iterator();
      while(it.hasNext()){
        Object[] obj=(Object[]) it.next();
        LeaveApprover leaveApprover=new LeaveApprover();
        leaveApprover.set_approverId((String) obj[0]);
        leaveApprover.set_approverName((String) obj[1]);
        _leavApprovers.add(leaveApprover);
    }

    return _leavApprovers;
}



public List<TimeProjectCategory> getLeaveType() throws Exception{
    List<TimeProjectCategory> timeProjectCategories=new ArrayList<TimeProjectCategory>();
    Iterator it =getSessionFactory().getCurrentSession().createQuery(sql.toString()).setCacheable(true).list().iterator();
        while(it.hasNext()){
            Object[] obj=(Object[]) it.next();
            TimeProjectCategory category=(TimeProjectCategory) ObjectFactory.getBean("domainTimeProjectCategoryObj");
            category.getProjectId().set_projectId((String) obj[0]);
            category.setTimeCategory((String) obj[1]);
            category.setTimeProjectCategoryId((String) obj[2]);
            timeProjectCategories.add(category);
        }


    return timeProjectCategories;

}

}

And my TransactionService class

public class TransactionService{
/**
 * 
 */
private static final long serialVersionUID = 3747504246445270484L;

@Autowired
private DataSource dataSource;

@Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
    return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}


public DataSource getDataSource() {
    return dataSource;
}
public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
}


}

And the exception I see in the stack-track is

Stack Trace for the code

My db.xml

db.xml file

Satyam Koyani
  • 4,236
  • 2
  • 22
  • 48
BholaVishwakarma
  • 581
  • 6
  • 18

1 Answers1

2

There are two possibilities:

Implementation-defined behavior with open transactions on session close:

Make sure you commit (or rollback, doesn't matter for read-only) the transaction before closing the connection. Hibernate Session.close() closes the underlying connection; and http://docs.oracle.com/javase/6/docs/api/java/sql/Connection.html#close%28%29 states that the behavior when a transaction is open is implementation-defined (i.e. some implementations will automatically close the transaction, others may reference count the connection and hold it open).

The general pattern is:

try {
    Transaction t = sessionFactory.getCurrentSession().beginTransaction();
    try {
        // do work
        t.commit();
    } catch (Exception e) { 
        t.rollback();
        throw e;
    }
} finally {
    sessionFactory.getCurrentSession().close();
}

A previous transaction is still active:

If a previous transaction is still active from somewhere else, you can do this:

Transaction t = session.getTransaction();
if (t == null || !t.isActive()) 
    t = session.beginTransaction();

// then use t (or session's current transaction, same thing)

Or, if you're not passing the Transaction around:

if (session.getTransaction() == null || !session.getTransaction().isActive())
    session.beginTransaction();

// then use session's current transaction

But you will still probably want to examine your code to see where else a transaction is being opened on a given connection.

Jason C
  • 38,729
  • 14
  • 126
  • 182
  • According to the link http://stackoverflow.com/questions/8046662/hibernate-opensession-vs-getcurrentsession getCurrentSession() will do it automatically. It will flush and close the connection . so I should not be worried about that. – BholaVishwakarma Oct 28 '13 at 11:42
  • I don't see that written anywhere in that link; the JDBC documentation is clear. Have you tried it? In any case I added a second possibility to the answer. – Jason C Oct 28 '13 at 11:44
  • I haven't used spring transaction propagation attribute. So what you suggest me to use. – BholaVishwakarma Oct 28 '13 at 12:33
  • @JasonC may be right (beside that the JDBC documentation id clear, that post in the forum is simply too old). So simply try and tell us the response. – V G Oct 30 '13 at 17:31
  • If this advice does not help, try updating/downgrading your hibernate version to a different minor version. – V G Oct 30 '13 at 17:36