私は基本的に、Ayende の第 1 および第 2 レベルのキャッシングhttp://nhibernate.hibernatingrhinos.com/28/first-and-second-level-caching-in-nhibernateを再現しようとしています。
構成を次のように配線しました。
<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>
そして今、私はいくつかのテストを行おうとしています (テストがキャッシングをテストするのにあまり適していないという事実を無視してください)。
[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 [session-id=e9de687f-1ef5-4824-9964-9b94f636a15d] がタイムスタンプでセッションを開きました: 5517356014678016、セッション ファクトリの場合: [NHibernate.Test/ca36467732ff486380672aeb062ef749] to: 通常の NHibernate.Loader.Custom.Sql.SQLCustomQuery: SQL クエリの処理を開始する DEBUG [{ call MyPackage.get_header(:id) }] NHibernate.Loader.Custom.Sql.SQLQueryReturnProcessor: DEBUG マッピング エイリアス [nh] to entity-サフィックス [0_] NHibernate.Cache.StandardQueryCache: INFO がリージョンでクエリ キャッシュを開始しています: Id2888469 sql: { 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 } NHibernate.Type.Int32Type: パラメータに '2888469' をバインドするデバッグ: 0 p0 = 2888469 [Type: Int32 (0)] 何とか何とか NHibernate.AdoNet.ConnectionManager: DEBUG データベース接続を積極的に解放します NHibernate.Connection.ConnectionProvider: DEBUG 接続を閉じます: NHibernate.Engine.TwoPhaseLoad: 第 2 レベルのキャッシュにエンティティを追加するデバッグ: [MyAssembly.HeaderDTO#2888469] NHibernate.Cache.ReadWriteCache: DEBUG キャッシュ: MyAssembly.HeaderDTO#2888469 NHibernate.Engine.TwoPhaseLoad: 実体化エンティティのデバッグが完了しました [MyAssembly.HeaderDTO#2888469] NHibernate.Engine.StatefulPersistenceContext: 非遅延コレクションの初期化をデバッグします sql: { MyPackage.get_header(?) を呼び出す }; パラメーター: []; 名前付きパラメーター: {'id'='2888469'} NHibernate.AdoNet.ConnectionManager: 自動コミット後の DEBUG 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: BatcherImpl.Dispose(true) を実行中の DEBUG : DEBUG [session-id=78820256-77e8-4596-8374-98f8b5cc946b] は、タイムスタンプでセッションを開きました: 5517356016148480、セッション ファクトリの場合: [NHibernate.Test/ca36467732ff486380672aeb062ef749] NHibernate.Loader.Custom.Sql.SQLCustom の NHibernate.Loader.Custom.Sql.SQLCustom 処理の開始query [{ call MyPackage.get_header(:id) }] NHibernate.Loader.Custom.Sql.SQLQueryReturnProcessor: DEBUG マッピング エイリアス [nh] to entity-suffix [0_] NHibernate.Cache.StandardQueryCache: DEBUG キャッシュされたクエリ結果を領域でチェック: 'NHibernate.Cache.StandardQueryCache'; sql: { MyPackage.get_header(?) を呼び出す }; パラメーター: []; 名前付きパラメーター: {'id' 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' to パラメータ: 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 ミリ秒かかりました) NHibernate.AdoNet.AbstractBatcher: DEBUG IDataReader を閉じ、IDataReaders を開きます:0 NHibernate.AdoNet.AbstractBatcher: DEBUG DataReader は 27 ミリ秒後に閉じられました何とか NHibernate.Loader.Loader: DEBUG 水和されたオブジェクトの合計: 1 NHibernate.Engine.TwoPhaseLoad: [MyAssembly.HeaderDTO#2888469] の関連付けを解決する DEBUG NHibernate.Engine.TwoPhaseLoad: DEBUG にエンティティを追加する二次キャッシュ: [MyAssembly.HeaderDTO#2888469] NHibernate.Cache.ReadWriteCache: DEBUG キャッシュ: MyAssembly.HeaderDTO#2888469 NHibernate.Cache.ReadWriteCache: DEBUG アイテムは既にキャッシュされていました: MyAssembly.HeaderDTO#2888469 Engine.StatefulPersistenceContext: 非遅延コレクションを初期化する DEBUG sql: { MyPackage.get_header(?) を呼び出す }; パラメーター: []; 名前付きパラメータ: {'id'='2888469'} NHibernate.AdoNet.ConnectionManager: 自動コミット後のデバッグ
NHibernate はキャッシュされたとどのように判断できますか? それを見つけることができず、すでにキャッシュされているため、NHibernate はそれをキャッシュしませんか?
多分それは HashTable プロバイダーと関係がありますか? どんな助けでも大歓迎です。
ありがとう、ビルN