NHibernate 二级缓存不返回对象



我正在使用存储过程进行简单的 2 级缓存实验,并且收到一个表或视图不存在 Oracle 错误。

缓存正在检索我的 DTO 对象并尝试对数据库进行 SQL 语句。 我猜这是一些配置错误。

这是应用程序.config

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory name="NHibernate.Test">
  <property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
  <property name="show_sql">true</property>
  <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
  <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
  <property name="cache.use_query_cache">true</property>
  <property name="cache.use_second_level_cache">true</property>
  <property name="cache.provider_class">NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache</property>
</session-factory>
</hibernate-configuration>

下面是要测试的代码: [测试方法] 公共无效 GetNomHeaderInfo_TestingCache_BPNomHeaderShouldBeCached(( { 安排 日期时间开始时间; 日期时间结束时间; 时间跨度第一次尝试; 时间跨度秒试;

    //Act
    using (var session = factory.OpenSession())
    {
        var query = session.GetNamedQuery("GetMyDTO");
        query.SetInt32("id", 1);
        query.SetCacheRegion("Id");
        query.SetCacheMode(CacheMode.Normal);
        query.SetCacheable(true);
        StartTime = DateTime.Now;
        myDTO DTO = query.UniqueResult<myDTO>();
        EndTime = DateTime.Now;
        FirstTry = EndTime - StartTime;
    }
    using (var session = factory.OpenSession())
    {
        var query = session.GetNamedQuery("GetMyDTO");
        query.SetInt32("id", 1);
        query.SetCacheRegion("Id");
        query.SetCacheMode(CacheMode.Normal);
        query.SetCacheable(true);
        StartTime = DateTime.Now;
        myDTO DTO = query.UniqueResult<myDTO>();
        EndTime = DateTime.Now;
        SecondTry = EndTime - StartTime;
    }
    //Test
    Assert.IsTrue(SecondTry < FirstTry);
}

然后,当我执行第二个查询时,我出错了。UniqueResult((; 错误消息是:

SELECT blah blah_.blahblah, etc FROM MyDTO SomeAlias_ WHERE SomeAlias_.id=:p0

但是没有 myDTO 表或视图。 我不知道为什么NHibernate认为从缓存myDTO中提取,然后尝试创建一个SQL语句。

以下是跟踪:

NHibernate.Cache.StandardQueryCache: DEBUG checking cached query results in region: 'Id'; sql: { call SomePackage.MyProc(?) }; parameters: []; named parameters: {'id'='1'}
NHibernate.Cache.StandardQueryCache: DEBUG checking cached query results in region: 'Id'; sql: { call SomePackage.MyProc(?) }; parameters: []; named parameters: {'id'='1'}
NHibernate.Caches.SysCache.SysCache: DEBUG Fetching object 'NHibernate-Cache:nomId:sql: { call SomePackage.MyProc(?) }; parameters: []; named parameters: {'id'='1'}@601355831' from the cache.
NHibernate.Caches.SysCache.SysCache: DEBUG Fetching object 'NHibernate-Cache:nomId:sql: { call SomePackage.MyProc(?) }; parameters: []; named parameters: {'id'='1'}@601355831' from the cache.
NHibernate.Cache.StandardQueryCache: DEBUG Checking query spaces for up-to-dateness [MyDTO]
NHibernate.Cache.StandardQueryCache: DEBUG Checking query spaces for up-to-dateness [MyDTO]
NHibernate.Caches.SysCache.SysCache: DEBUG Fetching object 'NHibernate-Cache:UpdateTimestampsCache:MyDTO@1270222867' from the cache.
NHibernate.Caches.SysCache.SysCache: DEBUG Fetching object 'NHibernate-Cache:UpdateTimestampsCache:MyDTO@1270222867' from the cache.
NHibernate.Cache.StandardQueryCache: DEBUG returning cached query results for: sql: { call SomePackage.MyProc(?) }; parameters: []; named parameters: {'id'='1'}
NHibernate.Cache.StandardQueryCache: DEBUG returning cached query results for: sql: { call SomePackage.MyProc(?) }; parameters: []; named parameters: {'id'='1'}
NHibernate.Event.Default.DefaultLoadEventListener: DEBUG loading entity: [MyAssembly.MyDTO#1]
NHibernate.Event.Default.DefaultLoadEventListener: DEBUG loading entity: [MyAssembly.MyDTO#1]
NHibernate.Event.Default.DefaultLoadEventListener: DEBUG attempting to resolve: [MyAssembly.MyDTO#1]
NHibernate.Event.Default.DefaultLoadEventListener: DEBUG attempting to resolve: [MyAssembly.MyDTO#1]
NHibernate.Event.Default.DefaultLoadEventListener: DEBUG object not resolved in any cache: [MyAssembly.MyDTO#1]
NHibernate.Event.Default.DefaultLoadEventListener: DEBUG object not resolved in any cache: [MyAssembly.MyDTO#1]
NHibernate.Persister.Entity.AbstractEntityPersister: DEBUG Fetching entity: [MyAssembly.MyDTO#1]
NHibernate.Persister.Entity.AbstractEntityPersister: DEBUG Fetching entity: [MyAssembly.MyDTO#1]
NHibernate.Loader.Loader: DEBUG loading entity: [MyAssembly.MyDTO#1]
NHibernate.Loader.Loader: DEBUG loading entity: [MyAssembly.MyDTO#1]
NHibernate.AdoNet.AbstractBatcher: DEBUG Opened new IDbCommand, open IDbCommands: 1
NHibernate.AdoNet.AbstractBatcher: DEBUG Opened new IDbCommand, open IDbCommands: 1
NHibernate.AdoNet.AbstractBatcher: DEBUG Building an IDbCommand object for the SqlString: SELECT blah blah_.blahblah, etc FROM MyDTO SomeAlias_ WHERE SomeAlias_.id=:p0

有人知道我在这里做错了什么吗?

谢谢,比尔·

我看不到您的映射,但这里有一个解释。

  • 您正在缓存查询结果,而不是您的实体(这些是单独的缓存(
  • 缓存查询
  • 的结果只存储 ID;如果您不也缓存实体,则会发出查询以加载每个返回的实体(这通常是错误的(
  • MyDTO 类的默认表名是 MyDTO,所以这就是它要查找的地方
  • 这看起来像是按 ID 查询,您不应该使用松散的命名查询,而应该使用正确的loader(请参阅 17.4。用于加载的自定义 SQL(。

设置加载程序和实体缓存后,只需使用 session.Get<MyDTO>(id) 即可检索对象,只要您在事务中完成所有工作,它就会使用二级缓存,这是推荐的做法。

对不起,迭戈,你想看看我的映射是什么样子的,这可能是正确的。 一旦我添加:

<cache usage="read-write"/> 

到 HBM.xml 文件一切正常。

最新更新