当前位置: 首页 > 知识库问答 >
问题:

使用Hibernate JPA启动spring boot应用程序时的NoSuchMethodError

经炜
2023-03-14

我有一个简单的Hello-World spring boot应用程序,带有JPA存储库和Hibernate。pom.xml如下所示:

...
<properties>
  <springframework.version>1.5.1.RELEASE</springframework.version>
  <validation-api.version>1.1.0.Final</validation-api.version>
  <dbunit.version>2.5.3</dbunit.version>
  <usertype.core.version>6.0.1.GA</usertype.core.version>
  <validate.version>2.2.0</validate.version>
  <strman.version>0.2.0</strman.version>
  <reflections.version>0.9.10</reflections.version>
  <javax.servlet.jsp-api.version>2.3.1</javax.servlet.jsp-api.version>
  <rest-assured.version>3.0.1</rest-assured.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${springframework.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<repositories>
    <repository>
        <id>spring-milestone</id>
        <url>https://repo.spring.io/libs-release</url>
    </repository>
</repositories>

<pluginRepositories>
    <pluginRepository>
        <id>spring-milestone</id>
        <url>https://repo.spring.io/libs-release</url>
    </pluginRepository>
</pluginRepositories>

<dependencies>
    <!-- Spring -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <!-- We use Logback for logging. -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
            <exclusion>
                <!-- We use Jetty because it is cooler ;) -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-messaging</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>

    <!-- JSON -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jdk8</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-joda</artifactId>
    </dependency>

    <!-- Logging -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
    </dependency>

    <!-- Hibernate -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
    </dependency>

    <!-- jsr303 validation -->
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>${validation-api.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
    </dependency>

    <!-- Joda-Time -->
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
    </dependency>

    <!-- To map JodaTime with database type -->
    <dependency>
        <groupId>org.jadira.usertype</groupId>
        <artifactId>usertype.core</artifactId>
        <version>${usertype.core.version}</version>
    </dependency>

    <!-- MySQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
        <groupId>de.weltraumschaf.commons</groupId>
        <artifactId>validate</artifactId>
        <version>${validate.version}</version>
    </dependency>

    <!-- String utility -->
    <dependency>
        <groupId>com.shekhargulati</groupId>
        <artifactId>strman</artifactId>
        <version>${strman.version}</version>
    </dependency>

    <dependency>
        <groupId>org.reflections</groupId>
        <artifactId>reflections</artifactId>
        <version>${reflections.version}</version>
    </dependency>

    <!-- Provided from container -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>${javax.servlet.jsp-api.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <scope>provided</scope>
    </dependency>
</dependnecies>
...

数据库配置是相当简单的属性文件:

spring.datasource.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.url               = jdbc:mysql://localhost:3306/snafu?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=utf8
spring.datasource.username          = snafu
spring.datasource.password          = ***

spring.jpa.show-sql             = false
spring.jpa.hibernate.format_sql = true
spring.jpa.hibernate.ddl-auto   = update
spring.jpa.database-platform    = org.hibernate.dialect.MySQLInnoDBDialect

和DB ConfigClass:

package org.snafu;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableJpaRepositories(basePackages = { "org.snafu.repo" })
public class DatabaseConfiguration {
    @Value("${spring.datasource.driverClassName}")
    private String driver = "";
    
    @Value("${spring.datasource.url}")
    private String url = "";
    
    @Value("${spring.datasource.username}")
    private String user = "";
    
    @Value("${spring.datasource.password}")
    private String password = "";
    
    @Value("${spring.jpa.show-sql}")
    private String showSql = "";
    
    @Value("${spring.jpa.hibernate.format_sql}")
    private String formatSql = "";
    
    @Value(value = "${spring.jpa.hibernate.ddl-auto}")
    private String ddlAuto;
    
    @Value(value = "${spring.jpa.database-platform}")
    private String dialect;
    
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan("de.iteratec.str.iteratweet.model");

        final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());
        
        return em;
    }
    
    @Bean
    public DataSource dataSource() {
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(user);
        dataSource.setPassword(password);
        return dataSource;
    }
    
    private Properties additionalProperties() {
        final Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", ddlAuto);
        properties.setProperty("hibernate.dialect", dialect);
        properties.setProperty("hibernate.naming_strategy", "org.hibernate.cfg.EJB3NamingStrategy");
        return properties;
    }
}

这在spring的1.3.x版本中运行良好。但对于任何1.4.x或1.5.x版本,Hibernate的自动配置都将失败:

java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' 
defined in class path resource [org/snafu/DatabaseConfiguration.class]: Invocation of init method failed; 
nested exception is java.lang.NoSuchMethodError: org.hibernate.engine.spi.SessionFactoryImplementor.getProperties()Ljava/util/Map;
Caused by: java.lang.NoSuchMethodError: org.hibernate.engine.spi.SessionFactoryImplementor.getProperties()Ljava/util/Map;

