-1

我基本上只是想重现 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

4

1 回答 1

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();
}
于 2012-09-12T14:48:29.973 回答