我无法理解HQL
查询从何处获取信息。我的项目使用不同的线程,每个线程读/写数据库。线程不共享Session对象,而是使用HibernateUtil
类为我创建会话。
直到最近,我只会在写完后关闭一个会议但不会在阅读后关闭。当读取其他线程(与用于写入的Session对象不同的Session对象)时,会立即在数据库但中看到对象的更改。我会得到陈旧的信息。读取和写入总是发生在不同的线程上,这意味着不同的Session对象和不同的会话缓存。
我一直认为通过使用HQL
代替Criteria
,我总是会以数据库(或二级缓存)为目标,而不是会话缓存,但在调试我的代码时,它已经明确了我认为HQL在会话缓存中寻找对象并检索旧的过时对象。
假设HQL
总是以数据库为目标,我错了吗?或者至少是二级缓存?
PS:我只使用一个SessionFactory
对象。
答案 0 :(得分:8)
Hibernate有不同的缓存概念 - 实体缓存和查询缓存。实体缓存是会话缓存(以及第二级缓存,如果已启用)的功能。
假设未启用查询缓存(默认情况下不是这样),那么您的HQL将针对数据库执行。这将返回与查询匹配的实体的ID。如果这些实体已经在会话缓存中,那么Hibernate会返回这些实体,而不是从数据库重建它们。如果你的会话有过时的副本(因为另一个会话更新了数据库),那就是你遇到的问题。
我建议不要使用长期会话,主要是因为这个原因。您应该将会话的生命周期限制为您尝试执行的特定工作单元,然后将其关闭。这样做几乎没有性能损失(假设您使用数据库连接池)。或者,为了确保您没有过时的实体,您可以致电Session.clear()
,但最终可能会出现意外的性能副作用。