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?