Java 升级到Hibernate 4.1和;臭名昭著的;模板类

Java 升级到Hibernate 4.1和;臭名昭著的;模板类,java,spring,hibernate,Java,Spring,Hibernate,我正在将我们的项目从Hibernate3.0升级到Hibernate4.1.6。(我们目前正在使用spring 3.1) 我在许多文章和HibernateTemplate文档中读到,由于版本4.0 HibernateTemplate不受支持,我应该用调用sessionFactory.getCurrentSession()来替换它的用法以获取会话 由于该项目是从较旧版本的Hibernate开始的,其中鼓励使用HibernateTemplate,我们目前在整个项目中使用了124次HibernateT

我正在将我们的项目从Hibernate3.0升级到Hibernate4.1.6。(我们目前正在使用spring 3.1)

我在许多文章和HibernateTemplate文档中读到,由于版本4.0 HibernateTemplate不受支持,我应该用调用
sessionFactory.getCurrentSession()
来替换它的用法以获取会话

由于该项目是从较旧版本的Hibernate开始的,其中鼓励使用
HibernateTemplate
,我们目前在整个项目中使用了124次
HibernateTemplate
。我担心用
sessionFactory.getCurrentSession()
替换所有这些事件可能会在我们的项目中插入回归错误。此外,还有一些地方在非事务上下文中使用了
HibernateTemplate
,其中没有“当前”会话。在这种情况下我该怎么办?打开一个新会话并自己处理(关闭)它?当我使用
HibernateTemplate
时,情况并非如此

你有解决这些问题的好策略吗

谢谢

相关阅读:

  • 在文档中签出。它说,
    SessionFactory.getCurrentSession()
    是可插入的,并且有一个实现将“当前会话”保留在
    ThreadLocal
    中,而不是JTA事务中。ThreadLocalSessionContext还将在从该会话创建的hibernate事务结束时关闭会话,因此您不必担心自己关闭会话


    关于引入回归bug,升级库总是有风险的,尤其是当它是应用程序的核心,如hibernate时。我能给出的唯一建议是在升级之前确保您的测试套件具有良好的覆盖率。毕竟,这是你的测试套件的工作——捕捉回归bug。

    好吧,这就是我实际做的,我不知道这是否是解决这个问题的最佳解决方案,但在我们的情况下,因为我在寻找最本地化的解决方案,对我来说似乎是最好的

    我已经扩展了springframework.orm.hibernate3.HibernateTemplate并创建了一个新的MyHibernateTemplate。新模板的主要作用是覆盖大多数hibernate3.HibernateTemplate最终导致的doExecute方法,并提供旧SessionFactoryUtils提供的一些功能(如isSessionTransactional和applyTransactionTimeout)

    新doExecute复制旧doExecute的逻辑,但不是SessionFactoryUtils.getNewSession,而是首先尝试查找打开的会话getSessionFactory()。getCurrentSession():

    您只需手动关闭此会话:

        finally {
        // if session was used in an existing transaction restore old settings
        if (existingTransaction) {
            //logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
            disableFilters(session);
            if (previousFlushMode != null) {
                session.setFlushMode(previousFlushMode);
            }
        }
        // if not and a new session was opened close it
        else {
            // Never use deferred close for an explicitly new Session.
            if (newSessionOpened) {
                SessionFactoryUtils.closeSession(session);
                //_log.info("Closing opened Hibernate session");
            }
        }
    

    我尽量简短地回答这个问题,但如果有任何问题,我可以进一步详细说明。

    您也可以继续使用
    HibernateTemplate
    getCurrentSession()
    ,因为在许多情况下
    openSession()
    可能不是最佳选择,因为您需要自己关闭会话。 要使用currentSession,可以添加以下内容来管理事务:

    org.hibernate.engine.transaction.jta.platform.internal.JBossAppServerJtaPlatform


    其中,密钥的值取决于您的AS。

    不帮助回答仍然良好的阅读也可能是相关的:这是一个棘手的问题,因为HibernateTemplate和friends中有大量的功能。在找到这篇文章之前,我已经走了与您描述的大致相同的道路,但是克隆了HibernateTemplate而不是扩展它。我不确定这是不是最好的策略。我还有很多功能要考虑,所以我担心结果代码的稳定性。我知道这对你们来说已经是一段古老的历史了,但你们能分享更多关于你们的战略,以及它是如何为你们制定的吗?
        finally {
        // if session was used in an existing transaction restore old settings
        if (existingTransaction) {
            //logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
            disableFilters(session);
            if (previousFlushMode != null) {
                session.setFlushMode(previousFlushMode);
            }
        }
        // if not and a new session was opened close it
        else {
            // Never use deferred close for an explicitly new Session.
            if (newSessionOpened) {
                SessionFactoryUtils.closeSession(session);
                //_log.info("Closing opened Hibernate session");
            }
        }