告诉我的那样,运行此查询时也使用了缓存的查询结果:
criteria.SetCacheable(true)
有人可以解释为什么或将我指向此“功能”的一些深入文档?或者,更好的是,有人解决问题吗?
NHIBERNATE使用第一级缓存(由身份图实现)来缓存您查询的每个对象。即使您查询一个对象列表,nhibernate在单个实体上也有效。 我解释了一些东西:如果执行此查询,请查询您的查询并尝试使用ID 1:获得实体。
SELECT this_.Id as y0_,
this_.Name as y1_
FROM Products this_
WHERE this_.IsActive = 1
ORDER BY this_.IsPremium desc,
this_.Name
NHIBERNATE将检查缓存,以查看它是否已包含ID 1。如果是这样,将返回缓存的对象,并且不会运行查询。如果不是,则执行查询选择记录,将其放入缓存中并将其返回给您。如果您再次执行查询,则将其缓存,并且该对象将在没有新查询的情况下返回。
session.get<SomeEntity>(1);
NHibrenate不知道将获取哪个ID,因此即使您两次运行查询,它也会查询所有记录并检查结果。可以说,您的数据库中有2个记录(ID 1和2)。当您的高速缓存仍然为空时,您可以用查询获取它们。这两个记录都被获取,放入缓存并返回给您。现在,您插入了记录3、4和5,并且在您的情况下,您也将更新记录1。现在,如果您再次运行查询,它将读取所有5个记录,但现在缓存记录3、4和5。您将获得一个列表,其中有5个对象,其中3、4、5是刚刚读取的对象,但返回了1和2的缓存版本。您将无法获得ID的更新版本1.
要回答您的问题:更改订单并不重要。您的查询将导致一组记录,这些记录将对缓存进行检查,如果其中一个已经存在,则将返回缓存版本。使用session.refresh(obj);如果您知道哪些已更新。
认为会话中的某些或所有实体(这意味着它们将被扔掉从缓存中扔出,并且可以用查询进行补充)。注意:如果您驱逐它们,则不会保存更改。
您可以使用无状态会话,该会话具有 - 如无状态名称所建议的 - 无缓存。
交易
在更新之前打开会话并调用clear()
禁用缓存
尽管如此,nhibernate总是会生成针对X的更新查询,从而导致不正确的值存储在数据库中。
我怎么能解决这个问题?