2017-02-14 10 views
5

Ich habe eine einfache Hello-World Spring Boot-Anwendung mit JPA-Repositories und Hibernate. Die pom.xml wie folgt aussieht:NoSuchMethodError beim Starten der Spring Boot-Anwendung mit Hibernate JPA

... 
<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> 
... 

Die Datenbank-Konfiguration ist ganz einfach Properties-Datei:

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 

Und 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; 
    } 
} 

Das funktionierte mit 1.3.x Releases des Frühlings in Ordnung. Aber mit jeder 1.4.x oder 1.5.x Version der Autokonfiguration von Hibernate fehlschlägt:

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; 

Offensichtlich gibt keine solche Methode ist. Die Hibernate-Version, die von Spring-Boot konfiguriert ist:

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 

ich einige Frühlings Probleme gefunden, die dieses Problem Adressen. Sie behaupten, dass es behoben ist. Ist dieses Update nicht im Frühlingsstiefel verfügbar? Muss ich die Hibernate-Version manuell ändern? Ich bin sehr neu zu Spring Boot, aber ich dachte, dies ist der Grund für die Verwendung von Spring Boot, dass ich ein Präfix von dependnecies bekommen, die funktionieren wird. Was vermisse ich oder mache ich falsch?

Antwort

4

Wenn Sie Spring-Boot 1.5.1.RELEASE verwenden und in der Datei pom.xml eine spring-boot-starter-data-jpa-Abhängigkeit haben, ruft Spring-Boot alle Hibernate-bezogenen Jars ab. Bitte entfernen Sie die hibernate-core Abhängigkeit von Ihrer pom.xml, da Spring-Boot hibernate-core-5.0.11.jar zusammen mit anderen Hibernate-Jars abruft.

Der Fehler, den Sie bekommen, ist wegen Jadira Version 6.0.1.GA in Ihrer pom.xml. Diese Version ist nicht kompatibel mit Hibernate Version 5.0. Verwenden Sie Jadira Version 5.0.0.GA in Ihrer pom.xml wie unten.

<dependency> 
     <groupId>org.jadira.usertype</groupId> 
     <artifactId>usertype.core</artifactId> 
     <version>5.0.0.GA</version> 
</dependency> 
Verwandte Themen