Java 从Hibernate3迁移到Hibernate4将继续获取不支持的嵌套事务

Java 从Hibernate3迁移到Hibernate4将继续获取不支持的嵌套事务,java,hibernate,jakarta-ee,hibernate-4.x,hibernate3,Java,Hibernate,Jakarta Ee,Hibernate 4.x,Hibernate3,在我们将应用程序从hibernate3迁移到hibernate4的前一周,hibernate3中的每件事情都运行良好,但在迁移到hibernate4之后。我不断得到不支持的嵌套事务 下面是我的服务层,它正在调用dao public class LeaveApplicationService implementsSerializable,LeaveApplicationInterfaceService{ @Autowired private LeaveApplicationInte

在我们将应用程序从hibernate3迁移到hibernate4的前一周,hibernate3中的每件事情都运行良好,但在迁移到hibernate4之后。我不断得到不支持的嵌套事务

下面是我的服务层,它正在调用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();
        }
}
道层

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;

}

}
我在堆栈轨迹中看到的例外是

My db.xml


有两种可能性:

会话关闭时打开事务的实现定义行为:

在关闭连接之前,请确保提交(或回滚,对于只读来说并不重要)事务。Hibernate
Session.close()
关闭底层连接;并声明事务打开时的行为由实现定义(即,一些实现将自动关闭事务,其他实现可能引用计数连接并保持其打开)

一般情况是:

try {
    Transaction t = sessionFactory.getCurrentSession().beginTransaction();
    try {
        // do work
        t.commit();
    } catch (Exception e) { 
        t.rollback();
        throw e;
    }
} finally {
    sessionFactory.getCurrentSession().close();
}
以前的事务仍处于活动状态:

如果以前的交易在其他地方仍处于活动状态,您可以执行以下操作:

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

// then use t (or session's current transaction, same thing)
或者,如果您没有传递
事务

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

// then use session's current transaction

但是,您可能仍然需要检查代码,以查看在给定连接上打开事务的其他位置。

检查hibernate4中添加的更新,我看不到给定代码的解决方法。Hibernate从不支持嵌套事务,并且这是在Hibernate 4中强制执行的。因为AbstractTransactionImpl以前不存在。查看与发布异常的完整堆栈跟踪类似的问题。另外,您的服务方法启动一个事务,但不提交也不回滚它。正如我仅用于获取记录一样,没有什么是提交和回滚。根据链接getCurrentSession()将自动执行。它将冲洗并关闭连接。所以我不必担心,我看不到这个链接的任何地方写着这样的内容;JDBC文档很清楚。你试过了吗?无论如何,我在答案中添加了第二种可能性。我没有使用spring事务传播属性。所以你建议我使用的@JasonC可能是对的(除了JDBC文档id很清楚之外,论坛中的帖子太旧了)。因此,请尝试告诉我们答案。如果这个建议没有帮助,请尝试将您的hibernate版本更新/降级到其他次要版本。
if (session.getTransaction() == null || !session.getTransaction().isActive())
    session.beginTransaction();

// then use session's current transaction