在javax.persistence.Table中出现NoSuchMethodError错误:indexes()[Ljavax/persistence/Index]

89

我有一个Play框架应用程序,之前使用的是通过Maven依赖管理器检索到的Hibernate 4.2.5.Final。现在决定升级到Hibernate 4.3.0.Final,成功重新编译并运行该应用程序。

但是我遇到了下面的异常,目前还没有找出原因。我将版本降级回4.2.5后,就没有出现这个问题。然后,我尝试了从4.2.5.Final开始逐个升级到每个Final版本,包括4.2.6.Final、4.2.7.Final、4.2.8.Final以及4.3.Final。只有升级到4.3.0.Final时才会出现这个问题。

Java版本信息

java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

异常情况:

play.api.UnexpectedException: Unexpected exception[NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:152) ~[play_2.10.jar:2.2.1]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:112) ~[play_2.10.jar:2.2.1]
    at scala.Option.map(Option.scala:145) ~[scala-library.jar:na]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:112) ~[play_2.10.jar:2.2.1]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:110) ~[play_2.10.jar:2.2.1]
    at scala.util.Success.flatMap(Try.scala:200) ~[scala-library.jar:na]
Caused by: java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
    at org.hibernate.cfg.annotations.EntityBinder.processComplementaryTableDefinitions(EntityBinder.java:936) ~[hibernate-core-4.3.0.Final.jar:4.3.0.Final]
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:781) ~[hibernate-core-4.3.0.Final.jar:4.3.0.Final]
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3762) ~[hibernate-core-4.3.0.Final.jar:4.3.0.Final]
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3716) ~[hibernate-core-4.3.0.Final.jar:4.3.0.Final]
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1410) ~[hibernate-core-4.3.0.Final.jar:4.3.0.Final]
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844) ~[hibernate-core-4.3.0.Final.jar:4.3.0.Final]

1
您正在调用一个在较新版本中不存在的方法。 - Brian Roach
9个回答

81

我也遇到了同样的问题。问题在于play-java-jpa组件(build.sbt文件中的javaJpa键)依赖于不同版本的规范 (version 2.0 -> "org.hibernate.javax.persistence" % "hibernate-jpa-2.0-api" % "1.0.1.Final")

当你添加了 hibernate-entitymanager 4.3 后,它会带来更新的规范(2.1)和一个不同的实体管理器工厂提供程序。基本上你最终会在类路径中拥有这两个JAR作为传递依赖项。

按照以下方式编辑你的 build.sbt 文件,它将暂时解决你的问题,直到play发布新版本的jpa插件以适应更新的API依赖关系。

libraryDependencies ++= Seq(
javaJdbc,
javaJpa.exclude("org.hibernate.javax.persistence", "hibernate-jpa-2.0-api"),
"org.hibernate" % "hibernate-entitymanager" % "4.3.0.Final"
)

这是针对 play 2.2.x 版本的。在之前的版本中,构建文件有一些差异。


1
太棒了,它起作用了!谢谢。供以后参考,这里是一个链接,介绍如何排除传递依赖项:http://www.scala-sbt.org/0.12.2/docs/Detailed-Topics/Library-Management.html#exclude-transitive-dependencies - musubi
4
谢谢!针对Maven用户而言,这意味着不要再使用<groupId>org.hibernate.java-persistence</groupId> <artifactId>jpa-api</artifactId>。请直接避免使用这个库。 - oak
4
对于 hibernate-jpa-2.0-api,Hibernate 4.2.8.Final 版本可以工作,但是 4.3.0.Final 版本会抛出错误。 - Harmeet Singh Taara
在Play 2.2.3中,libraryDependencies ++= Seq(javaJdbc,javaEbean,cache,javaJpa.exclude(“org.hibernate.javax.persistence”,“hibernate-jpa-2.0-api”),“org.hibernate”%“hibernate-core”%“4.3.0.Final”,“org.hibernate”%“hibernate-entitymanager”%“4.3.0.Final”,“com.typesafe”%%“play-plugins-mailer”%“2.2.0”,“postgresql”%“postgresql”%“9.1-901-1.jdbc4”,“com.google.guava”%“guava-base”%“r03”,“org.apache.commons”%“commons-io”%“1.3.2”)仍然会抛出NoSuchMethodException NoSuchMethodError:javax.persistence.JoinTable.indexes()。有人知道如何解决吗? - FrancescoM
我也遇到了Play 2.3.4版本的同样问题。以下是堆栈跟踪信息: play.api.UnexpectedException: Unexpected exception[NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;] at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:170) ~[play_2.11-2.3.4.jar:2.3.4 ] at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:130) ~[play_2.11-2.3.4.jar:2.3.4 ] at scala.Option.map(Option.scala:145) ~[scala-library-2.11.1.jar:na] - Ketan Khairnar
遇到了同样的问题。添加了 "org.hibernate" % "hibernate-entitymanager" % "4.3.8.Final" 并替换为 javaJpa.exclude("org.hibernate.javax.persistence", "hibernate-jpa-2.1-api"),javaJpa.exclude("org.hibernate.javax.persistence", "hibernate-jpa-2.0-api"),但仍然存在相同的问题。 - kashish verma

