我基本上只是想重现 Ayende 的一级和二级缓存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] NHibernate 设置缓存模式.Impl。 to: Normal NHibernate.Loader.Custom.Sql.SQLCustomQuery: DEBUG 开始处理 sql 查询 [{ call MyPackage.get_header(:id) }] NHibernate.Loader.Custom.Sql.SQLQueryReturnProcessor: DEBUG mapping alias [nh] to entity-后缀 [0_] NHibernate.Cache.StandardQueryCache:INFO 在区域开始查询缓存:Id2888469 NHibernate.Cache.StandardQueryCache:调试在区域检查缓存的查询结果:'Id2888469'; sql: { 调用 MyPackage.get_header(?) }; 参数: []; 命名参数:{'id'='2888469'} NHibernate.Cache.StandardQueryCache:缓存中未找到DEBUG查询结果: sql: { call MyPackage.get_header(?) }; 参数: []; 命名参数:{'id'='2888469'} NHibernate.AdoNet.AbstractBatcher:调试打开新的 IDbCommand,打开 IDbCommands:1 NHibernate.AdoNet.AbstractBatcher:调试为 SqlString 构建 IDbCommand 对象:{ call MyPackage.get_header(?) } NHibernate.Type.Int32Type:调试绑定“2888469”到参数:0 NHibernate.Loader.Loader:INFO { call MyPackage.get_header(:p0) } NHibernate.SQL: DEBUG { call MyPackage.get_header(:p0) };: p0 = 2888469 [Type: Int32 (0)] blah blah NHibernate.AdoNet.ConnectionManager: DEBUG 积极释放数据库连接 NHibernate.Connection.ConnectionProvider: DEBUG 关闭连接 NHibernate.Loader.Loader: DEBUG 水合对象总数: 1 NHibernate.Engine.TwoPhaseLoad : NHibernate.Engine.TwoPhaseLoad:调试将实体添加到二级缓存:[MyAssembly.HeaderDTO#2888469] NHibernate.Cache.ReadWriteCache:调试缓存:MyAssembly.HeaderDTO#2888469 NHibernate.Cache.ReadWriteCache:调试缓存:MyAssembly.HeaderDTO#2888469 NHibernate.Engine.TwoPhaseLoad:调试完成实体化 [MyAssembly.HeaderDTO#2888469] NHibernate.Engine.StatefulPersistenceContext:调试初始化非延迟集合 NHibernate.Cache.StandardQueryCache:调试缓存查询结果在区域:'Id2888469'; sql: { 调用 MyPackage.get_header(?) }; 参数: []; 命名参数:{'id'='2888469'} NHibernate.AdoNet.ConnectionManager:自动提交后的调试 NHibernate.Impl.SessionImpl:调试事务完成 NHibernate.AdoNet.ConnectionManager:调试积极释放数据库连接 NHibernate.Impl.SessionImpl:调试设置缓存模式为:正常 NHibernate.Impl.SessionImpl:调试 [session-id=e9de687f-1ef5-4824-9964-9b94f636a15d] 运行 ISession.Dispose() NHibernate.Impl.SessionImpl:调试 [session-id=e9de687f-1ef5-4824-9964-9b94f636a15d] 执行真正的 Dispose(True) NHibernate.Impl.SessionImpl:调试关闭会话 NHibernate.AdoNet.AbstractBatcher:调试运行 BatcherImpl.Dispose(true) NHibernate.Impl.SessionImpl :DEBUG [session-id=78820256-77e8-4596-8374-98f8b5cc946b] 在时间戳打开会话:5517356016148480,对于会话工厂:[NHibernate.Test/ca36467732ff486380672aeb062ef749] NHibernate.Loader.Custom.sql.SQLCustomQuery 开始处理:查询 [{ call MyPackage.get_header(:id) }] NHibernate.Loader.Custom.Sql.SQLQueryReturnProcessor: DEBUG 映射别名 [nh] 到实体后缀 [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:调试打开新 IDbCommand,打开 IDbCommands:1 NHibernate.AdoNet.AbstractBatcher:调试为 SqlString 构建 IDbCommand 对象:{ call MyPackage.get_header(?)} NHibernate.Type.Int32Type:调试绑定'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:调试从驱动程序 NHibernate.AdoNet.AbstractBatcher 获取 IDbConnection:调试 ExecuteReader 花了 2 毫秒 NHibernate.AdoNet.AbstractBatcher:调试打开 IDataReader,打开 IDataReaders:等等 NHibernate.Loader.Loader:调试完成处理结果集(1 行) NHibernate.AdoNet.AbstractBatcher:调试关闭 IDataReader,打开 IDataReaders:0 NHibernate.AdoNet。AbstractBatcher:调试数据读取器在 27 毫秒后关闭。二级缓存:[MyAssembly.HeaderDTO#2888469] NHibernate.Cache.ReadWriteCache:调试缓存:MyAssembly.HeaderDTO#2888469 NHibernate.Cache.ReadWriteCache:调试项已缓存: MyAssembly.HeaderDTO#2888469 NHibernate.Engine.TwoPhaseLoad:调试完成实体化实体 [MyAssembly.HeaderDTO#2888469] NHibernate。 Engine.StatefulPersistenceContext: DEBUG 初始化非惰性集合 NHibernate.Cache.StandardQueryCache: DEBUG 缓存查询结果在 region: 'NHibernate.Cache.StandardQueryCache'; sql: { 调用 MyPackage.get_header(?) }; 参数: []; 命名参数:{'id'='2888469'} NHibernate.AdoNet.ConnectionManager:自动提交后调试等等等等
NHibernate 怎么能说它被缓存了?找不到它然后NHibernate不会缓存它,因为它已经被缓存了?
也许这与 HashTable 提供者有关?任何帮助,将不胜感激。
谢谢,比尔 N