使用休眠回调的优势?
问题内容:
我无法理解使用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;
}
还有一个更重要的问题是HibernateCallback方法是否在查询返回值后每次都关闭会话?我有用例,每次刷新状态页时都会多次调用此函数,因此每次打开会话和查询数据库时都会调用此函数,或者将查询结果存储在内存中,然后每次调用此函数时,都会弹出结果从记忆里。
我已阅读(参考):
春天的HibernateTemplate.execute()默认在完成时关闭所有打开的会话。与延迟初始化配合使用时,您可能会收到LazyInitializationException,如下所示
org.hibernate.LazyInitializationException:无法初始化代理-没有会话
任何对相关文档部分的引用将不胜感激。
更新:
在我的情况下,我使用ejb事务并将其设置为“
support”,我认为在这种情况下,由于事务设置为support,因此它是可选的,因此每次创建新会话时,hibernate都会查询数据库以获取结果,所以这就是有瓶颈,是否可以做出正确的假设?
问题答案:
就您为什么使用HibernateCallback
。简短答案-
它允许您访问当前的事务绑定会话,以执行更复杂的休眠功能。在大多数情况下,使用简单的方法就HibernateTemplate
足够了,但是有时您需要使用Session
。
这个难题有两个部分。
第一个是通过使用PlatformTransactionManager
/ TransactionTemplate
OR
@Transactional
注释定义的事务范围。有关更多信息,请参见spring docs / google。
第二个是,当您处于事务中时,HibernateTemplate
将使用一些魔术与当前事务进行交互。
因此,像这样的简单操作hibernateTemplate.save()
将参与交易。像您的示例这样的更复杂的事务也将参与事务。实际上,hTemplate上的几乎任何方法都会参与。
因此,请问您有关会话何时关闭的问题
- 如果您明确使用事务,请参见上面的第一点,然后,当事务作用域关闭时,将提交事务,并关闭会话。
- 如果没有事务,spring每次您调用一个
HibernateTemplate
方法都会为您创建一个会话,然后立即关闭它。这不是首选方法,因为除非您执行非常简单的操作,否则结果将与会话分离,并且您将获得LazyInit异常。
在上面第二种情况下要注意的重要一点是,没有显式事务。您受连接自动提交模式的支配,因此您可能会在回调中执行保存,保存,引发异常的操作。第一次保存可能已提交,没有交易就不能保证。
我的建议是在进行任何更新时都使用事务。
如果您对交易的所有内容都不熟悉,请查看spring文档以获取交易章节。