为什么我在使用 Hibernate 5.2.8 和 JasperReports 6.4.0 时得到 java.lang.NoSuchMethodError

Why do I get java.lang.NoSuchMethodError when using Hibernate 5.2.8 with JasperReports 6.4.0

我正在开发使用 Apache Tomcat、Spring 和 Hibernate 的网络应用程序项目。它还使用 JasperReports v.6.4.0 生成 pdf 报告。最近,Spring 和 Hibernate 的版本从 3.1.2 更新到 Spring 的 4.3.6,Hibernate 从 3.3.1 更新到 5.2.8。

迁移后出现的所有问题都已解决,只有一个除外。当生成带有 hql-queries 的报告时,会抛出以下异常:

java.lang.NoSuchMethodError: org.hibernate.Session.createQuery(Ljava/lang/String;)Lorg/hibernate/Query;
at net.sf.jasperreports.engine.query.JRHibernateQueryExecuter.createQuery(JRHibernateQueryExecuter.java:279)
at net.sf.jasperreports.engine.query.JRHibernateQueryExecuter.createDatasource(JRHibernateQueryExecuter.java:195)
at net.sf.jasperreports.engine.fill.JRFillDataset.createQueryDatasource(JRFillDataset.java:1245)
at net.sf.jasperreports.engine.fill.JRFillDataset.initDatasource(JRFillDataset.java:723)
at net.sf.jasperreports.engine.fill.BaseReportFiller.setParameters(BaseReportFiller.java:438)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:550)
at net.sf.jasperreports.engine.fill.BaseReportFiller.fill(BaseReportFiller.java:396)
at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:90)
at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:456)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:863)

在升级之前,JasperReports v.6.4.0 可以与 Hibernate v.3.3.1 一起正常工作。 谁能帮我避免这个问题?

jasper-reports v.6.4.0 is depending on hibernate v. 3.3.2.GA中的JRHibernateQueryExecuter

不同之处在于,在 Hibernate 5.2 中,Query class 从 org.hibernate 移动到了 org.hibernate.query

那么解决方法是什么?

要使用 JRHibernateQueryExecuter,您需要在 class 路径中使用 hibernate v. 3.3.2,因此您要么恢复原状,要么开发自己的 JRHibernateQueryExecuterJRHibernateQueryExecuterFactory依赖于 Hibernate 5.2.8.

source code is available 以来,开发您自己的 JRHibernateQueryExecuter 可能并不像听起来那么困难,您可能只需要调整导入即可。

要注册您的 "new" QueryFactory,请参阅:How I can associate a query language with my executer in Jaspersoft studio?

我听从了@PetterFriberg 给出的建议,并编写了一个小库,使将 Hibernate 5 与 JasperReports 6 结合使用成为可能。

来源和说明可在此处找到: JasperReports6-Hibernate5

一旦您创建了自己的 JRHibernateQueryExecuterJRHibernateQueryExecuterFactory 版本,您就可以通过调用

注册它们以供使用
JasperReportsContext jasperReportsContext = DefaultJasperReportsContext.getInstance();
JRPropertiesUtil jrPropertiesUtil = JRPropertiesUtil.getInstance(jasperReportsContext);
jrPropertiesUtil.setProperty("net.sf.jasperreports.query.executer.factory.hql", "net.sf.jasperreports.engine.query.h5.JRHibernateQueryExecuterFactory");
jrPropertiesUtil.setProperty("net.sf.jasperreports.query.executer.factory.HQL", "net.sf.jasperreports.engine.query.h5.JRHibernateQueryExecuterFactory");

我不确定为什么 Jaspersoft 没有自己实施修复。开始正确支持更高版本的hibernate确实是一个简单的更改。