I was doing a simple 2 level caching experiment with Stored Procedures and am receiving a table or view does not exist Oracle error.
The cache is retrieving my DTO object and trying to make a SQL statement to the database. I’m guessing it is some configuration error.
Here’s the 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>
And here’s the code to test:
[TestMethod]
public void GetNomHeaderInfo_TestingCache_BPNomHeaderShouldBeCached()
{
//Arrange
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);
}
I then error out when I do the second query.UniqueResult(); The error message is:
SELECT blah blah_.blahblah, etc FROM MyDTO SomeAlias_ WHERE SomeAlias_.id=:p0
But there’s no myDTO table or view. I don’t know why NHibernate thinks to pull from the cache myDTO and then tries to create a SQL statement.
Here’s the trace:
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
Anyone know what I’m doing wrong here?
Thanks, Bill N
I can’t see your mapping, but here’s an explanation.
loader(see 17.4. Custom SQL for loading).Once you set up the loader and entity caching, you’ll just be able to retrieve your objects using just
session.Get<MyDTO>(id), which will use the second level cache, as long as you do all of your work inside transactions, which is a recommended practice.