Wildfly, spring data jpa get NoClassDefFoundError: HibernateException - java

Hi I am trying to create a spring mvc application on wildfly 9 with spring data jpa, when I add in the jpa related config and dependencies, it gets NoClassDef Found error. Here's the server log:
Caused by: java.lang.NoClassDefFoundError: org/hibernate/HibernateException
at org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter.(HibernateJpaVendorAdapter.java:60)
Maven pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>testspringmvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
<spring.version>4.2.0.RELEASE</spring.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-parent</artifactId>
<version>9.0.1.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.8.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
The config class
package com;
//import skipped...
#Configuration
#ComponentScan(basePackages = "com*")
#EnableWebMvc
#EnableJpaRepositories
#EnableTransactionManagement
public class TestAppConfig extends WebMvcConfigurerAdapter {
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.freeMarker().cache(false);
}
#Bean
public FreeMarkerConfigurer freeMarkerConfigurer() throws TemplateException, IOException {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("/WEB-INF/freemarker/");
return configurer;
}
#Bean
public AbstractPlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory());
}
#Bean
public EntityManagerFactory entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
bean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); //This is the line the log complaining
bean.setDataSource(dataSource());
final Properties props = new Properties();
props.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
props.setProperty("hibernate.hbm2ddl.auto", "validate");
props.setProperty("hibernate.show_sql", "true");
props.setProperty("hibernate.format_sql", "true");
bean.setJpaProperties(props);
return bean.getObject();
}
#Bean
public DataSource dataSource() {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(true);
DataSource dataSource = dsLookup.getDataSource("java:/PostgresDS");
return dataSource;
}
}
Did i do anything wrong?
For maven, i read somewhere that using jpa should not include hibernate-core but the HibernateException is in there, but include and exclude it gives the same error.
Project ran on wildfly 9 using eclipse and wildfly plugin.
Thank you very much.

You need to put provided scope for jpa 2.1 api, and exclude the same api from hibernate core for it to work.

Related

No bean named 'transactionManager' available in SpringBoot JPA Configuration

According to baeldung here
If we're using a Spring Boot project, and have a spring-data-* or spring-tx >dependencies on the classpath, then transaction management will be enabled by >default."
However, i have this error:
org.springframework.messaging.MessageHandlingException: error occurred during processing message in 'MethodInvokingMessageProcessor' [org.springframework.integration.handler.MethodInvokingMessageProcessor#788f2bfc]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'transactionManager' available: No matching TransactionManager bean found for qualifier 'transactionManager' - neither qualifier match nor bean name match!
with these Dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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-artemis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.indra.icens</groupId>
<artifactId>ic-license</artifactId>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>javax.jms-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jms</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>mq</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>mqjms</artifactId>
</dependency>
<dependency>
<groupId>javax.resource</groupId>
<artifactId>connector</artifactId>
</dependency>
<dependency>
<groupId>com.indra.icens.srom</groupId>
<artifactId>ic_int_srom_common</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
</dependency>
</dependencies>
application.properties:
spring.datasource.url=jdbc:postgresql://xxx/yyy
spring.datasource.username=asdasd
spring.datasource.password=werwer
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL95Dialect
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
spring.jpa.show-sql=false
ServiceConfig.java
#EnableJms
#Configuration
#ImportResource({
"classpath:/META-INF/spring/integration/main-config.xml"
})
#EnableJpaRepositories("com.nbi.conn.repository")
#EntityScan("com.nbi.conn.entities")
public class ServiceConfig {
}
what is wrong ?, what am i missing in my SpringBoot Config?
Thanks in advance for your help
Did you try to add a bean "transactionManager" in your config like this
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}

NoSuchMethodError when starting Spring Boot Application with Hibernate JPA

I have a simple Hello-World Spring Boot Application with JPA repositories and Hibernate. The pom.xml looks like:
...
<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>
...
The database configuration is quite simple properties file:
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
And 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;
}
}
This worked fine with 1.3.x Releases of Spring. But with any 1.4.x or 1.5.x Version the autoconfiguration
of Hibernate fails:
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;
Obviously there is no such method. The Hibernate version which is configured by Spring Boot is:
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
I found some Spring issues which addresses this problem. They claim it is fixed. Is this fix not
available in Spring Boot? Do I have to change the Hibernate version by hand? I'm very new to
Spring Boot, but I thought this is the reason for using Spring Boot that I get a predefined set
of dependencies which will work together. What do I miss or do wrong?
Considering you are using Spring-Boot 1.5.1.RELEASE and have spring-boot-starter-data-jpa dependency in pom.xml file, Spring-Boot will fetch all the Hibernate related jars. Please remove hibernate-core dependency from your pom.xml as Spring-Boot will fetch hibernate-core-5.0.11.jar along with other hibernate jars.
The error you are getting is because of Jadira version 6.0.1.GA in your pom.xml. This version is not compatible with Hibernate version 5.0. Use Jadira version 5.0.0.GA in your pom.xml like below.
<dependency>
<groupId>org.jadira.usertype</groupId>
<artifactId>usertype.core</artifactId>
<version>5.0.0.GA</version>
</dependency>

