【问题标题】:How can I replace HibernateTemplate and HibernateCallback in my Spring 4/Hibernate 4 project?如何在我的 Spring 4/Hibernate 4 项目中替换 HibernateTemplate 和 HibernateCallback?
【发布时间】:2015-07-06 04:25:59
【问题描述】:

我正在开发一个非常大的、旧的 spring3、hibernate3 项目,我的任务是将其升级到 spring4 hibernate4。

显然 hibernate4 不再支持 HibernateTemplate,所以当我升级时,我们的客户端代码会中断。

我们所有的 DAO 都扩展了 HibernateDaoSupport 很多 DAO 代码如下所示:

public class ManagerDaoImpl extends HibernateDaoSupport implements ManagerDAO {

public List<Person> getManagers() {
    List l = (List) this.getHibernateTemplate().executeFind(new HibernateCallback(){
        public Object doInHibernate(Session session) throws HibernateException, SQLException {
            List result = (List) session.createQuery(MySqlQueryString).list();
            return result;
        }
    });
    return l;
}

//........

}

它是用 XML 连接起来的:

<bean id="managerDaoImpl" class="com.foo.bar.hibernate.ManagerDaoImpl">
    <property name="sessionFactory" ref="MySessionFactory" />
</bean>

<bean id="MySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource"     ref="myDataSource" />
    <property name="configLocation" value="WEB-INF/hibernate.cfg.xml" />
</bean>

我认为我需要做的事情:

public List<Person> getManagers() {}
            List result = (List) getSessionFactory().getCurrentSession.createQuery(MySqlQueryString).list();
            return result;
    return l;
}

但这给了我一个错误,例如:

Property 'sessionFactory' threw exception; nested exception is org.hibernate.HibernateException: No Session found for current thread

我做错了什么?

我认为不推荐使用 hibernateTemplate 的全部意义在于 Spring 3+ 可以为我处理事务?

我真的不认为升级此类常用技术的“阻力最小路径”方法会涉及到像会话会话和事务范围这样的操作。

【问题讨论】:

    标签: java spring hibernate


    【解决方案1】:

    你通读过spring事务管理吗?

    http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html

    您可以连接一个全局 txn 拦截器,然后使用 @Transactional 标记您的业务/服务方法(DAO 可能太低级)。 LMK 如果您需要详细信息。干杯。

    编辑: 回应保罗的评论(将其放入答案中,因为评论太长了)。

    @Transactional 旨在用于方法级别,但根据我的经验,DAO 级别太低。需要明确的是,单个概念操作可以涉及多个 DAO 级别的操作,事务边界位于业务操作级别而不是 DAO 级别的优点是您可以获得更一致的状态,因为否则部分业务操作可以失败,但其他人已经提交。

    【讨论】:

    • “DAO 可能级别太低” - 你是什么意思?我以为 hibernateCallback 是之前事务的范围?方法级别的@transaction 会导致问题吗?
    • 我在回答中对此进行了一些扩展。
    • 啊啊,我明白你的意思了,谢谢! :) 昨天当我试图理解你的答案时,我的大脑刚刚炸了。我还有一个问题:回调在旧代码中的工作方式——它是界定事务范围的回调,是吗?所以....我不应该在我的新代码中以编程方式(而不是通过 XML 和拦截器)实现我的新事务吗?
    • 你可以,这取决于你,但@Transactional + AOP 是传统的spring方法。
    • 但是 hibernateCallbacks 实际上是什么限制了我的交易?那就是那个方法调用的作用?此时的主要目标是使现有代码像以前一样工作,因此选择与以前相同的模式似乎是一条好路——如果我想在春季 4 复制这些“编程会话”,我会使用什么?
    【解决方案2】:

    正如 Taylor 所说,您需要配置交易。

    更多详情请参考以下帖子:

    1) Spring and hibernate: No Session found for current thread

    2) Spring + Hibernate : No Session found for current thread 上面写着:

    sessionFactory 需要事务才能工作,为了解决它,声明一个 Spring 中的事务管理器。

    【讨论】:

      【解决方案3】:

      (配置完所有内容后...)
      由您的类 ManagerDaoImpl 扩展的 HibernateDaoSupport 具有受保护的方法 currentSession()。所以你可以写

      public List<Person> getManagers() {}
                  List result = (List) currentSession.createQuery(MySqlQueryString).list();
                  return result;
          return l;
      }
      

      【讨论】:

      • 这是一些奇怪的代码,有 2 个返回...请再检查一遍。
      猜你喜欢
      • 1970-01-01
      • 2018-01-11
      • 1970-01-01
      • 2014-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-10
      • 1970-01-01
      相关资源
      最近更新 更多