Fixed
Details
Details
Assignee
Unassigned
UnassignedReporter
Olli Ryhänen
Olli RyhänenComponents
Fix versions
Priority
Who's Looking?
Open Who's Looking?
Created August 10, 2007 at 1:10 AM
Updated December 29, 2012 at 11:00 AM
Resolved May 2, 2011 at 7:08 AM
Enabling query-cache on a projection query with a result transformer attached using Criteria API, will fail with an exception:
"System.InvalidCastException: Unable to cast object of type '<The output type from the result transformer' to type 'System.Object[]'"
The exception is caused by the line:
"cacheable.Add( TypeFactory.Disassemble( ( object[ ] ) result[ i ], returnTypes, session ) );"
in "NHibernate\Cache\StandardQueryCache.cs" on line 63, when it tries to cast the "result[i]" to an "object[]".
Using result transformers the result set has already been transformed to the transformed type, before adding to the cache, so casting to "object[]" will fail. (The transformation is done in the method "GetResultColumnOrRow" in CriteriaLoader.cs on line 74, which gets called in process of loading the result set from the database).
To reproduce the issue, turn on caching on any of the projection query tests with result transformer in "CriteriaQueryTests.cs". E.g. on line 494
IList resultWithAliasedBean = s.CreateCriteria(typeof (Enrolment))
.CreateAlias("Student", "st")
.CreateAlias("Course", "co")
.SetProjection(Projections.ProjectionList()
.Add(Projections.Property("st.Name"), "studentName")
.Add(Projections.Property("co.Description"), "courseDescription")
)
.AddOrder(Order.Desc("studentName"))
.SetResultTransformer(Transformers.AliasToBean(typeof (StudentDTO)))
.SetCacheable(true)
.List();
A simple fix would be to check if the type of "result[i]" is an "object[]" before adding to the cache and cache non "object[]" types as is to the cache (and do the same check when getting the items back from the cache), but I'm not sure if that would break the caching architecture in some way.