显然没有这样的方法。spring boot配置的Hibernate版本是:

mvn dependency:tree | grep -i hibernate
[INFO] |  +- org.hibernate:hibernate-entitymanager:jar:5.0.11.Final:compile
[INFO] +- org.hibernate:hibernate-core:jar:5.0.11.Final:compile
[INFO] |  +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
[INFO] |  \- org.hibernate.common:hibernate-commons-annotations:jar:5.0.1.Final:compile
[INFO] +- org.hibernate:hibernate-validator:jar:5.3.4.Final:compile

我发现了一些解决这个问题的spring问题。他们声称它已经修好了。spring boot没有这种方法吗?我必须手动更改Hibernate版本吗?我对spring boot很陌生,但我认为这是使用spring boot的原因,因为我得到了一组预定义的依赖项,这些依赖项可以协同工作。我错过了什么或者做错了什么?

共有1个答案

宦炜
2023-03-14

考虑到您使用的是spring-boot1.5.1.release并且在pom.xml文件中有spring-boot-starter-data-jpa依赖项,spring-boot将获取所有与Hibernate相关的JAR。请从您的pom.xml中删除hibernate-core依赖项,因为spring引导将获取hibernate-core-5.0.11.jar以及其他hibernate JAR。

您得到的错误是因为pom.xml中的Jadira版本6.0.1.ga。此版本与Hibernate 5.0版本不兼容。在pom.xml中使用jadira版本5.0.0.ga,如下所示。

<dependency>
        <groupId>org.jadira.usertype</groupId>
        <artifactId>usertype.core</artifactId>
        <version>5.0.0.GA</version>
</dependency>
 类似资料:
  • 使用spring-boot时,一切工作都很好。尽管如此,在spring-boot中已删除了注释和。我试图将代码重构为新版本,但我做不到。对于以下测试,我的应用程序在测试之前没有启动,http://localhost:8080返回404: 如何重构测试以使其在Spring-Boot1.5中工作?

  • 问题内容: 我有一个Java应用程序。 该应用程序具有一个设置,该设置决定该应用程序是否在启动时启动。 目前,我可以通过在“启动项目”文件夹中放置/删除快捷方式来实现此目的。 但是,我想知道是否有更好的方法来处理此行为。 编辑 是的,它是Windows。抱歉,之前没有清除该内容。 该应用程序具有一个用户可以在其中触发动作的UI,并且该应用程序在运行时会定期在后台运行一些任务。 @Peter,如何在

  • 问题内容: 我已经看到许多应用程序将乐器类作为参数并在加载时作为参数,这些应用程序也将a 放到了命令行中。 Java文档说关闭了类验证。 但是,为什么有人要关闭验证,即使他们正在学习类呢? 问题答案: 我会说启动时间。加载类时,验证类是否正确需要花费一些时间。由于类可能以惰性方式加载(不是在应用程序启动时加载,而是在首次使用时加载),因此这可能会导致意外的和不希望的运行时延迟。 实际上,通常不需要

  • 我的程序编译了所有内容,我没有出错,但我实际上期望tomcat应该永久在端口8080上。输出中也没有Spring。在另一个项目中,我做的一切都很好。谢谢你帮助我。 我的父母: 我的tarter.class: 我的Starter-Pom: 控制台输出: 然后什么都不会发生了。谢谢你的帮助。

  • 我想对Spring数据使用ElasticSearch。我使用的是Spring 5、Spring Boot 2和ElasticSearch 7.4。Docker compose: 马文: 存储库: 配置: 和错误时启动应用程序: 引起:java.lang.NoSuchMEDError:org.springframework.http.HttpHeaders.(Lorg/springframe/uti

  • 我在stackoverflow上发现了类似的问题,并试图用这种方式(LINK)解决这个问题,但在我的项目中没有起作用。谁能给我一些建议吗? pom.xml 应用属性

  • 我有一份Java申请。 应用程序有一个决定应用程序是否在启动时启动的设置。 目前,我通过在StartUp items文件夹中放置/删除快捷方式实现了这一点。 然而,我想知道是否有更好的方法来处理这种行为。 编辑 是的,是视窗。抱歉之前没有清除。 应用程序有一个UI,用户可以在其中触发操作,并且应用程序在运行时定期在后台运行一些任务。 @Peter,如何使用应用程序中的代码更改注册表?这种方法是否与

  • 我正试图将运行在tomcat上的现有应用程序更改为SpringBoot。它一直运行到真正的SpringBoot启动。我有一个类似的应用程序运行在SpringBoot上。这就是我知道它一直运行到Springboot的原因。 我的主要方法: 我尝试使用@componentscan运行main方法,该方法具有如下所示的basePackages: 这无济于事。我尝试在main类的顶部添加@SpringBo