Hi folks, Could I get your feedback on this one? Am I missing something?
Thanks, From: Segura, Eduardo [Tech] Sent: Tuesday, August 17, 2010 1:29 PM To: '[email protected]' Subject: .Cacheable().Fetch() throws 'Exception occurred getter of xxx' I'm wondering if this is the right way to use second-level caching along with eagerly loading a collection. This code is equivalent to a query that we are issuing from a fairly large application. I've stripped it down to the very minimum while still throwing the exception. (My apologies for the rather large email, but I want to provide as much information up-front as possible) I have this test set up: [TestMethod] public void FindWithFetchAndCacheableTest() { IPersistenceService ps = PersistenceServiceFactory.CreateService(PersistenceServiceType.Hibernate); IList<ParentObject> pos = ps.Find<ParentObject, IQueryable<ParentObject>>(ParentObjects => from po in ParentObjects select po) .Cacheable() .Fetch(po => po.ChildObjects).ToList(); Assert.IsTrue(pos.Count > 0); } My uneducated guess: -------------------------------------- The lambda expression in Fetch() is being used as a 'resultTransfomer' here: (NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.cs:line 335, using NH3.0.0Alpha1) protected override object GetResultColumnOrRow(object[] row, IResultTransformer resultTransformer, IDataReader rs, ISessionImplementor session) { row = ToResultRow(row); <-- after this assignment, row is an Array[1] holding my object bool hasTransform = HasSelectNew || resultTransformer != null; <-- at this point, resultTransformer has a lambda ... else if (!hasTransform) { return row.Length == 1 ? row[0] : row; <-- the object is not extracted from the array, because of the lambda } } And this method ends up returning an array (object[1] = [{ ParentObject}]), instead of returning the object itself. Then later on, since the 'object[1]' array doesn't have an 'Id' property, this line throws the exception: (NHibernate.Properties.BasicPropertyAccessor.cs:Line 207 (BasicGetter.Get)): public object Get(object target) { try { return property.GetValue(target, new object[0]); <-- target is not {ParentObject}, but an object[1] instead } catch (Exception e) { throw new PropertyAccessException(e, "Exception occurred", false, clazz, propertyName); } } My classes: ------------------------------------------------------ public class ParentObject { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual ISet<ChildObject> ChildObjects { get; set; } public virtual void AddChildObject(ChildObject co) { this.ChildObjects.Add(co); co.Parent = this; } } public class ChildObject { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual ParentObject Parent { get; set; } } Mappings: ---------------------------------------- <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true"> <class name="PersistenceLayer.Test.Model.ParentObject, PersistenceLayer.Test"> <cache usage="read-write"/> <id name="Id"> <generator class="native"/> </id> <property name="Name"/> <set name="ChildObjects" inverse="true" cascade="all-delete-orphan"> <cache usage="read-write"/> <key column="ParentId"/> <one-to-many class="PersistenceLayer.Test.Model.ChildObject"/> </set> </class> </hibernate-mapping> <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true"> <class name="PersistenceLayer.Test.Model.ChildObject, PersistenceLayer.Test"> <cache usage="read-write"/> <id name="Id"> <generator class="native"/> </id> <property name="Name"/> <many-to-one name="Parent" column="ParentId" not-null="true"/> </class> </hibernate-mapping> But it throws this exception: Test method PersistenceLayer.Test.PersistenceServiceTest.FindWithFetchAndCacheableTest threw exception: NHibernate.PropertyAccessException: Exception occurred getter of PersistenceLayer.Test.Model.ParentObject.Id ---> System.Reflection.TargetException: Object does not match target type.. System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target) System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index) NHibernate.Properties.BasicPropertyAccessor.BasicGetter.Get(Object target) in d:\CSharp\NH\nhibernate\src\NHibernate\Properties\BasicPropertyAccessor.cs: line 207 NHibernate.Properties.BasicPropertyAccessor.BasicGetter.Get(Object target) in d:\CSharp\NH\nhibernate\src\NHibernate\Properties\BasicPropertyAccessor.cs: line 211 NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetIdentifier(Object entity) in d:\CSharp\NH\nhibernate\src\NHibernate\Tuple\Entity\AbstractEntityTuplizer.cs: line 139 NHibernate.Persister.Entity.AbstractEntityPersister.GetIdentifier(Object obj, EntityMode entityMode) in d:\CSharp\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs: line 3838 NHibernate.Persister.Entity.AbstractEntityPersister.IsTransient(Object entity, ISessionImplementor session) in d:\CSharp\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs: line 3629 NHibernate.Engine.ForeignKeys.IsTransient(String entityName, Object entity, Nullable`1 assumed, ISessionImplementor session) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ForeignKeys.cs: line 193 NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(String entityName, Object entity, ISessionImplementor session) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ForeignKeys.cs: line 249 NHibernate.Type.ManyToOneType.Disassemble(Object value, ISessionImplementor session, Object owner) in d:\CSharp\NH\nhibernate\src\NHibernate\Type\ManyToOneType.cs: line 137 NHibernate.Cache.StandardQueryCache.Put(QueryKey key, ICacheAssembler[] returnTypes, IList result, Boolean isNaturalKeyLookup, ISessionImplementor session) in d:\CSharp\NH\nhibernate\src\NHibernate\Cache\StandardQueryCache.cs: line 82 NHibernate.Loader.Loader.PutResultInQueryCache(ISessionImplementor session, QueryParameters queryParameters, IType[] resultTypes, IQueryCache queryCache, QueryKey key, IList result) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Loader.cs: line 1627 NHibernate.Loader.Loader.ListUsingQueryCache(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Loader.cs: line 1593 NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Loader.cs: line 1567 NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters) in d:\CSharp\NH\nhibernate\src\NHibernate\Hql\Ast\ANTLR\Loader\QueryLoader.cs: line 298 NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters) in d:\CSharp\NH\nhibernate\src\NHibernate\Hql\Ast\ANTLR\QueryTranslatorImpl.cs: line 110 NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\Query\HQLQueryPlan.cs: line 105 NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results) in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs: line 679 NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters) in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs: line 655 NHibernate.Impl.ExpressionQueryImpl.List() in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\ExpressionQueryImpl.cs: line 63 NHibernate.Linq.NhQueryProvider.Execute(Expression expression) in d:\CSharp\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs: line 31 NHibernate.Linq.NhQueryProvider.Execute[TResult](Expression expression) in d:\CSharp\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs: line 55 GetEnumerator() ctor(IEnumerable`1 collection) System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) PersistenceLayer.Test.PersistenceServiceTest.FindWithFetchAndCacheableTest() in .....\PersistenceServiceTest.cs: line 345 Thanks, Eduardo -- You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
