0

ストアド プロシージャを使用して単純な 2 レベルのキャッシュ実験を行っていたところ、テーブルまたはビューが存在しないという Oracle エラーが発生しました。

キャッシュが 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] public void GetNomHeaderInfo_TestingCache_BPNomHeaderShouldBeCached() { //DateTime StartTime; 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);
}

次に、2 番目の 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:MyDTO@1270222867' from the cache.
NHibernate.Caches.SysCache.SysCache: DEBUG Fetching object 'NHibernate-Cache:UpdateTimestampsCache:MyDTO@1270222867' 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

4

2 に答える 2

2

マッピングがわかりませんが、説明があります。

  • クエリ結果をキャッシュしていますが、エンティティはキャッシュしていません(これらは個別のキャッシュです)
  • クエリの結果をキャッシュすると、IDが保存されるだけです。エンティティもキャッシュしていない場合は、返された各エンティティをロードするためのクエリが発行されます(これは通常は悪いことです)
  • MyDTOクラスのデフォルトのテーブル名はMyDTOであるため、ここで検索します
  • これはIDによるクエリのように見えます。このため、緩い名前のクエリを使用するべきではありませんが、適切ですloader17.4。ロード用のカスタムSQLを参照)。

ローダーとエンティティsession.Get<MyDTO>(id)のキ​​ャッシュを設定すると、トランザクション内ですべての作業を行う限り、2番目のレベルのキャッシュを使用するだけでオブジェクトを取得できるようになります。これは推奨される方法です。

于 2012-09-05T02:53:23.997 に答える
0

申し訳ありませんディエゴ、私のマッピングがどのように見えるかを見たいというあなたはおそらく正しかったでしょう。追加したら:

<cache usage="read-write"/> 

hbm.xml ファイルにすべてが機能します。

于 2012-09-05T13:09:25.730 に答える