Spring : Restrict injection of Repository module in Controller

I'm building a REST Webservice using Spring Boot (v 1.4.2.RELEASE). I'm trying to follow separation of concerns pattern, so I've created 3 maven projects,
myapp-repository, myapp-service and myapp-rest. myapp-service has a dependency of myapp-repository and myapp-rest has a dependency of myapp-service. Below is the initial configuration I've made.
myapp-repository
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
Repository Config
#Configuration
#EnableJpaRepositories
#ComponentScan("com.mycompany.myapp.repository")
#EntityScan("com.mycompany.myapp.entity")
#PropertySource("classpath:repository.properties")
public class RepositoryConfig {
#Bean
#Primary
#ConfigurationProperties(prefix = "myapp.primary.datasource")
public DataSource getDataSource() {
return DataSourceBuilder.create().build();
}
}
myapp-service
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>com.mycompany.myapp</groupId>
<artifactId>myapp-repository</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
Service config
#Configuration
#ComponentScan("com.mycompany.myapp.service")
#Import(RepositoryConfig.class)
#PropertySource("classpath:service.properties")
public class ServiceConfig {
}
myapp-rest
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mycompany.myapp</groupId>
<artifactId>myapp-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
Rest config
#SpringBootApplication
#ComponentScan("com.mycompany.myapp.rest")
#Import(ServiceConfig.class)
public class RestConfig extends SpringBootServletInitializer {
/**
* #param args
*/
public static void main(String[] args) {
SpringApplication.run(RestConfig.class, args);
}
}
Now, I want to restrict my repository services to be autowired in myapp-rest, but with this current implementation, it's possible. Only services inside myapp-service module should be allowed to autowire in myapp-rest. Is it possible?

Spring MVC 4.1 ResourceUrlProvider not found

