Nhibernate 2nd level cache and Result transformer

Description

I have a big problem with 2nd level cache in NHibernate. Everything is working fine(Cache is running well) until I use

.SetResultTransformer(new DistinctRootEntityResultTransformer())

Example code:

using (var session = SessionFactory.OpenSession())
{
Console.WriteLine("---> using query first time");
var query = session
.CreateQuery("from Blog b where b.Author = :author")
.SetString("author", "Gabriel")
.SetCacheable(true)
.SetResultTransformer(new DistinctRootEntityResultTransformer())
;
var list = query.List<Blog>();
}

Exception:

NHibernate.PropertyAccessException: Exception occurred getter of Caching.Blog.Id
v NHibernate.Properties.BasicPropertyAccessor.BasicGetter.Get(Object target) v d:\CSharp\NH\NH\nhibernate\src\NHibernate\Properties\BasicPropertyAccessor.cs: line 211
v NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetIdentifier(Object entity) v d:\CSharp\NH\NH\nhibernate\src\NHibernate\Tuple\Entity\AbstractEntityTuplizer.cs: line 139
v NHibernate.Persister.Entity.AbstractEntityPersister.GetIdentifier(Object obj, EntityMode entityMode) v d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs: line 3883
v NHibernate.Persister.Entity.AbstractEntityPersister.IsTransient(Object entity, ISessionImplementor session) v d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs: line 3669
v NHibernate.Engine.ForeignKeys.IsTransient(String entityName, Object entity, Nullable`1 assumed, ISessionImplementor session) v ForeignKeys.cs: line 194
v NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(String entityName, Object entity, ISessionImplementor session) v ForeignKeys.cs: line 250
v NHibernate.Type.ManyToOneType.Disassemble(Object value, ISessionImplementor session, Object owner) v ManyToOneType.cs: line 137
v NHibernate.Cache.StandardQueryCache.Put(QueryKey key, ICacheAssembler[] returnTypes, IList result, Boolean isNaturalKeyLookup, ISessionImplementor session) v StandardQueryCache.cs: line 82
v NHibernate.Loader.Loader.PutResultInQueryCache(ISessionImplementor session, QueryParameters queryParameters, IType[] resultTypes, IQueryCache queryCache, QueryKey key, IList result) v Loader.cs: line 1668
v NHibernate.Loader.Loader.ListUsingQueryCache(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) v Loader.cs: line 1617
v NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) v Loader.cs: line 1591
v NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters) v QueryLoader.cs: line 300
v NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters) v QueryTranslatorImpl.cs: line 111
v NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results) v HQLQueryPlan.cs: line 105
v NHibernate.Impl.SessionImpl.List(String query, QueryParameters queryParameters, IList results) v SessionImpl.cs: line 616
v NHibernate.Impl.SessionImpl.List<T>(String query, QueryParameters parameters) v SessionImpl.cs: line 592
v NHibernate.Impl.QueryImpl.List<T>() v QueryImpl.cs: line 94
v UnitTests.when_having_blog_with_posts.trying_to_cache_a_complex_query() v Blog_Spec.cs: line 110

Mapping:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="Caching"
assembly="Caching">
<class name="Blog">
<cache usage="read-write"/>
<id name="Id">
<generator class="hilo"/>
</id>
<property name="Author"/>
<property name="Name"/>
<set name="Posts" cascade="all" lazy="true">
<cache usage="read-write"/>
<key column="BlogId"/>
<one-to-many class="Post"/>
</set>
</class>

<class name="Post">
<cache usage="read-write"/>
<id name="Id">
<generator class="hilo"/>
</id>
<property name="Title"/>
<property name="Body"/>
</class>

</hibernate-mapping>

Classes:

public class Blog
{
public virtual int Id { get; set; }
public virtual string Author { get; set; }
public virtual string Name { get; set; }
public virtual ISet<Post> Posts { get; set; }

public Blog()
{
Posts = new HashedSet<Post>();
}
}

public class Post
{
public virtual int Id { get; private set; }
public virtual string Title { get; set; }
public virtual string Body { get; set; }
}

nhibernate.config:

<property name="cache.provider_class">NHibernate.Cache.HashtableCacheProvider</property>
<property name="cache.use_second_level_cache">true</property>
<property name="cache.use_query_cache" >true</property>

In summary: Cache and nhibernate running well until i use result transformer. To work i must disable transformer or 2nd level cache. It is not working together

This is only example, i know that distinct in this situation is stupid.

Environment

None

Attachments

1

Activity

Show:

Alberto B 
November 1, 2012 at 12:31 PM

If you use eager loading or joins you still have the same problem.
I've opened an issue https://nhibernate.jira.com/browse/NH-3311

Fabio Maulo 
July 30, 2011 at 2:10 PM

Closed after final release of NH3.2.0GA

Fabio Maulo 
April 30, 2011 at 7:21 AM

Josef Holan 
April 26, 2011 at 10:59 AM

Hi, this is key function of nhibernate in my application in company. Is there a workaround or possibility to quick repair? I need 2nd level cache and result transformer working together. Thanks. Josef

Fixed

Details

Assignee

Reporter

Components

Fix versions

Affects versions

Priority

Who's Looking?

Open Who's Looking?
Created April 25, 2011 at 11:04 AM
Updated December 29, 2012 at 11:00 AM
Resolved May 2, 2011 at 7:09 AM
Who's Looking?