Well, I don't know what the code of
IPersistenceService.Find does, but the following works here:
session.Query<Foo>().Cacheable().Fetch(f => f.Bar).ToList();
And I don't get the idea behind "from po in ParentObjects select po"; that's
a noop.
Diego
On Thu, Aug 19, 2010 at 11:08, Segura, Eduardo [Tech] <[email protected]
> wrote:
> 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]<nhusers%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/nhusers?hl=en.
>
--
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.