I'm working in a Spring MVC 4.1 application with Velocity teampltes. I'm trying to get resource handling setup. This tutorial documents exactly what i want:
http://www.mscharhag.com/spring/resource-versioning-with-spring-mvc
However, the ResourceUrlAdvice throws an error that ResourceUrlProvider is not defined. I thought ResourceUrlProvider was supposed to be automatically defined by #EnableWebMvc (I'm not using Spring Boot).
I even tried explicitly declaring an #Bean in my MvcConfig class and it still threw an error. I feel like I'm missing something obvious.
Controller advice class:
#ControllerAdvice
public class ResourceUrlAdvice {
#Autowired private ResourceUrlProvider resourceUrlProvider;
#ModelAttribute("urls")
public ResourceUrlProvider urls() {
return this.resourceUrlProvider;
}
}
Error:
...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.resource.ResourceUrlProvider] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1308)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
... 24 more
Edit: Additional Info
MvcConfig.java:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.foo.controller" })
public class MvcConfig extends WebMvcConfigurerAdapter {
private static final int CACHE_1_YEAR = 60 * 60 * 24 * 365; // 1 year, in seconds
#Autowired private ResourceUrlProvider resourceUrlProvider;
#Bean
public VelocityConfigurer velocityConfigurer() {
VelocityConfigurer vc = new VelocityConfigurer();
vc.setResourceLoaderPath("/WEB-INF/pages/");
return vc;
}
#Bean
public VelocityViewResolver viewResolver(Environment env) {
VelocityViewResolver vvr = new VelocityViewResolver();
vvr.setCache(env.getRequiredProperty("velocity.cache", Boolean.class)); // TODO enable cache for prod
vvr.setPrefix("");
vvr.setSuffix(".vm");
vvr.setToolboxConfigLocation("/WEB-INF/velocity-toolbox.xml");
vvr.setExposeSpringMacroHelpers(true);
return vvr;
}
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:i18n/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Bean
public CookieLocaleResolver localeResolver() {
CookieLocaleResolver localResolver = new CookieLocaleResolver();
localResolver.setDefaultLocale(Locale.ENGLISH);
localResolver.setCookieName("lang");
localResolver.setCookieMaxAge(CACHE_1_YEAR);
return localResolver;
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang");
return interceptor;
}
/*
* #see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addInterceptors(org.springframework.web.servlet.config.annotation.InterceptorRegistry)
*/
#Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
registry.addInterceptor(localeChangeInterceptor());
}
/*
* #see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addResourceHandlers(org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry)
*/
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
VersionResourceResolver versionResourceResolver = new VersionResourceResolver().addVersionStrategy(new ContentVersionStrategy(), "/**");
registry.addResourceHandler("/css/**")
.addResourceLocations("/css/")
.setCachePeriod(CACHE_1_YEAR)
.resourceChain(true)
.addResolver(versionResourceResolver);
registry.addResourceHandler("/js/**")
.addResourceLocations("/js/")
.setCachePeriod(CACHE_1_YEAR)
.resourceChain(true)
.addResolver(versionResourceResolver);
// registry.addResourceHandler("/css/**").addResourceLocations("/css/");
// registry.addResourceHandler("/js/**").addResourceLocations("/js/");
}
}
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>My App</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
<build.timestamp>${maven.build.timestamp}</build.timestamp>
<spring.version>4.1.2.RELEASE</spring.version>
<jackson.version>2.2.3</jackson.version>
<wro.version>1.6.3</wro.version> <!-- Was unable to get to work with version 1.7.8 -->
</properties>
<dependencies>
<!-- ********** J2EE ********** -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.1</version>
</dependency>
<!-- ********** Spring ********** -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- ********** Web Optimization ********** -->
<dependency>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-core</artifactId>
<version>${wro.version}</version>
</dependency>
<dependency>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-extensions</artifactId>
<version>${wro.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.28</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.tuckey</groupId>
<artifactId>urlrewritefilter</artifactId>
<version>4.0.3</version>
</dependency>
<!-- ********** Templating ********** -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-tools</artifactId>
<version>2.0</version>
</dependency>
<!-- ********** CSV ********** -->
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.3</version>
</dependency>
<!-- ********** Dozer ********** -->
<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
<version>5.5.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- ********** Database ********** -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>12.1.0.1.0</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- ********** Logging ********** -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- ********** Testing ********** -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

Spring Data Rest PagingAndSortingRepository AbstractMethodError (RepositoryFactorySupport)

I'm trying to buil an Rest Api using Spring Data Rest, after to change my pom.xml many times to find the compatible dependencies to my project, I have this problem now:
java.lang.AbstractMethodError: org.springframework.data.repository.core.support.RepositoryFactorySupport.getTargetRepository(Lorg/springframework/data/repository/core/RepositoryInformation;)Ljava/lang/Object;
Once upon a time ...
I have a Java Config Web App, my JPAConfig has these annotations
#Configuration
//#EnableJpaRepositories("com.protect.inf.jpa.repositories")
#EnableJpaRepositories
#EnableTransactionManagement
public class JPAConfig { ... }
See the #EnableJpaRepositories annotation, if i don´t set the package name where are my Repositories class, the application starts fine, but when I make the request to the api, the response looks like this:
{
_links: {
profile: {
href: "http://localhost:8080/protect-inf-01/api/profile"
}-
}-
}
It doesn´t expose my Repos url. My Repos classes looks like this
#RestResource(path = "users", rel = "users")
public interface UsuariosRepository extends PagingAndSortingRepository<Usuarios, Integer>{
Usuarios findByEmail(String email);
}
Then ...
When I set the package name to the #EnableRepositories annotation #EnableJpaRepositories("com.protect.inf.jpa.repositories") the applications start fails with this error:
Error creating bean with name 'cuentasRepository': Invocation of init method failed; nested exception is java.lang.AbstractMethodError: org.springframework.data.repository.core.support.RepositoryFactorySupport.getTargetRepository(Lorg/springframework/data/repository/core/RepositoryInformation;)Ljava/lang/Object;
I think that is a dependencies problem in my Maven, i'm not really sure.
Here is my pom.xm
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>protect-inf-01</groupId>
<artifactId>protect-inf-01</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>protect-inf-01 Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<org.aspectj-version>1.6.10</org.aspectj-version>
<jackson.version>1.9.13</jackson.version>
<hibernate.validator.version>4.2.0.Final</hibernate.validator.version>
<org.springframework-version>4.1.7.RELEASE</org.springframework-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<repositories>
<repository>
<id>spring-milestones</id>
<url>http://repo.spring.io/libs-milestone/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
<version>2.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.11.0.RC1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.8.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.1.RELEASE</version>
</dependency>
<!-- MYSQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.2.6.Final</version>
</dependency>
<!-- SERVLET -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>protect-inf-01</finalName>
</build>
</project>
This is my WebAppInitializer class
package com.protect.inf.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{JPAConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfiguration.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
This is my WebConfiguration class
package com.protect.inf.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
#Configuration
public class WebConfiguration extends RepositoryRestMvcConfiguration{
#Override
public RepositoryRestConfiguration config() {
RepositoryRestConfiguration config = super.config();
config.setBasePath("/api");
return config;
}
}
Any help is welcome, thanks!
SOLVED
Deleting the spring-data-commons and changing the spring-data-jpa version to 1.9.0.RELEASE like #peeskillet said now works fine!
Comment the spring-data-commons dependency
<!-- <dependency> -->
<!-- <groupId>org.springframework.data</groupId> -->
<!-- <artifactId>spring-data-commons</artifactId> -->
<!-- <version>1.11.0.RC1</version> -->
<!-- </dependency> -->
Change the spring-data-jpa version
<!-- <dependency> -->
<!-- <groupId>org.springframework.data</groupId> -->
<!-- <artifactId>spring-data-jpa</artifactId> -->
<!-- <version>1.8.2.RELEASE</version> -->
<!-- </dependency> -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
Thanks peeskillet!
Get rid of spring-data-commons and change spring-data-jpa version to 1.9.0.RELEASE.
Both spring-data-rest-webmvc and spring-data-jpa already depend on spring-data-commons. But you need to make sure that they both depend on the same version. s-d-rest-webmvc-2.4.0 depends on s-d-commons-1.11.0 while s-d-jpa-1.8.2 depends on s-d-commons-1.10.2. And that's the difference. s-d-jpa-1.9.0 depends on s-d-commons-1.11.0.

Categories