I'm writing a jpa repostory example and I'm getting a runtime exception of type UnsatisfiedDependencyException.
Here is my program:
#Configuration
#EnableJpaRepositories(basePackageClasses = { PersonRepository.class, ProfessionRepository.class})
#ComponentScan( basePackageClasses =MyService.class)
public class SpringDataJpa {
public static void main( String[] args ) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringDataJpa.class);
service myService = applicationContext.getBean(MyService.class);
}
}
The service interface:
public interface service {
void add( Person person );
List<Person> getListOfPersons();
}
The implementation that throw the exception:
#Service
public class MyService implements service {
#Autowired
PersonRepository personRepository;
#Override
public void add( Person person ){
System.out.println("saved");
}
#Override
public List<Person> getListOfPersons() {
return null;
}
}
The repositories:
#Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
}
#Repository
public interface ProfessionRepository extends JpaRepository<Profession, Integer> {
}
The exception i'm getting:
Exception in thread "main"
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'myService': Unsatisfied dependency
expressed through field 'personRepository'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'personRepository': Post-processing of merged
bean definition failed; nested exception is
java.lang.NoClassDefFoundError: javax/persistence/SynchronizationType
As I checked this discussion, I added the proposed dependencies. My dependencies in the pom.xml file:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
How to solve this error?
My second question is: should we use #EnableJpaRepositories if we use Spring Boot?
a datasource and an entityManagerFactory beans were missing.
To solve my problem i added the followed code in my configuration class:
#Bean
public DataSource firstDataSource (){
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
driverManagerDataSource.setUrl("jdbc:mysql://localhost:3306/ride_tracker?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC");
driverManagerDataSource.setUsername("root");
driverManagerDataSource.setPassword("password");
return driverManagerDataSource;
}
#Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory( DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactoryBean.setPackagesToScan("data");
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
entityManagerFactoryBean.setJpaProperties(jpaProperties);
return entityManagerFactoryBean;
}
You can try the following version, SynchronizationType is available since 2.1.
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
Related
I am trying to write an integration test for a spring boot JPA application using h2 database. Somehow TestEntityManager is not getting created. I tried look for some help on the forum but could not find any relevant information.
Appreciate if anybody can help or provide some direction.
Thanks.
My code is as follows:
Repository:
#Repository
public interface ConfigRepository extends JpaRepository<Config, Long> {
Config findByKey(ConfigKey configKey);
}
Configuration:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(entityManagerFactoryRef = "testEntityManagerFactory",
transactionManagerRef = "testTransactionManager",
basePackages = "com.abc.xyz.business.repository")
public class TestPersistenceConfig {
private static final String TEST_PERSISTENCE_UNIT = "emTestPersistenceUnit";
#Bean(name = "testEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws SQLException {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan(new String[] { "nl.rabobank.rom.exception.manager.rom.em.business.domain" });
entityManagerFactoryBean.setPersistenceUnitName(TEST_PERSISTENCE_UNIT);
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
entityManagerFactoryBean.setJpaProperties(additionalProperties());
return entityManagerFactoryBean;
}
#Bean
#Profile("test")
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1");
dataSource.setUsername("sa");
dataSource.setPassword("sa");
return dataSource;
}
#Bean(name = "testTransactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
private Properties additionalProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("em.hibernate.hbm2ddl.auto", "none");
hibernateProperties.setProperty("hibernate.show_sql", "true");
hibernateProperties.setProperty("hibernate.format_sql", "true");
hibernateProperties.setProperty("em.hibernate.naming.physical-strategy", "org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");
hibernateProperties.setProperty("em.properties.hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
return hibernateProperties;
}
}
Test:
#RunWith(SpringRunner.class)
#DataJpaTest
#ActiveProfiles("test")
#ContextConfiguration(classes = {TestPersistenceConfig.class})
public class ConfigRepositoryTest {
#Autowired
private TestEntityManager entityManagerFactory;
#Autowired
private ConfigRepository configRepository;
#Test
public void test1() {
Config config =
configRepository.findByKey(ConfigKey.PURGE_DATE_RETENTION_CALENDAR_TYPE);
assertNotNull(config);
}
}
POM.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<!-- To run tests on IDE such as Eclipse, Intellij -->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Stacktrace:
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'TestExceptionHandlerEntityManagerFactory' defined in nl.rabobank.rom.exception.manager.rom.em.business.TestPersistenceConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.IllegalArgumentException: No visible constructors in class org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean
...
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.IllegalArgumentException: No visible constructors in class org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579)
... 42 more
Caused by: java.lang.IllegalArgumentException: No visible constructors in class org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean
at org.springframework.cglib.proxy.Enhancer.filterConstructors(Enhancer.java:666)
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:567)
If you have a production type database in tests you must add #AutoConfigureTestDatabase(replace=Replace.NONE) to Test classes.
Just add above annotation to ConfigRepositoryTest class to resolve your problem.
#RunWith(SpringRunner.class)
#DataJpaTest
#ActiveProfiles("test")
#ContextConfiguration(classes = {TestPersistenceConfig.class})
#AutoConfigureTestDatabase(replace=Replace.NONE)
public class ConfigRepositoryTest {
...
}
I am trying to use HibernateValidator in SpringMVC tests, but I can't get it to work.
I added it to classpath along with el and validation api deps. In WebMvcConfigurerAdapter overrided getValidator:
#Override
public Validator getValidator() {
LocalValidatorFactoryBean validatorFactoryBean = new LocalValidatorFactoryBean();
validatorFactoryBean.setProviderClass(HibernateValidator.class);
return validatorFactoryBean;
}
Binding result just doesn't have errors that should be produced by hibernate validator, and DTO has null values.
However javax validation annotations works.
What I should to do to make hibernate validator work in
spring mvc tests (with junit runner)?
UPDATE:
Here is how my test looks like:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(classes = {AppConfig.class, WebConfig.class})
public class UserControllerTest {
#Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
#Before
public void before() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
#Test
public void RegisterUser_ValidData_UserRegistered() throws Exception {
ObjectMapper mapper = new ObjectMapper();
UserRegistrationDTO dto = new UserRegistrationDTO();
String payload = mapper.writeValueAsString(dto);
RequestBuilder request = MockMvcRequestBuilders
.post(URI.create("/users/register"))
.contentType(MediaType.APPLICATION_JSON)
.content(payload);
this.mockMvc.perform(request).andDo...
}
}
Dependencies:
<properties>
<spring.version>4.3.9.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
Controller:
#RestController
#RequestMapping(path = "users", produces = "application/json", consumes = "application/json")
public class UserController {
#PostMapping(path = "/register")
public ResponseEntity register(#Valid #RequestBody UserRegistrationDTO registration) {
return ResponseEntity.ok("registered");
}
}
LocalContainerEntityManagerFactoryBean not created context faild
Below is the error:
java.lang.IllegalStateException: Failed to load ApplicationContext at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'entityManagerFactory' defined in
com.test.spring.AppConfig: Invocation of init method failed; nested
exception is java.lang.NoSuchMethodError:
javax.persistence.spi.PersistenceUnitInfo.getSharedCacheMode()Ljavax/persistence/SharedCacheMode;
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
and code:
#ComponentScan
#Configuration
#EnableJpaRepositories("com.test.spring.repository")
public class AppConfig {
#Value("${jdbc.driverClassName}")
private String jdbcDriverClassName;
#Value("${jdbc.url}")
private String jdbcURL;
#Value("${jdbc.username}")
private String jdbcUserName;
#Value("${jdbc.password}")
private String jdbcPassword;
public static PropertySourcesPlaceholderConfigurer getPropertiesFile(String profileName) {
PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
String path = new StringJoiner("").add("application_dev")/*.add(profileName)*/.add(".properties").toString();
Resource location = new ClassPathResource(path);
pspc.setLocations(location);
return pspc;
}
#Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(jdbcDriverClassName);
dataSource.setUrl(jdbcURL);
dataSource.setUsername(jdbcUserName);
dataSource.setPassword(jdbcPassword);
return dataSource;
}
#Bean(name="entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setPackagesToScan("com.test.spring.domain");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
factoryBean.setJpaVendorAdapter(vendorAdapter);
Properties props = new Properties();
props.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
props.put("hibernate.hbm2ddl.auto", "create");
factoryBean.setJpaProperties(props);
return factoryBean;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
//Here is the pom file
<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.test.spring</groupId>
<artifactId>EntityExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
Since you are missing hibernate classes and libraries, try to extend your pom dependency with something like this:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.5.0</version>
</dependency>
I have a problem. I'm using Spring4 and i want to add a configuration to be able to use spring data couchbase and i have an error :
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: file
[/home/charlie/Desktop/Ultimate
Projects/novare_dashboard/novare-project-dashboard/target/classes/hk/com/novare/dashboard/configuration/CouchbaseConfig.class];
nested exception is java.lang.annotation.AnnotationFormatError:
Invalid default: public abstract java.lang.Class
org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories.repositoryBaseClass()
at
org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:303)
Here is my code:
CouchbaseConfig.java
#Configuration
#EnableCouchbaseRepositories
public class CouchbaseConfig extends AbstractCouchbaseConfiguration{
#Override
protected List<String> bootstrapHosts() {
return Collections.singletonList("localhost");
}
#Override
protected String getBucketName() {
return "crud";
}
#Override
protected String getBucketPassword() {
return "password";
}}
WebMvcConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackageClasses = Application.class)
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setPrefix("/WEB-INF/views/");
bean.setSuffix(".jsp");
return bean;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/static/");
}}
POM.XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--H2-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!--couchbase-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.couchbase.client</groupId>
<artifactId>couchbase-client</artifactId>
<version>1.4.9</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.0</version>
</dependency>
<!--JSON-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Can see the error for missing repositoryBaseClass config which is needed to create the repository proxies for your CouchbaseConfig class :-
nested exception is java.lang.annotation.AnnotationFormatError: Invalid default: public abstract java.lang.Class
org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories.repositoryBaseClass() at
Pls specify same as parameter to #EnableCouchbaseRepositories
I just found a solution regarding my error. You must change your spring-data-couchbase version to 1.2.2 and remove the annotation #Repository to your repository.
I'm trying to create a Scheduled task with Spring, but I'm probably not doing something correctly exposing the #Bean in configuration. My code is as follows:
#Configuration
#PropertySource("classpath:hibernate.properties")
#EnableJpaRepositories("org.app.repository")
#ComponentScan("org.app")
#EnableTransactionManagement
#EnableScheduling
public class JpaConfiguration {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN =
"entitymanager.packages.to.scan";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
// will set the provider to 'org.hibernate.ejb.HibernatePersistence'
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
// will set hibernate.show_sql to 'true'
vendorAdapter.setShowSql(true);
// if set to true, will set hibernate.hbm2ddl.auto to 'update'
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean emfBean = new
LocalContainerEntityManagerFactoryBean();
emfBean.setDataSource(dataSource());
emfBean.setJpaVendorAdapter(vendorAdapter);
emfBean.setPersistenceProviderClass(
org.hibernate.jpa.HibernatePersistenceProvider.class);
emfBean.setPackagesToScan(
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
emfBean.setJpaProperties(hibProperties());
return emfBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
return properties;
}
#Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
#Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler ts = new ThreadPoolTaskScheduler();
ts.initialize();
ts.setPoolSize(8);
ts.setWaitForTasksToCompleteOnShutdown(true);
return ts;
}
}
#Component
public class MainBean {
#Autowired
private MyRunnable myRunnable;
#Autowired
private CategoryRepo categoryRepo;
#Autowired
private ThreadPoolTaskScheduler taskScheduler;
public void start() {
//This works
categoryRepo.findAll().forEach(System.out::println);
//this throws an exception
taskScheduler.execute(myRunnable);
//if i use an infinite loop here in order to prevent
//the method from exiting everything works normal
// while(true) {
// Thread.sleep(10000000);
// }
System.out.println("Application Started. . .");
}
}
Category Repo
public interface CategoryRepo extends JpaRepository<Category, String> {
}
Runnable
#Component
public class MyRunnable implements Runnable {
#Autowired
private CategoryRepo categoryRepo;
#Override
public void run() {
try {
List<Category> list = categoryRepo.findAll();
list.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Also if I dont use a scheduler and I just do
myRunnable.run();
it executes normally.
Anyone have an idea what I'm doing wrong, or maybe an alternative way in doing this?
EDIT: My pom.xml dependencies are as follows (Spring is 4.0.2 as you can see in the properties tag):
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<!--Hibernate Dependencies-->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.3.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.3.Final</version>
</dependency>
<!-- Spring Dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</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-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
<!--CGLIB is required to process #Configuration classes-->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<!--Other Dependencies-->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.28</version>
</dependency>
</dependencies>
And Java is 1.8 - also tried with 1.7 and had same results
EDIT:
Apparently I think the issue is that the program is exiting and it leaves the Spring Context. Therefore when the runnable is executed, the thread cant find the entitymanager.
If I use an infinite while loop right before the MainBean exits then everything executes normally
The root cause is
Caused by: java.lang.NoSuchMethodError: org.app.config.JpaConfiguration.setBeanFactory(Lorg/springframework/beans/factory/BeanFactory;)V
A NoSuchMethodError almost always indicates that there is a versioning issue with your build. The application tries to execute a method that was available at compile time, but not at run time. In other words, the classpath at compilation is different than the classpath at run time.
spring-data-jpa version 1.5.1.RELEASE is compiled with Spring 3.2.8, but you're providing Spring libraries of 4.0.2.RELEASE. However, it is built in a way that it will delegate to your project's actual dependencies if those exist. In your current setup, it will use the following
<artifactId>spring-context-support</artifactId>
<artifactId>spring-context</artifactId>
<artifactId>spring-jdbc</artifactId>
<artifactId>spring-orm</artifactId>
<artifactId>spring-tx</artifactId>
with version 4.0.2.RELEASE, but it will use version 3.2.8.RELEASE of
<artifactId>spring-core</artifactId>
<artifactId>spring-beans</artifactId>
These are typically dependencies of spring-context with the same version, but here it seems they get overwritten by spring-data-jpa.
The simplest, but maybe incomplete (depending on the rest of your configuration), is to specifically declare those two dependencies
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
So spring-data-jpa will now delegate to these.
Alternatively, unless you are using some features of Spring 4.0.2.RELEASE, you could get rid of all your other Spring dependencies and only keep spring-data-jpa. It will be responsible for pulling the other Spring 3.2.8.RELEASE libraries.
I havent found any satisfactory answers unfortunately. The only unorthodox solution (in my opinion) I have found is to do an infinite loop that doesnt allow the program to exit as follows:
public void start() {
System.out.println("Application Started. . .");
taskScheduler.scheduleAtFixedRate(myRunnable, Date.from(Instant.now()),
TimeUnit.DAYS.toMillis(1));
while (true) {
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
It seems like a known bug on spring boot or Spring 4.
https://github.com/spring-projects/spring-boot/issues/253
As it seems, the scheduler masks the real problem thrwing this strange error.
In your case, as it just happens with the scheduler, I would try to make a exception breakpoint to find out which kind of exception is being thrown in this case that is being hidden.