【问题标题】:Repeating a query does not refresh the properties of the returned objects重复查询不会刷新返回对象的属性
【发布时间】:2012-07-09 20:08:52
【问题描述】:

使用 NHibernate 进行条件查询时,我想从缓存中获取新结果而不是旧结果。

流程基本上是:

  1. 在 NHibernate 应用程序中查询持久对象。
  2. 从外部更改数据库条目(另一个程序,在 SSMS/MSSQL 中手动编辑等)。
  3. 查询持久化对象(查询代码相同),之前加载的对象应从数据库中刷新。

这是代码(对象名称略有更改):

public IOrder GetOrderByOrderId(int orderId)
{    
...
IList result;
var query = 
    session.CreateCriteria(typeof(Order))
        .SetFetchMode("Products", FetchMode.Eager)
        .SetFetchMode("Customer", FetchMode.Eager)
        .SetFetchMode("OrderItems", FetchMode.Eager)
        .Add(Restrictions.Eq("OrderId", orderId));
query.SetCacheMode(CacheMode.Ignore);
query.SetCacheable(false);

result = query.List();
...
}

我添加了 SetCacheMode 和 SetCacheable 来禁用缓存。此外,NHibernate 工厂是使用配置参数 UseQueryCache=false 设置的:

Cfg.SetProperty(NHibernate.Cfg.Environment.UseQueryCache, "false");

无论我为查询或会话做什么,包括 Put/Refresh 缓存模式:NHibernate 都会在第二次调用查询时向我返回过时的对象,而没有外部提交的更改。 Info btw.:在这种情况下,过时的值是 Version 列的值(测试是否可以在保存之前检测到陈旧的对象状态)。但出于多种原因,我需要新的查询结果!

NHibernate 甚至会生成一个 SQL 查询,但它从不用于返回的值。

保持会话打开对于仅对脏列进行动态更新是必要的(也没有用于解决方案的无状态会话!);我不想在代码中到处添加 Clear()、Evict() 或类似的东西,特别是因为查询处于较低级别并且不记得以前加载的对象。悲观锁定会降低性能(多用户环境!)

有没有办法通过配置强制 NHibernate 直接向数据库发送查询并获得新的结果,而不是使用不需要的缓存功能?

【问题讨论】:

    标签: nhibernate session caching


    【解决方案1】:

    首先:这与二级缓存(由SetCacheModeSetCacheable 控制)没有任何关系。即使是这样,这些控制查询的缓存,而不是返回实体的缓存。

    当一个对象已经被加载到当前会话中(也有人称之为“一级缓存”,虽然它不是缓存而是Identity Map),使用任何方法再次从数据库中查询它都会从不覆盖它的值。

    这是设计使然,这样做有充分的理由。

    如果您需要通过查询更新多条记录中可能更改的值,您必须事先Evict它们。

    或者,您可能想了解Stateless Sessions

    【讨论】:

      【解决方案2】:

      此代码是否在事务中运行?还是该外部进程在事务中运行?如果这两个中的一个仍在交易中,您将看不到任何更新。

      如果不是这样,您也许可以在 NHibernate 创建的日志消息中找到问题。这些信息非常丰富,总是会告诉你它在做什么。

      保持会话打开对于仅对脏列进行动态更新是必要的

      这要么是问题,要么将来会成为问题。 NHibernate 正在尽一切努力让您的生活更美好,但您正在尽最大努力阻止 NHibernate 正常工作。

      如果您希望 NHibernate 仅更新脏列,您可以查看类映射文件中的 dynamic-update-attribute

      【讨论】:

        猜你喜欢
        • 2015-03-25
        • 2021-09-14
        • 1970-01-01
        • 2014-02-17
        • 2020-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多