Spring Hibernate Template执行方法返回Oracle上的计数查询的对象类型是什么?

当与Oracle数据库一起运行时,以下Spring Hibernate Template (Spring 2.5和Hibernate 3.3.2GA)代码返回的对象的运行时类型是什么,SQL查询是一个计数查询,如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; 

此代码抛出以下exception:

 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) 

怎么样

 long value = ((Number)query.uniqueResult()).longValue(); return Long.valueOf(value); 

这适用于Number的所有子类,如Long,Double,Biginteger或BigDecimal。

事实certificate, ClassCastException可能是由Hibernate标准查询缓存中的错误引起的。

解决方案是在查询中添加标量:

 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(); } }); 

参考文献:

  • 使用SQLQuery和setCacheable的ClassCastException(true)
  • Martin Schaaf的博客:使用SQLQuery和setCacheable的ClassCastException(true)
  • 使用Hibernate和EhCache缓存原始sql计数
  • HHH-5163在基于可缓存投影的条件上应用ResultTransformer时出现错误
  • 当Hibernate尝试使用ResultTransformer缓存结果时出现ClassCastException

我认为它返回Long类型。 我在代码中使用了Long。 但是如果你的BigDecimal工作,那么即使我想知道什么是返回类型:)

hibernateTemplate.execute()返回的对象的类类型确实是BigDecimal 。 事实certificate, ClassCastException的原因是方法doInHibernate()的返回值的doInHibernate()

 (BigDecimal) query.uniqueResult(); 

更正代码:

  BigDecimal count = (BigDecimal) hibernateTemplate.execute( new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { SQLQuery query = session.createSQLQuery(sql); return query.uniqueResult(); }}); return count;