74

Hibernate 4.3是第一个实现JPA 2.1规范(Java EE 7的一部分)的版本。因此,它需要在类路径中使用JPA 2.1库,而不是JPA 2.0库。这就是为什么会出现这个异常的原因:Table.indexes()是Table的一个新属性,引入于JPA 2.1。


@SotiriosDelimanolis:错误是 NoSuchMethodError: javax.persistence.Table.indexes() - JB Nizet
1
你可能没有看正确的代码。请参考 https://github.com/hibernate/hibernate-orm/blob/4.3.0.Final/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java#L936 - JB Nizet
1
@JBNizet JPA 2.1只能在Java EE 7中使用,而不能在SE 7中使用?我猜JPA 2.0可以在Java SE 7中使用? - musubi
2
@JBNizet 那么解决方案是什么?我可以将Java EE更改为7还是将JPA 2.0更改为JPA 2.1?如果我这样做会出现错误。 - Shailendra Madda
1
<!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api --> <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency> - bula
显示剩余4条评论

16

我将我的Hibernate JPA更新到2.1,现在它可以正常工作。

<dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.1-api</artifactId>
    <version>1.0.0.Final</version>
</dependency>

14

你的类路径上可能有2个不同版本的hibernate-jpa-api。为了检查它,请运行:

mvn dependency:tree >dep.txt

然后搜索是否存在 hibernate-jpa-2.0-api 和 hibernate-jpa-2.1-api。然后排除多余的一个。


6
错误: java.lang.NoSuchMethodError: javax.persistence.JoinTable.indexes()[Ljavax/persistence/Index;
唯一解决我的问题的方法是在pom.xml中删除以下依赖项: org.hibernate.javax.persistence hibernate-jpa-2.1-api 1.0.0.Final 并替换为:
<dependency>
  <groupId>javax.persistence</groupId>
  <artifactId>persistence-api</artifactId>
  <version>1.0.2</version>
</dependency>

希望能帮助到有需要的人。


6

我可以通过替换位于jboss7/modules/javax/persistence/api/main目录下的JPA api jar文件为“hibernate-jpa-2.1-api”,并更新该目录下的module.xml文件来简单解决这个问题。


1

你的类路径中有多个JPA提供程序。或者至少在应用服务器lib文件夹中。

如果你正在使用Maven,请使用此处提到的命令检查依赖项 https://dev59.com/HnVC5IYBdhLWcg3wfhKL#47474708

然后通过删除/排除不需要的依赖项来修复问题。

如果你的类路径中只有一个依赖项,那么应用服务器的类加载器可能是问题所在。

由于JavaEE应用服务器(如Websphere、Wildfly、Tomee等)具有自己的JPA和其他EE标准实现,类加载器可能会加载它自己的实现,而不是从WAR/EAR文件中选择。

为了避免这种情况,你可以尝试以下步骤。

  1. 从应用服务器库路径中删除有问题的jar。请小心操作,因为它可能会破坏其他托管应用程序。
在Tomee 1.7.5 Plume/Web中,它将使用JPA 2.0在lib文件夹中捆绑eclipselink-2.4.2,但我必须使用来自org.hibernate:hibernate-core:5.1.17的JPA 2.1,因此删除了eclipselink jar并添加了所有相关/传递依赖项从hibernate core。
  1. 添加共享库。并手动将jar添加到应用程序服务器的路径中。Websphere有这个选项。

  2. 在Websphere中,可以更改类加载器的执行方式。所以使它成为应用程序服务器的类路径最后加载,即父级最后加载,并且首先加载您的路径。可以解决这个问题。

在继续第一点之前,请检查您的应用程序服务器是否具有上述功能。

Ibm websphere参考资料:

https://www.ibm.com/support/knowledgecenter/SSEQTP_9.0.5/com.ibm.websphere.base.doc/ae/trun_classload_server.html

https://www.ibm.com/support/pages/how-create-shared-library-and-associate-it-application-server-or-enterprise-application-websphere-application-server


0

我在我的Spring Boot应用程序中遇到了相同的问题。在lib文件夹中手动删除javax.persistance.jar文件后,问题解决了。在pom.xml文件中,我只保留了以下依赖项。

  <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>

0

我遇到了同样的问题,但是在实体类中使用org.hibernate.annotations.Table注解而不是javax.persistence.Table来修复它。

import javax.persistence.Entity;
import org.hibernate.annotations.Table;

@Entity
@Table(appliesTo = "my_table")
public class MyTable{
//and rest of the code

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接