[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2463?page=c...
]
Tim Leahy commented on HHH-2463:
--------------------------------
We're also facing this same problem with out projects. Our applications and
persistence library were rewritten to use Hibernate by an offshore company however it was
not built to scale very well. The database was fully normalized and restructured as part
of the rewrite and getting the full object back for queries put too much load on our
database, memory, network, and cpu. We eventually decided to start using projections in
the existing criteria queries to only get the data we needed.
When we started converting the criteria queries to use projections with a result
transformer we discovered we could not cache the queries because of this bug. Manually
mapping Object[] to beans after the query is less than ideal, so we ended up using HQL
with dynamic bean instantiation and with a set of beans with some pretty big constructors.
Every time we find an expensive criteria query we have to completely rewrite it, we'd
like to stop doing that.
ClassCastException when Hibernate tries to cache results using
ResultTransformer
--------------------------------------------------------------------------------
Key: HHH-2463
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2463
Project: Hibernate3
Issue Type: Bug
Affects Versions: 3.2.2
Reporter: Peak user
When Hibernate executes a cacheable query using a ResultTransformer, it will attempt to
cache the results AFTER applying the ResultTransformer. The problem is that the
ResultTransformer may modify the data in a way that Hibernate won't understand it
anymore, and in this case it will generate a ClassCastException when trying to cache it.
This problem could be easily solved if Hibernate cached results before applying the
ResultTransformer instead of afterwards.
Here's a sample code to reproduce this problem:
class ToMapResultTransformer implements ResultTransformer {
private String[] properties;
public ToMapResultTransformer(String[] properties) {
this.properties = properties;
}
public List transformList(List collection) {
return collection;
}
public Object transformTuple(Object[] tuple, String[] aliases) {
Map<String,Object> result = new
HashMap<String,Object>(tuple.length);
for (int i=0; i<tuple.length; i++) {
result.put((properties != null ? properties[i] : aliases[i]), tuple[i]);
}
return result;
}
}
Criteria sqlCriteria = createSqlCriteria(session);
sqlCriteria.setProjection(projections);
sqlCriteria.setCacheable(true);
sqlCriteria.setResultTransformer(new ToMapResultTransformer(properties));
sqlCriteria.list();
The code above produces the following exception:
java.lang.ClassCastException: java.util.HashMap
at org.hibernate.cache.StandardQueryCache.put(StandardQueryCache.java:83)
at org.hibernate.loader.Loader.putResultInQueryCache(Loader.java:2185)
at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2129)
at org.hibernate.loader.Loader.list(Loader.java:2087)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira