java.lang.ClassCastException:java.math.BigInteger无法强制转换为java.lang.Long

我想使用本机sql返回行数。 但是控制台说我java.math.BigInteger cannot be cast to java.lang.Long 。 怎么了? 这是我的方法:

 public Long getNumRows(Integer id){ Session session = null; session = this.sessionFactory.getCurrentSession(); Query query = session .createSQLQuery("SELECT COUNT(*) FROM controllnews WHERE news_id=" + id + ";"); List firstResult = query.list(); return (Long) firstResult.get(0); } 

使用BigInteger#longValue()方法,而不是将其强制转换为Long

 return firstResult.get(0).longValue(); 

看起来像firstResult.get(0)返回一个Object 。 一种选择是强制转换为BigInteger

 return ((BigInteger)firstResult.get(0)).longValue(); 

但是不要这样做。 而是使用Nambari在评论中提供的方式。 我不是Hibernate的用户,所以我不能提供Hibernate特定的解决方案。

我遇到了同样的问题,我使用了@Rohit Jain的回答评论中建议的Hibernate Scalar查询。 感谢@nambari的评论。

我们遇到的问题,

 Query query = session .createSQLQuery("SELECT COUNT(*) FROM controllnews WHERE news_id=" + id + ";"); 

这些将返回一个Object of Array数组(Object []),其中包含controllnews表中每列的标量值。 Hibernate将使用ResultSetMetadata来推断返回的标量值的实际顺序和类型。

为了避免使用ResultSetMetadata的开销,或者只是在返回的内容中更明确,可以使用addScalar():

 Query query = session .createSQLQuery("SELECT COUNT(*) as count FROM controllnews WHERE news_id=" + id + ";").addScalar("count", LongType.INSTANCE); 

这将返回Object数组,但现在它不会使用ResultSetMetadata,而是显式从底层结果集中将count列作为Long

如何将从ResultSetMetaData返回的java.sql.Types映射到Hibernate类型由Dialect控制。 如果未映射特定类型,或者未产生预期类型,则可以通过调用Dialect中的registerHibernateType来自定义它。


您可以使用Query#setParameter方法来避免查询中的任何错误

 Query query = session .createSQLQuery("SELECT COUNT(*) as count FROM controllnews WHERE news_id= :id") .addScalar("count", LongType.INSTANCE).setParameter("id",id); 

当您引用标量查询 docs 4.0时,一个混乱, addScalar方法有第二个参数Hibernate.LONG ,记得它自Hibernate版本3.6.X以来已被弃用
这是不推荐使用的文档 ,因此您必须使用LongType.INSTANCE

相关链接

  • Hibernate javadocs