|
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
|