2012-09-07 44 views
-1

我基本上只是試圖重現Ayende的第一級和第二級緩存http://nhibernate.hibernatingrhinos.com/28/first-and-second-level-caching-in-nhibernateNHibernate二級緩存不能與HashTableCacheProvider配合使用

我已經連接好配置爲:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> 
    <session-factory name="NHibernate.Test"> 
    <property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property> 
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property> 
    <property name="show_sql">true</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.Cache.HashtableCacheProvider</property> 
    <property name="cache.default_expiration">1801</property> 
</session-factory> 

,我已經映射實體爲:

<class name="HeaderDTO" mutable="false" check="none"> 
<cache usage="read-write"/> 
    <id name="Id" type="System.Int32" > 
    <column name="id" sql-type="NUMBER" not-null="true" unique="true"/> 
    <generator class="assigned"/> 
    </id> 
    <property name="Description" column="description" type="System.String" /> 
</class> 

和我命名查詢看起來是這樣的:

<sql-query name="GetHeaderDTO"> 
    <query-param name="id" type="int"/> 
    <return class="HeaderDTO" /> 
    { call MyPackage.get_header(:id) } 
</sql-query> 

現在我' m試圖做一些測試(忽略測試不是一個很好的測試緩存的事實)。

[TestMethod] 
public void Cacching_Entity_FirstCallIsCached() 
{ 
DateTime StartTime; 
DateTime EndTime; 
TimeSpan FirstTry; 
TimeSpan SecondTry; 
int Id = 2888469; 
string key = string.Concat("Id", Id); 

using (var session = factory.OpenSession()) 
{ 
    //Act 
    var query = session.GetNamedQuery("GetHeaderDTO"); 
    query.SetInt32("in_nom_id", Id); 
    query.SetCacheable(true); 
    query.SetCacheMode(CacheMode.Normal); 
    query.SetCacheRegion(key); 
    StartTime = DateTime.Now; 
    HeaderDTO MyHeader = query.UniqueResult<HeaderDTO>(); 
    EndTime = DateTime.Now; 
    FirstTry = EndTime - StartTime; 
} 

using (var session = factory.OpenSession()) 
{ 
    //Act 
    var query = session.GetNamedQuery("GetHeaderDTO"); 
    query.SetInt32("in_nom_id", Id); 
    query.SetCacheable(true); 
    StartTime = DateTime.Now; 
    HeaderDTO MyHeader = query.UniqueResult<HeaderDTO>(); 
    EndTime = DateTime.Now; 
    SecondTry = EndTime - StartTime; 
} 

Assert.IsTrue(FirstTry>SecondTry); 
} 

但是當我運行測試,並期待在NHibernate的日誌:

NHibernate.Impl.SessionImpl:DEBUG [會話id = e9de687f-1ef5-4824-9964-9b94f636a15d]打開的會話的時間戳:5517356014678016,用於會話工廠:[NHibernate.Test/ca36467732ff486380672aeb062ef749] NHibernate.Impl.SessionImpl:DEBUG設置緩存模式爲:正常 NHibernate.Loader.Custom.Sql.SQLCustomQuery:DEBUG開始處理sql查詢[{call MyPackage。 get_header(:id)}] NHibernate.Loader.Custom.Sql.SQLQueryReturnProcessor:DEBUG映射別名[nh]到實體後綴[0_] NHibernate.Cache.StandardQueryCache:INFO在地區啓動查詢緩存:Id2888469 NHibernate.Cache.StandardQueryCache:DEBUG檢查區域中的緩存查詢結果:'Id2888469'; sql:{call MyPackage.get_header(?)};參數:[];命名參數:{'id'='2888469'} NHibernate.Cache.StandardQueryCache:在緩存中找不到DEBUG查詢結果:sql:{call MyPackage.get_header(?)};參數:[];命名參數:{'id'='2888469'} NHibernate.AdoNet.AbstractBatcher:DEBUG打開新的IDbCommand,打開IDbCommands:1 NHibernate.AdoNet.AbstractBatcher:DEBUG爲SqlString構建一個IDbCommand對象{call MyPackage.get_header ?)} NHibernate.Type.Int32Type:DEBUG綁定'2888469'參數:0 NHibernate.Loader.Loader:INFO {call MyPackage.get_header(:p0)} NHibernate.SQL:DEBUG {call MyPackage.get_header(: P0)} ;: P0 = 2888469 [類型:的Int32(0)] 等等 嗒嗒 NHibernate.AdoNet.ConnectionManager:DEBUG積極釋放數據庫連接 NHibernate.Connection.ConnectionProvider:DEBUG截止連接 NHibernate.Loader.Loader:DEBUG總物體水合物d:1 NHibernate.Engine.TwoPhaseLoad:對於[MyAssembly.HeaderDTO#2888469] NHibernate.Engine.TwoPhaseLoad DEBUG解決協會:DEBUG添加實體到第二級高速緩存:[MyAssembly.HeaderDTO#2888469] NHibernate.Cache。 ReadWriteCache:DEBUG緩存:MyAssembly.HeaderDTO#2888469 NHibernate.Cache.ReadWriteCache:DEBUG緩存:MyAssembly.HeaderDTO#2888469 NHibernate.Engine.TwoPhaseLoad:DEBUG進行物化實體[MyAssembly.HeaderDTO#2888469] NHibernate.Engine.StatefulPersistenceContext :DEBUG初始化非懶惰集合 NHibernate.Cache.StandardQueryCache:DEBUG在區域中緩存查詢結果:'Id2888469'; sql:{call MyPackage.get_header(?)};參數:[];命名參數:{'id'='2888469'} NHibernate.AdoNet.ConnectionManager:自動提交後調試 NHibernate.Impl。SessionImpl:DEBUG事務完成 NHibernate.AdoNet.ConnectionManager:DEBUG積極釋放數據庫連接 NHibernate.Impl.SessionImpl:DEBUG設置緩存模式爲:正常 NHibernate.Impl.SessionImpl:DEBUG [session-id = e9de687f-1ef5-4824- 9964-9b94f636a15d]運行ISession.Dispose() NHibernate.Impl.SessionImpl:DEBUG [session-id = e9de687f-1ef5-4824-9964-9b94f636a15d]執行真正Dispose(True) NHibernate.Impl.SessionImpl:DEBUG關閉會話 NHibernate.AdoNet.AbstractBatcher:DEBUG運行BatcherImpl.Dispose(true) NHibernate.Impl.SessionImpl:DEBUG [session-id = 78820256-77e8-4596-8374-98f8b5cc946b]打開會話時間戳:5517356016148480,對於會話工廠:[NHibernate .Test/ca36467732ff486380672aeb062ef749] NHibernate.Loader.Custom.Sql.SQLCustomQuery:DEBUG開始處理SQL查詢[{call MyPackage.get_header(:id)}] NHibernate.Loader.Custom.Sql.SQLQueryReturnProcessor:將DEBUG映射別名[nh]映射到entity-suffix [0_] NHibernate.Cache.StandardQueryCache:DEBUG檢查區域中的緩存查詢結果:'NHibernate.Cache.StandardQueryCache'; sql:{call MyPackage.get_header(?)};參數:[];命名參數:{'id'='2888469'} NHibernate.Cache.StandardQueryCache:在緩存中找不到DEBUG查詢結果:sql:{call MyPackage.get_header(?)};參數:[];命名參數:{'id'='2888469'} NHibernate.AdoNet.AbstractBatcher:DEBUG打開新的IDbCommand,打開IDbCommands:1 NHibernate.AdoNet.AbstractBatcher:DEBUG爲SqlString建立一個IDbCommand對象:{call MyPackage.get_header (?)} NHibernate.Type.Int32Type:DEBUG綁定'2888469'到參數:0 NHibernate.Loader.Loader:INFO {call MyPackage.get_header(:p0)} NHibernate.SQL:DEBUG {call MyPackage.get_header :p0)};:p0 = 2888469 [Type:Int32(0)] NHibernate.Connection.DriverConnectionProvider:DEBUG從驅動程序獲取IDbConnection NHibernate.AdoNet.AbstractBatcher:DEBUG ExecuteReader花了2 ms NHibernate.AdoNet.AbstractBatcher:DEBUG Opened IDataReader,打開IDataReaders: 等等 嗒嗒 NHibernate.Loader.Loader:調試完成處理的結果集(1行) NHibernate.AdoNet.AbstractBatcher:DEBUG封閉的IDataReader,開放IDataReaders:0 NHibernate.AdoNet.AbstractBatcher:DEBUG的DataReader物後27毫秒 關閉等等 嗒嗒 NHibernate.Loader.Loader:DEBUG總對象的水合:1 NHibernate.Engine.TwoPhaseLoad:DEBUG拆分爲[MyAssembly.HeaderDTO#2888469] NHibernate.Engine.TwoPhaseLoad協會:DEBUG添加實體到第二級高速緩存: [MyAssembly.HeaderDTO#2888469] NHibernate.Cache.ReadWriteCache:DEBUG緩存:MyAssembly.HeaderDTO#2888469 NHibernate.Cache.Re adWriteCache:DEBUG項目已經緩存: MyAssembly.HeaderDTO#2888469 NHibernate.Engine.TwoPhaseLoad:DEBUG進行物化實體[MyAssembly.HeaderDTO#2888469] NHibernate.Engine.StatefulPersistenceContext:DEBUG初始化非延遲的集合 NHibernate.Cache。 StandardQueryCache:DEBUG在區域中緩存查詢結果:'NHibernate.Cache.StandardQueryCache'; sql:{call MyPackage.get_header(?)};參數:[];命名參數:{ '身份證'= '2888469'} NHibernate.AdoNet.ConnectionManager:DEBUG自動提交 等等之後 等等

怎樣才能NHibernate的說這是緩存?無法找到它,然後NHibernate不會緩存它,因爲它已被緩存?

也許這與HashTable提供程序有關?任何幫助,將不勝感激。

謝謝你,比爾ñ

+0

不知道在所有的,但也許它與事實,你也必須標記你的查詢作爲做超高速緩存 –

+0

我以爲我是當我設置緩存=真(query.SetCacheable(真);) –

+0

我想你可能還需要將其指定爲可緩存在你的XML映射 –

回答

0

你應該把你的代碼在一個事務中:

using (var session = factory.OpenSession()) 
using (var tx = session.BeginTransaction()) 
{ 
    //Act 
    var query = session.GetNamedQuery("GetHeaderDTO"); 
    query.SetInt32("in_nom_id", Id); 
    query.SetCacheable(true); 
    query.SetCacheMode(CacheMode.Normal); 
    query.SetCacheRegion(key); 
    StartTime = DateTime.Now; 
    HeaderDTO MyHeader = query.UniqueResult<HeaderDTO>(); 
    EndTime = DateTime.Now; 
    FirstTry = EndTime - StartTime; 

    tx.Commit(); 
} 

using (var session = factory.OpenSession()) 
using (var tx = session.BeginTransaction()) 
{ 
    //Act 
    var query = session.GetNamedQuery("GetHeaderDTO"); 
    query.SetInt32("in_nom_id", Id); 
    query.SetCacheable(true); 
    StartTime = DateTime.Now; 
    HeaderDTO MyHeader = query.UniqueResult<HeaderDTO>(); 
    EndTime = DateTime.Now; 
    SecondTry = EndTime - StartTime; 

    tx.Commit(); 
}