2012-09-05 42 views
0

我正在做一個簡單的2級緩存實驗與存儲過程,並收到一個表或視圖不存在Oracle錯誤。NHibernate第二級緩存不返回對象

緩存正在檢索我的DTO對象並嘗試向數據庫建立SQL語句。我猜這是一些配置錯誤。

這裏是在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> 

而這裏的代碼進行測試: [TestMethod的] 公共無效GetNomHeaderInfo_TestingCache_BPNomHeaderShouldBeCached(){ // 安排 DateTime的開始時間; 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); 
} 

我然後錯誤了,當我做第二個query.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:[email protected]' from the cache. 
NHibernate.Caches.SysCache.SysCache: DEBUG Fetching object 'NHibernate-Cache:UpdateTimestampsCache:[email protected]' 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 

任何人都知道我在做什麼錯在這裏?

謝謝,比爾N

回答

2

我看不到你的映射,但這裏有一個解釋。

  • 您正在緩存查詢結果,但不是你的實體(這些都是獨立的高速緩存)
  • 緩存查詢的結果只是存儲的ID;如果你不緩存你的實體也查詢發出加載每個返回的實體(這通常是壞)
  • 爲MyDTO類的默認表名是MyDTO,因此,這就是它看起來
  • 這看起來像一個按ID查詢,您不應該使用寬鬆的命名查詢,而應使用適當的loader(請參閱17.4. Custom SQL for loading)。

一旦設置了裝載機和實體緩存,你只能夠檢索只用session.Get<MyDTO>(id)你的對象,其中會使用到二級緩存,只要你做的所有工作中交易,這是一個推薦的做法。

+0

感謝迭戈你的迴應。 –

+0

感謝Diego的回覆。理想情況下,我喜歡緩存MyDTO實體(並查詢我擁有列表的位置)。我已經簡化了場景,但是存儲過程通常是100到500行,所以我不認爲加載自定義SQL會有幫助。你知道如何緩存實體(MyDTO)的文檔或樣本在哪裏? –

+0

@BillNielsen你不明白我的答案。您必須將您的存儲過程調用作爲用於加載的自定義sql。 –

0

對不起迭戈,你可能是想看看我的映射是什麼樣子。一旦我加入:

<cache usage="read-write"/> 

到hbm.xml文件一切正常。