From: Fabio M. (JIRA) <nh...@gm...> - 2011-05-02 14:10:08
|
[ http://216.121.112.228/browse/NH-1344?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Fabio Maulo resolved NH-1344. ----------------------------- Resolution: Fixed Fix Version/s: 3.2.0Alpha3 > QueryTranslator: Invalid Cast to object array when using IResultTransformer > --------------------------------------------------------------------------- > > Key: NH-1344 > URL: http://216.121.112.228/browse/NH-1344 > Project: NHibernate > Issue Type: Sub-task > Components: Core > Affects Versions: 1.2.1, 2.0.0.Alpha2 > Reporter: Stefan Simroth > Priority: Minor > Fix For: 3.2.0Alpha3 > > Attachments: QueryTranslatorInvalidCastToObjectArray20trunk.patch > > > there seems to be an issue with a hard cast in the QueryTranslator > class, line 1452 (trunk) - resp. line 1288 (1.2.1) ... > The hard cast in method GetResultList to an object[] fails in the case > of my company's product, when using an IResultTransformer. > I chose to use an IResultTransformer implementation for Criteria's and > Query's to be able to set a required property. It seems an appropriate > way to me and my tests (and the running app) ensure that it works. > However, I had to patch the QueryTranslator at the locations mentioned > above, because it threw an invalid cast exception (stacktrace below) - > because the IList of my objects could not be casted to an object[]. > Debugging it, showed me that the "results" list contained my domain > objects, but it could not be casted to an object[]. It was a collection > of my domain types and my domain types are no object[]. Now, some time > passed by since then, and our product works fine with the patch, so > unfortunately I forgot the exact reason, but I'd guess, I used the > generic Query signature and so the results list was a generic list that > cannot be casted to object[]. But also ArrayList or Hashtable cannot be > casted to object[]... > A little experiment, gave me the compiler error: > Cannot convert type > 'System.Collections.Generic.List<ConsoleApplication1.Project>' to 'object[]' > class Program > { > static void Main(string[] args) > { > List<Project> projects = new List<Project>(); > object[] objs = (object[]) projects; > } > class Project { } > } > => same thing doesn't work with ArrayList or Hashtable ... > ---- > The code snippet from QueryTranslator in question: > for (int i = 0; i < results.Count; i++) > { > object[] row = (object[]) results[i]; > results[i] = holderInstantiator.Instantiate(row); > } > ---- > Patch - with a "safe" cast: > object[] row = results[i] as object[]; > if (row != null) > { > results[i] = holderInstantiator.Instantiate(row); > } > The included patch is for the NHibernate 2.0 trunk. > The same problem exists in earlier versions, namely 1.2. > I might be totally missing the root of the problem, but please excuse > this, as I am not familiar with the NHibernate internals, but tried to > apply a patch at the right place to enable the very useful feature of > the IResultTransformer to our case - and maybe to others in future. > Here is the stacktrace: (version 1.2.1) > at NHibernate.Hql.Classic.QueryTranslator.GetResultList(IList > results, IResultTransformer resultTransformer) in > d:\dev\yap\nhibernate\trunk\src\NHibernate\Hql\Classic\QueryTranslator.cs:line > 1291 > at NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor > session, QueryParameters queryParameters) in > d:\dev\yap\nhibernate\trunk\src\NHibernate\Loader\Loader.cs:line 1744 > at NHibernate.Loader.Loader.List(ISessionImplementor session, > QueryParameters queryParameters, ISet querySpaces, IType[] resultTypes) > in d:\dev\yap\nhibernate\trunk\src\NHibernate\Loader\Loader.cs:line 1738 > at NHibernate.Hql.Classic.QueryTranslator.List(ISessionImplementor > session, QueryParameters queryParameters) in > d:\dev\yap\nhibernate\trunk\src\NHibernate\Hql\Classic\QueryTranslator.cs:line > 1124 > at NHibernate.Impl.SessionImpl.Find(String query, QueryParameters > parameters, IList results) in > d:\dev\yap\nhibernate\trunk\src\NHibernate\Impl\SessionImpl.cs:line 1763 > ---- > My IResultTransformer implementation: > #region IResultTransformer Members > public object TransformTuple(object[] tuple, string[] aliases) > { > object o = CriteriaUtil.RootEntity.TransformTuple(tuple, aliases); > TrySetDomainModelStore(o); > return o; > } > public IList TransformList(IList collection) > { > for (int i = 0; i < collection.Count; i++) > { > TrySetDomainModelStore(collection[i]); > } > return collection; > } > #endregion > TranformTuple is called rarely. TransformList is called after the > HolderInstantiator call. > I never create a new MyEntity[] { my, domain, entities}, nor a new > object[] { my, domain, entities} ... > ------ > Felix Gartsman: > Isn't this similar to Hibernate issues: > http://opensource.atlassian.com/projects/hibernate/browse/HHH-2463 > http://opensource.atlassian.com/projects/hibernate/browse/HHH-2525 > They are also present in NH, and they prevent caching queries with > IResultTransformer - the caching thinks it gets a tuple, but it's actually > the transformed object. -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://216.121.112.228/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira |