使用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; }
还有一个更重要的问题是HibernateCallback方法在查询返回值后每次关闭会话吗? 我有一个用例,每次刷新状态页面都会多次调用这个函数,所以每次打开会话和查询数据库都会这样,或者它会将查询结果存储在内存中,然后每当我调用这个函数时,都会弹出结果从记忆里。
我看过( 参考 ):
默认情况下,Spring HibernateTemplate.execute()会在完成时关闭所有打开的会话。 与惰性初始化一起使用时,您可能会收到类似以下内容的LazyInitializationException
org.hibernate.LazyInitializationException:无法初始化代理 – 没有会话
任何对相关文档部分的引用都将受到高度赞赏。
更新:
在我的情况下我使用ejb事务并将其设置为“支持”,我相信在这种情况下,事务被设置为支持,它是可选的,因此每次创建新会话时,hibernate将查询数据库以获得结果,所以这是我的有瓶颈,这是一个正确的假设吗?
为了你的观点,为什么要使用HibernateCallback
。 简短回答 – 它允许您访问当前事务绑定会话,以执行更复杂的hibernatefunction。 大多数情况下, HibernateTemplate
上的简单方法就足够了,但有时您需要转到Session
。
这个难题有两个部分。
第一个是事务范围,它通过使用PlatformTransactionManager
/ TransactionTemplate
或@Transactional
注释来定义。 有关详细信息,请参阅spring docs / google。
第二个是当你在一个事务中时, HibernateTemplate
将使用一些魔法与当前事务进行交互。
因此像hibernateTemplate.save()
这样的简单操作将参与事务。 像您的示例更复杂也将参与交易。 事实上,hTemplate上的任何方法都会参与其中。
因此,请知道会议何时结束的问题
- 如果您明确使用事务,请参阅上面的第一点,然后当事务范围关闭时,将提交事务并关闭会话。
- 如果没有事务,spring会在每次调用
HibernateTemplate
方法时为您创建一个会话,并在之后立即关闭它。 这不是首选方法,因为除非您正在做一些非常简单的事情,否则结果将从会话中分离出来,您将获得LazyInitexception。
在上面的第二个案例中需要注意的重点是没有明确的交易。 您受连接的自动提交模式的支配,因此您可以在回调中执行保存,保存,抛出exception。 第一次保存可能已经提交,没有交易就没有保证。
我的建议是,在进行任何更新时,使用交易。
如果所有交易内容都是新的,请查看交易章节的春季文档。
如果你还在使用Spring,你应该只在你的Repository或Service层周围使用声明式事务管理来透明地处理它。 PlatformTransactionManager实现将执行适合给定持久性提供程序的操作。
在您没有数据访问代码之后依赖于惰性集合的初始化被认为是不好的做法 – 这通常意味着您在应用程序的控制器/视图层中有一些应该移动到服务层的业务逻辑。