NHibernate二级缓存不返回对象 [英] NHibernate second level caching not returning object

查看:58
本文介绍了NHibernate二级缓存不返回对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was doing a simple 2 level caching experiment with Stored Procedures and am receiving a table or view does not exist Oracle error.

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

The cache is retrieving my DTO object and trying to make a SQL statement to the database. I'm guessing it is some configuration error.

这是app.config

Here's the app.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() { //安排 DateTime StartTime; DateTime EndTime; TimeSpan FirstTry; TimeSpan SecondTry;

And here's the code to test: [TestMethod] public void GetNomHeaderInfo_TestingCache_BPNomHeaderShouldBeCached() { //Arrange DateTime StartTime; DateTime EndTime; TimeSpan FirstTry; TimeSpan SecondTry;

    //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);
}

然后我执行第二个查询时出错.错误消息是:

I then error out when I do the second query.UniqueResult(); The error message is:

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

但是没有myDTO表或视图.我不知道为什么NHibernate会想从缓存myDTO中拉出然后尝试创建SQL语句.

But there's no myDTO table or view. I don't know why NHibernate thinks to pull from the cache myDTO and then tries to create a SQL statement.

这是痕迹:

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

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

Anyone know what I'm doing wrong here?

谢谢,比尔N

推荐答案

我看不到您的映射,但这是一个解释.

I can't see your mapping, but here's an explanation.

  • 您正在缓存查询结果,但不是您的实体(那些是单独的缓存)
  • 缓存查询结果只存储ID.如果您也没有缓存实体,则会发出查询以加载每个返回的实体(通常很糟糕)
  • MyDTO类的默认表名是MyDTO,因此就是它的外观
  • 这看起来像一个按ID查询,您不应该使用一个松散的命名查询,而是一个适当的loader(请参阅
  • You are caching your query results, but not your entity (those are separate caches)
  • Caching a query's results just stores the IDs; if you are not caching your entities too, a query is issued to load each returned entity (this is usually bad)
  • The default table name for the MyDTO class is MyDTO, so that's where it's looking
  • This looks like a Query by ID, for which you shouldn't be using a loose named query, but a proper loader (see 17.4. Custom SQL for loading).

一旦设置了加载程序和 entity 缓存,您就可以只使用session.Get<MyDTO>(id)检索对象,只要您执行所有操作,它将使用二级缓存.交易中的工作量,这是推荐做法.

Once you set up the loader and entity caching, you'll just be able to retrieve your objects using just session.Get<MyDTO>(id), which will use the second level cache, as long as you do all of your work inside transactions, which is a recommended practice.

这篇关于NHibernate二级缓存不返回对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