ClassCastException with SQLQuery and setCacheable(true)

Today I had to change a hibernate query constructed with the criteria API to a SQL query. The result looked like:

String sqlQuery = "select count(*) ...";
Session dbSession = getSession();
SQLQuery crit = dbSession.createSQLQuery(sqlQuery);
crit.setCacheable(true);
return (Integer) crit.uniqueResult();

The former query was cached and the new one should be too. But I got the following exception:

java.lang.ClassCastException: java.math.BigDecimal
at org.hibernate.cache.StandardQueryCache.put(StandardQueryCache.java:83)

The following post from hibernate forum helped me to find a solution. The exception is gone after adding the result as a scalar. And the working query looks like:

String sqlQuery = "select count(*) as result ...";
Session dbSession = getSession();
SQLQuery crit = dbSession.createSQLQuery(sqlQuery);
crit.addScalar("result", Hibernate.INTEGER);
crit.setCacheable(true);
return (Integer) crit.uniqueResult();

Revisions of entities with hibernate

The last week we implemented revisions for entites with hibernate. We decided us for envers. The documentation is good. We were able to get a working revision system with switching between revisions within this week. One note we used the version 1.1.0.GA for hibernate 3.2.6 so the documentation didn’t applied fully the naming of annotations and configuration property names changed. We run in to one issue. Our database already existed and we had to introduce the revisions later. Envers does not create on first run a initial revision for versioned entities. But you will need them because if you switch back you will lost data for properties that are stored in a list. Lets say you have a versioned entity with a list of strings and you change this list by adding entries. If you go back you don’t have the entries that were in the list before you added the new one. To solve this we had to write our own tool to create the first revision. Since fixing this envers works very good in our project. I can suggest its usage.