使用Hibernate回调的优点?

Rac*_*hel 16 java database spring hibernate

我无法理解使用Hibernate Callback方法的优点,是否有任何优势或特定用例我们应该去实现它.

public List findRecentRequests(final int offset, final int length)
{
    List list = getHibernateTemplate().executeFind(new HibernateCallback()
    {
        public Object doInHibernate(Session session) throws HibernateException
        {
            Query q = session.createQuery(FIND_RECENT_REQUESTS);
            q.setFirstResult(offset);
            q.setMaxResults(length);
            return q.list();
        }
    });
    return list;
}
Run Code Online (Sandbox Code Playgroud)

还有一个更重要的问题是HibernateCallback方法在查询返回值后每次关闭会话吗?我有一个用例,每次刷新状态页面都会多次调用这个函数,所以每次打开会话和查询数据库都会这样,或者它会将查询结果存储在内存中,然后每当我调用这个函数时,都会弹出结果从记忆里.

我看过(参考):

默认情况下,Spring HibernateTemplate.execute()会在完成时关闭所有打开的会话.与惰性初始化一起使用时,您可能会收到类似以下内容的LazyInitializationException

org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话

任何对相关文档部分的引用都将受到高度赞赏.

更新:

在我的情况下,我正在使用ejb事务并将其设置为"支持",我相信在这种情况下,事务被设置为支持,它是可选的,因此每次创建新会话时,hibernate将查询数据库以获得结果,所以这是我的有瓶颈,这是一个正确的假设吗?

Mik*_*e Q 22

关于为什么使用你的观点HibernateCallback.简短回答 - 它允许您访问当前事务绑定会话,以执行更复杂的休眠功能.大多数情况下,简单的方法就HibernateTemplate足够了,但有时你需要深入研究Session.

这个难题有两个部分.

第一个是通过使用PlatformTransactionManager/ TransactionTemplateOR @Transactional注释定义的事务范围.有关详细信息,请参阅spring docs/google.

第二个是,当你在一个事务中时,HibernateTemplate将使用一点魔法与当前事务进行交互.

所以一个简单的操作就像hibernateTemplate.save()参与交易一样.像您的示例更复杂也将参与交易.事实上,hTemplate上的任何方法都会参与其中.

因此,请知道会议何时结束的问题

  • 如果您明确使用事务,请参阅上面的第一点,然后当事务范围关闭时,将提交事务并关闭会话.
  • 如果没有事务,spring会在每次调用HibernateTemplate方法时为您创建一个会话,并在之后立即关闭它.这不是首选方法,因为除非您正在做一些非常简单的事情,否则结果将从会话中分离出来并且您将获得LazyInit异常.

在上面的第二个案例中需要注意的重点是没有明确的交易.您受连接的自动提交模式的支配,因此您可以在回调中执行保存,保存,抛出异常.第一次保存可能已经提交,没有交易就没有保证.

我的建议是,在进行任何更新时,使用交易.

如果所有事务内容都是新的,请查看事务章节的spring文档.


mil*_*ose 6

如果你还在使用Spring,你应该只使用存储库或服务层周围的声明式事务管理来透明地处理它.PlatformTransactionManager实现将执行适合给定持久性提供程序的操作.

在您没有数据访问代码之后依赖延迟集合进行初始化被认为是不好的做法 - 这通常意味着您在应用程序的控制器/视图层中有一些应该移动到服务层的业务逻辑.