当针对Oracle数据库运行时,以下Spring Hibernate模板(Spring 2.5和Hibernate 3.3.2GA)代码返回的对象的运行时类型是什么,SQL查询是诸如此类的计数查询select count(*) from table?
select count(*) from table
String sql = "select count(*) from table"; BigDecimal count = (BigDecimal) hibernateTemplate.execute( new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { SQLQuery query = session.createSQLQuery(sql); return (BigDecimal) query.uniqueResult(); }}); return count;
此代码引发以下异常:
javax.ejb.EJBException: EJB Exception: : java.lang.ClassCastException: java.math.BigDecimal cannot be cast to [Ljava.lang.Object; 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.custom.CustomLoader.list(CustomLoader.java:289) at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1695) at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:142) at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:150) at org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:804) at com.db.abstrack.dao.hibernate.RfqCdoUsDaoHibernate$1.doInHibernate(RfqCdoUsDaoHibernate.java:124)
原来,这ClassCastException可能是由于Hibernate标准查询缓存中的错误所致。
ClassCastException
解决方案是在查询中添加标量:
String sql = "select count(*) as result from table"; BigDecimal count = (BigDecimal) ht.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { SQLQuery query = session.createSQLQuery(sql); // Add scalar to avoid bug in Hibernate query cache. query.addScalar("result", Hibernate.BIG_DECIMAL); return query.uniqueResult(); } });
参考文献: