Spring Boot, JPA-Hibernate does not translate MySql exceptions to DataAccessException - spring-boot

We have the below configurations for our spring boot application. We are using the hibernate and MySql database.
The problem here is that when we face an java.sql.SQLException in public Entity getXXX(Long xxx), we are not receiving the translated exception by spring. Hibernate translates the underlying exceptions to javax.persistence.PersistenceException hierarchy But we need the spring translation which is the DataAccessException hierarchy.
We have this configuration for our JPA-Hibernate:
package ....;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#RequiredArgsConstructor
#Configuration
#EnableJpaRepositories
#EnableTransactionManagement
public class JpaConfig {
#Value("${spring.profiles.active}")
private String activeProfile;
private final LocalContainerEntityManagerFactoryBean emf;
#Bean
public PlatformTransactionManager txManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(emf.getObject());
txManager.setJpaDialect(emf.getJpaDialect());
txManager.setRollbackOnCommitFailure(true);
txManager.setPersistenceUnitName(activeProfile);
return txManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
With this properties:
spring.datasource.url=jdbc:mysql://xxx
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.hikari.maximum-pool-size=20
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.data.jpa.repositories.bootstrap_mode=lazy
spring.datasource.name=${xxx}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.pool-name=${xxx}
spring.datasource.hikari.auto-commit=false
spring.datasource.hikari.max-lifetime=600000
spring.datasource.hikari.connection-timeout=600000
spring.datasource.hikari.validation-timeout=600000
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.open-in-view=false
spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.connection.autocommit=false
spring.jpa.properties.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.format_sql=false
spring.jpa.properties.hibernate.use_sql_comments=false
And when we execute our JPA queries using the below:
#Repository
public class XxxxxDaoImpl implements XxxxxDao {
#Override
public Entity getXXX(Long xxx) {
try {
return entityManager.createQuery("SELECT c FROM xxx c " +
"INNER JOIN c.xx e ON e.id = :xxx " +
"INNER JOIN FETCH xxx i", xxx.class)
.setParameter("xxx", xxx).getSingleResult();
} catch(DataAccessException e) {
// It will not enter the catch because the type of exception is of javax.persistence.PersistenceException!
log.error("DAO: exception in querying xxx for xxx: {} => {}", xxx, e.getMessage());
return null;
}
}
}
So When there is no entity for this query, it always raise javax.persistence.NoResultException which is the sub-class of javax.persistence.PersistenceException and not the org.springframework.dao.DataAccessException.
In the log I can see these lines:
INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization:376: Bean 'spring.sql.init-org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties' of type [org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization:376: Bean 'dataSourceScriptDatabaseInitializer' of type [org.springframework.boot.autoconfigure.sql.init.SqlDataSourceScriptDatabaseInitializer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization:376: Bean 'spring.jpa-org.springframework.boot.autoconfigure.orm.jpa.JpaProperties' of type [org.springframework.boot.autoconfigure.orm.jpa.JpaProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization:376: Bean 'spring.jpa.hibernate-org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties' of type [org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization:376: Bean 'org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration$HikariPoolDataSourceMetadataProviderConfiguration' of type [org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration$HikariPoolDataSourceMetadataProviderConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization:376: Bean 'hikariPoolDataSourceMetadataProvider' of type [org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration$HikariPoolDataSourceMetadataProviderConfiguration$$Lambda$449/0x00000008403ab840] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization:376: Bean 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration' of type [org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization:376: Bean 'jpaVendorAdapter' of type [org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker.postProcessAfterInitialization:376: Bean 'entityManagerFactoryBuilder' of type [org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
It says that Bean 'jpaVendorAdapter' of type [org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter] is not eligible for getting processed by all BeanPostProcessors so might it be the reason for this? Because I know that this exception translation is a kind of post processor.
I have searched for days in jpa, hibernate documentation and tried stackoverflow but no result! We need DataAccessException which is the Spring translation.
Can someone point me to the right direction?

Related

Programmatically register EmbeddedDatabaseAutoConfiguration bean inside BeanDefinitionRegistryPostProcessor to use embedded Postgres

I am registering a bean for EmbeddedDatabaseAutoConfiguration but it is never acted upon.
Is something missing for it to be processed in the same manner as if the annotation was present? I'd like to not have to declare the EmbeddedDatabaseAutoConfiguration annotation on the test class.
The BeanDefinitionRegistryPostProcessor implementation:
import io.zonky.test.db.config.EmbeddedDatabaseAutoConfiguration;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
#Configuration
public class MyFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
#Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("postProcessBeanDefinitionRegistry before");
try {
registry.getBeanDefinition("io.zonky.test.db.config.EmbeddedDatabaseAutoConfiguration");
} catch (Exception e) {
System.out.println("Annotation missing, try programmatically register ..");
RootBeanDefinition beanDefinition = new RootBeanDefinition(EmbeddedDatabaseAutoConfiguration.class);
beanDefinition.setScope("singleton");
MutablePropertyValues values = new MutablePropertyValues();
values.addPropertyValue("zonky.test.database.provider", "zonky");
beanDefinition.setPropertyValues(values);
registry.registerBeanDefinition("io.zonky.test.db.config.EmbeddedDatabaseAutoConfiguration", beanDefinition);
}
System.out.println("postProcessBeanDefinitionRegistry after");
}
#Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
#Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("postProcessBeanFactory before");
beanFactory.getBeanDefinition("io.zonky.test.db.config.EmbeddedDatabaseAutoConfiguration");
System.out.println("postProcessBeanFactory after");
}
}
Current test class:
#ActiveProfiles("test")
#SpringBootTest
// I'd like `AutoConfigureEmbeddedDatabase` to be programmatically enabled for all test classes,
// rather than requiring declarative annotation
// If the annotation is provided, the test works fine
//#AutoConfigureEmbeddedDatabase(provider = AutoConfigureEmbeddedDatabase.DatabaseProvider.ZONKY)
public class ItemServiceTest {
#Autowired private ItemService itemService;
#Test
void test_Create() {
String text = "Initial value: " + new Date();
ItemDTO itemDTO = new ItemDTO();
itemDTO.setText(text);
itemDTO = itemService.create(itemDTO);
// assert something with itemDTO ..
}
}
In the console logs below, EmbeddedDatabaseAutoConfiguration is not acted upon in the programmatic use case. Instead processing assumes a non-embedded db is present and starts initializing.
Console output when annotation is declared on test class:
Finished Spring Data repository scanning in 35 ms. Found 1 JPA repository interfaces. []
postProcessBeanDefinitionRegistry before
Generic bean: class [io.zonky.test.db.config.EmbeddedDatabaseAutoConfiguration]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
postProcessBeanDefinitionRegistry after
Replacing 'dataSource' DataSource bean with embedded version []
postProcessBeanFactory before
postProcessBeanFactory after
trationDelegate$BeanPostProcessorChecker : Bean 'io.zonky.test.db.config.EmbeddedDatabaseAutoConfiguration' of type [io.zonky.test.db.config.EmbeddedDatabaseAutoConfiguration$$EnhancerBySpringCGLIB$$c4933b50] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) []
o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] []
org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.14.Final []
o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} []
i.z.t.d.p.embedded.EmbeddedPostgres : Detected a Darwin aarch64 system []
Console output when annotation is not declared on test class and programatically trying to create the Spring bean:
Finished Spring Data repository scanning in 31 ms. Found 1 JPA repository interfaces. []
postProcessBeanDefinitionRegistry before
postProcessBeanDefinitionRegistry after
o.s.c.a.ConfigurationClassPostProcessor : Cannot enhance #Configuration bean definition 'myFactoryPostProcessor' since its singleton instance has been created too early. The typical cause is a non-static #Bean method with a BeanDefinitionRegistryPostProcessor return type: Consider declaring such methods as 'static'. []
postProcessBeanFactory before
postProcessBeanFactory after
o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] []
org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.14.Final []
o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} []
com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... []
com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during pool initialization. []
Dependencies in build.gradle.kts:
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-test")
implementation("io.zonky.test:embedded-postgres:2.0.2")
implementation("io.zonky.test:embedded-database-spring-test:2.2.0")

A component required a bean named 'entityManagerFactory' that could not be found

I am doing a project in SpringBoot using Postgres and restful approach. My application is failing to start.I am new to this.Please help me with this problem.Below is my code:
Error
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.2-SNAPSHOT)
2020-12-30 21:42:08.397 INFO 7284 --- [ restartedMain] com.cg.pps.SpringRestApplication : Starting SpringRestApplication using Java 15.0.1 on DESKTOP-7ODO40V with PID 7284 (D:\E drive\studymaterial\Sprint2\PersonalityPredictionSystemMus\target\classes started by BST in D:\E drive\studymaterial\Sprint2\PersonalityPredictionSystemMus)
2020-12-30 21:42:08.410 INFO 7284 --- [ restartedMain] com.cg.pps.SpringRestApplication : No active profile set, falling back to default profiles: default
2020-12-30 21:42:08.677 INFO 7284 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2020-12-30 21:42:08.678 INFO 7284 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2020-12-30 21:42:10.722 INFO 7284 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2020-12-30 21:42:10.921 INFO 7284 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 165 ms. Found 1 JPA repository interfaces.
2020-12-30 21:42:12.831 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.hateoas.config.HateoasConfiguration' of type [org.springframework.hateoas.config.HateoasConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:12.848 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'relProviderPluginRegistry' of type [org.springframework.plugin.core.support.PluginRegistryFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:12.896 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'relProviderPluginRegistry' of type [org.springframework.plugin.core.OrderAwarePluginRegistry] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:12.907 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean '_relProvider' of type [org.springframework.hateoas.server.core.DelegatingLinkRelationProvider] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:12.933 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'messageResolver' of type [org.springframework.hateoas.mediatype.MessageSourceResolver] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:12.936 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.data.web.config.SpringDataJacksonConfiguration' of type [org.springframework.data.web.config.SpringDataJacksonConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:12.952 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'jacksonGeoModule' of type [org.springframework.data.geo.GeoModule] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.002 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration' of type [org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.011 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.018 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.097 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'spring.jackson-org.springframework.boot.autoconfigure.jackson.JacksonProperties' of type [org.springframework.boot.autoconfigure.jackson.JacksonProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.100 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'standardJacksonObjectMapperBuilderCustomizer' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration$StandardJackson2ObjectMapperBuilderCustomizer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.106 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$ParameterNamesModuleConfiguration' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$ParameterNamesModuleConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.112 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'parameterNamesModule' of type [com.fasterxml.jackson.module.paramnames.ParameterNamesModule] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.114 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.137 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'jsonComponentModule' of type [org.springframework.boot.jackson.JsonComponentModule] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.145 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'jacksonObjectMapperBuilder' of type [org.springframework.http.converter.json.Jackson2ObjectMapperBuilder] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.165 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'spring.data.rest-org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties' of type [org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.166 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'springBootRepositoryRestConfigurer' of type [org.springframework.boot.autoconfigure.data.rest.SpringBootRepositoryRestConfigurer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.169 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'configurerDelegate' of type [org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerDelegate] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.185 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfiguration' of type [org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.204 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'stringHttpMessageConverter' of type [org.springframework.http.converter.StringHttpMessageConverter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.207 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfiguration' of type [org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.210 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfiguration' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.224 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'jacksonObjectMapperBuilder' of type [org.springframework.http.converter.json.Jackson2ObjectMapperBuilder] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.279 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'jacksonObjectMapper' of type [com.fasterxml.jackson.databind.ObjectMapper] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.284 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'mappingJackson2HttpMessageConverter' of type [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:13.286 INFO 7284 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration' of type [org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-12-30 21:42:14.804 INFO 7284 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8082 (http)
2020-12-30 21:42:14.840 INFO 7284 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-12-30 21:42:14.841 INFO 7284 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.41]
2020-12-30 21:42:15.409 INFO 7284 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-12-30 21:42:15.410 INFO 7284 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 6731 ms
2020-12-30 21:42:16.076 WARN 7284 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cvRepo' defined in com.cg.pps.repository.CvRepo defined in #EnableJpaRepositories declared on SpringRestApplication: Cannot create inner bean '(inner bean)#2fe84e0e' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#2fe84e0e': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
2020-12-30 21:42:16.089 INFO 7284 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2020-12-30 21:42:16.173 INFO 7284 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-12-30 21:42:16.308 ERROR 7284 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean named 'entityManagerFactory' that could not be found.
Action:
Consider defining a bean named 'entityManagerFactory' in your configuration.
App.java
package com.cg.pps;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
#EnableJpaRepositories(basePackages = {"com.cg.pps.repository"})
#SpringBootApplication
public class SpringRestApplication {
public static void main(String[] args) {
SpringApplication.run(SpringRestApplication.class, args);
}
}
Controller
package com.cg.pps.controller;
import java.util.List;
import com.cg.pps.model.*;
import com.cg.pps.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController()
#RequestMapping("/candidatecv")
public class CandidateCvController {
#Autowired
private CandidateCvs candidatecvs;
#GetMapping("/getall")
public List<CandidateCv> getAllPeople() {
return candidatecvs.getAllCandiateCv();
}
#GetMapping("/get/{id}")
public CandidateCv getCandidateCvByEmail(#PathVariable String email) {
return candidatecvs.getCandidateCvByEmail(email);
}
#PostMapping("/create")
public String createCandidateCv(#PathVariable CandidateCv cv) {
if(cv != null) {
candidatecvs.createCandidateCv(cv);
return "Cv Added";
} else {
return "Request does not contain a body";
}
}
}
model
package com.cg.pps.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
//import the job package
#Entity
#Table(name="cand_info")
public class CandidateCv implements Serializable {
#Id
#Column(name="CandidateName", length=20)
private String CandidateName;
#Column(name="Email",length=12 ,unique=true)
private String email;
#Column(name="Phoneno",length=10)
private int phoneno;
#Column(name="Qualification",length=10)
private String qualification;
#Column(name="Experience",length=2)
private int exp;
#Column(name="Skill",length=10)
private String skill;
public CandidateCv() {
// TODO Auto-generated constructor stub
}
public CandidateCv(String candidateName, String email, int phoneno, String qualification, int exp, String skill) {
super();
CandidateName = candidateName;
this.email = email;
this.phoneno = phoneno;
this.qualification = qualification;
this.exp = exp;
this.skill = skill;
}
public String getCandidateName() {
return CandidateName;
}
public void setCandidateName(String candidateName) {
CandidateName = candidateName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getPhoneno() {
return phoneno;
}
public void setPhoneno(int phoneno) {
this.phoneno = phoneno;
}
public String getQualification() {
return qualification;
}
public void setQualification(String qualification) {
this.qualification = qualification;
}
public int getExp() {
return exp;
}
public void setExp(int exp) {
this.exp = exp;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
}
Repository
package com.cg.pps.repository;
import com.cg.pps.model.CandidateCv;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface CvRepo extends CrudRepository<CandidateCv, Long> {
public boolean existByEmail(String email);
public CandidateCv findByEmail(String email);
}
ServiceInterface
package com.cg.pps.service;
import com.cg.pps.model.*;
import java.util.List;
import org.springframework.stereotype.Service;
public interface CandidateCvs {
List<CandidateCv> getAllCandiateCv();
CandidateCv getCandidateCvByEmail(String email);
String createCandidateCv(CandidateCv e);
}
**Service Implementation**
package com.cg.pps.service;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.cg.pps.repository.CvRepo;
import com.cg.pps.model.CandidateCv;
#Transactional
#Service
public class CandidateCvImpl implements CandidateCvs {
private CvRepo repository;
#Override
public List<CandidateCv> getAllCandiateCv() {
return (List<CandidateCv>)repository.findAll();
}
#Override
public String createCandidateCv(CandidateCv e) {
String id=e.getEmail();
if(repository.existByEmail(id))
{
return "Candidate Cv already exists";
}
else {
repository.save(e);
return "Employee data successfully saved";
}
}
#Override
public CandidateCv getCandidateCvByEmail(String email) {
CandidateCv cv= new CandidateCv();
String id=cv.getEmail();
if(repository.existByEmail(id)) {
return repository.findByEmail(email);
}
else
{
return null;
}
}
}
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<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-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Please review my above codes and let me know what I am doing wrong.

Karate: How to configure karate mock-servlet using a YAML file instead of application.properties? [duplicate]

This question already has an answer here:
Karate Spring Integration
(1 answer)
Closed 1 year ago.
We have a Spring Boot project which uses an application.yml file to configure the spring context for things like datasource, rabbitmq etc.
The YAML file can be loaded in the karate-config.js to pick-up the baseUrl and that works fine.
function fn() {
var env = karate.env; // get system property 'karate.env'
karate.log('karate.env system property was:', env);
if (!env) {
env = 'dev';
}
karate.log('karate environment set to:', env);
var config = karate.read('classpath:application.yml');
karate.log('baseUrl configured for API tests: '+config.baseUrl)
if (env == 'dev') {
var Factory = Java.type('MockSpringMvcServlet');
karate.configure('httpClientInstance', Factory.getMock());
//var result = karate.callSingle('classpath:demo/headers/common-noheaders.feature', config);
} else if (env == 'stg') {
// customize
} else if (env == 'prod') {
// customize
}
return config;
}
The Mock Spring MVC servlet class taken from the karate mock servlet demo github project:
/**
* #author pthomas3
*/
public class MockSpringMvcServlet extends MockHttpClient {
private final Servlet servlet;
private final ServletContext servletContext;
public MockSpringMvcServlet(Servlet servlet, ServletContext servletContext) {
this.servlet = servlet;
this.servletContext = servletContext;
}
#Override
protected Servlet getServlet(HttpRequestBuilder request) {
return servlet;
}
#Override
protected ServletContext getServletContext() {
return servletContext;
}
private static final ServletContext SERVLET_CONTEXT = new MockServletContext();
private static final Servlet SERVLET;
static {
SERVLET = initServlet();
}
private static Servlet initServlet() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(MockConfig.class);
context.setServletContext(SERVLET_CONTEXT);
DispatcherServlet servlet = new DispatcherServlet(context);
ServletConfig servletConfig = new MockServletConfig();
try {
servlet.init(servletConfig);
} catch (Exception e) {
throw new RuntimeException(e);
}
return servlet;
}
public static MockSpringMvcServlet getMock() {
return new MockSpringMvcServlet(SERVLET, SERVLET_CONTEXT);
}
}
However, the MockConfig.class fails on the EnableAutoConfiguration annotation:
#Configuration
#EnableAutoConfiguration
// #PropertySource("classpath:application.yml") // only for key/value pair .properties files and not YAML
public class MockConfig {
// Global Exception Handler ...
// Services ...
// Controllers ...
#Bean
public NumbersAPI numbersAPI() {
return new NumbersAPI();
}
}
The exception is:
2019-04-23 15:13:21.297 INFO --- [ main] com.intuit.karate : karate.env system property was: null
2019-04-23 15:13:21.306 INFO --- [ main] com.intuit.karate : karate environment set to: dev
2019-04-23 15:13:21.429 INFO --- [ main] com.intuit.karate : baseUrl configured for API tests: http://localhost:50000
2019-04-23 15:13:21.469 INFO --- [ main] o.s.mock.web.MockServletContext : Initializing Spring FrameworkServlet ''
2019-04-23 15:13:21.469 INFO --- [ main] o.s.web.servlet.DispatcherServlet : FrameworkServlet '': initialization started
2019-04-23 15:13:21.496 INFO --- [ main] .s.AnnotationConfigWebApplicationContext : Refreshing WebApplicationContext for namespace '-servlet': startup date [Tue Apr 23 15:13:21 EDT 2019]; root of context hierarchy
2019-04-23 15:13:21.535 INFO --- [ main] .s.AnnotationConfigWebApplicationContext : Registering annotated classes: [class MockConfig]
2019-04-23 15:13:22.215 INFO --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Dbcp2; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Dbcp2.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Tomcat; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]]
2019-04-23 15:13:22.330 WARN --- [ main] o.s.b.a.AutoConfigurationPackages : #EnableAutoConfiguration was declared on a class in the default package. Automatic #Repository and #Entity scanning is not enabled.
2019-04-23 15:13:22.714 INFO --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration' of type [org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration$$EnhancerBySpringCGLIB$$cafe2407] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-04-23 15:13:23.212 WARN --- [ main] .s.AnnotationConfigWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
2019-04-23 15:13:23.215 ERROR --- [ main] o.s.web.servlet.DispatcherServlet : Context initialization failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
I've used the documentation from the karate mock-servlet github project as guidance to make other karate tests work successfully, but I don't know how to configure the spring context for our karate tests using an application YAML file.
The #PropertySource only supports properties files as you already found out.
Have a look at the following SOF question:
Spring #PropertySource using YAML
Hope this helps.
I was able to get the application.yml file to be respected and loaded by Spring by making the following changes:
Add a YamlPropertySourceFactory util class to the test package:
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class YamlPropertySourceFactory implements PropertySourceFactory {
#Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
Properties propertiesFromYaml = loadYamlIntoProperties(resource);
String sourceName = name != null ? name : resource.getResource().getFilename();
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
}
private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
try {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
return factory.getObject();
} catch (IllegalStateException e) {
// for ignoreResourceNotFound
Throwable cause = e.getCause();
if (cause instanceof FileNotFoundException)
throw (FileNotFoundException) e.getCause();
throw e;
}
}
}
and
Referencing the above in the #PropertySource annotation in the MockConfig class as follows:
#Configuration
#EnableAutoConfiguration
#PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:application.yml")
public class MockConfig {
// Global Exception Handler ...
#Bean
public ExampleAPIExceptionHandler exampleAPIExceptionHandler() {
return new ExampleAPIExceptionHandler();
}
// Services ...
// Controllers ...
#Bean
public NumbersAPI numbersAPI() {
return new NumbersAPI();
}
}
The Spring context loads and all karate tests pass.
If there is a simpler way to load a YAML file as a Spring context using Karate, then please post it. For now, this will work.
Reference: Use #PropertySource with YAML files

Error creating bean with name 'batchConfigurer' in Spring Boot

I have a spring batch written using Spring boot. My batch only reads from MongoDB and prints the record.
I'm not using any SQL DB nor have any dependencies declared in project but While running it I'm getting below exception:
s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'batchConfigurer' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchConfigurerConfiguration$JdbcBatchConfiguration.class]: Unsatisfied dependency expressed through method 'batchConfigurer' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-06-01 10:43:39.485 ERROR 15104 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 1 of method batchConfigurer in org.springframework.boot.autoconfigure.batch.BatchConfigurerConfiguration$JdbcBatchConfiguration required a bean of type 'javax.sql.DataSource' that could not be found.
- Bean method 'dataSource' not loaded because #ConditionalOnProperty (spring.datasource.jndi-name) did not find property 'jndi-name'
- Bean method 'dataSource' not loaded because #ConditionalOnClass did not find required class 'javax.transaction.TransactionManager'
Action:
Consider revisiting the conditions above or defining a bean of type 'javax.sql.DataSource' in your configuration.
In my pom.xml I've added below dependancies:
spring-boot-starter-batch
spring-boot-starter-data-mongodb
spring-boot-starter-test
spring-batch-test
Here's my batch configuration class:
#Configuration
#EnableBatchProcessing
public class BatchConfig {
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Autowired
private MongoTemplate mongoTemplate;
#Bean
public Job job() throws Exception {
return jobBuilderFactory.get("job1").flow(step1()).end().build();
}
#Bean
public Step step1() throws Exception {
return stepBuilderFactory.get("step1").<BasicDBObject, BasicDBObject>chunk(10).reader(reader())
.writer(writer()).build();
}
#Bean
public ItemReader<BasicDBObject> reader() {
MongoItemReader<BasicDBObject> reader = new MongoItemReader<BasicDBObject>();
reader.setTemplate(mongoTemplate);
reader.setCollection("test");
reader.setQuery("{'status':1}");
reader.setSort(new HashMap<String, Sort.Direction>() {
{
put("_id", Direction.ASC);
}
});
reader.setTargetType((Class<? extends BasicDBObject>) BasicDBObject.class);
return reader;
}
public ItemWriter<BasicDBObject> writer() {
MongoItemWriter<BasicDBObject> writer = new MongoItemWriter<BasicDBObject>();
return writer;
}
}
Here's is my launcher class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class MyBatchApplication {
...
}
Spring Batch requires the use of a relational data store for the job repository. Spring Boot enforces that fact. In order to fix this, you'll need to add an in memory database or create your own BatchConfigurer that uses the Map based repository. For the record, the recommended approach is to add an in memory database (HSQLDB/H2/etc).

Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered

I know this has been asked many time but I could not
find answer for I problem. I am Trying to schedule my spring batch for every 20 second but its getting fail.
QuartzConfiguration.java
#Configuration
public class QuartzConfiguration {
#Autowired
private JobLauncher jobLauncher;
#Autowired
private JobLocator jobLocator;
#Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new JobRegistryBeanPostProcessor();
jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry);
return jobRegistryBeanPostProcessor;
}
#Bean
public JobDetailFactoryBean jobDetailFactoryBean() {
JobDetailFactoryBean jobfactory = new JobDetailFactoryBean();
jobfactory.setJobClass(QuartzJobLauncher.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("jobName", "Test_Job");
map.put("jobLauncher", jobLauncher);
map.put("jobLocator", jobLocator);
jobfactory.setJobDataAsMap(map);
jobfactory.setGroup("group");
jobfactory.setName("job");
return jobfactory;
}
// Job is scheduled after every 20 sec
#Bean
public CronTriggerFactoryBean cronTriggerFactoryBean() {
CronTriggerFactoryBean ctFactory = new CronTriggerFactoryBean();
ctFactory.setJobDetail(jobDetailFactoryBean().getObject());
ctFactory.setStartDelay(3000);
ctFactory.setName("cron_trigger");
ctFactory.setGroup("cron_group");
ctFactory.setCronExpression("0/20 * * * * ?");
return ctFactory;
}
#Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
scheduler.setTriggers(cronTriggerFactoryBean().getObject());
return scheduler;
}
}
QuartzJobLauncher.java
public class QuartzJobLauncher extends QuartzJobBean {
private static final Logger log = LoggerFactory.getLogger(QuartzJobLauncher.class);
private String jobName;
private JobLauncher jobLauncher;
private JobLocator jobLocator;
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public JobLauncher getJobLauncher() {
return jobLauncher;
}
public void setJobLauncher(JobLauncher jobLauncher) {
this.jobLauncher = jobLauncher;
}
public JobLocator getJobLocator() {
return jobLocator;
}
public void setJobLocator(JobLocator jobLocator) {
this.jobLocator = jobLocator;
}
#Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
Job job = jobLocator.getJob(jobName);
JobExecution jobExecution = jobLauncher.run(job, new JobParameters());
log.info("{}_{} was completed successfully", job.getName(), jobExecution.getId());
} catch (Exception e) {
log.error("Encountered job execution exception!");
}
}
}
BatchConfig.java
#Configuration
public class BatchConfig {
#Autowired
JobBuilderFactory jobBuilderFactory;
#Autowired
StepBuilderFactory stepBuilderFactory;
#Bean
public Tasklet task1()
{
return new Tasklet(){
#Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
// TODO Auto-generated method stub
System.out.println("hello world");
return RepeatStatus.FINISHED;
}
};
}
#Bean
public Step step1(){
return stepBuilderFactory.get("step1")
.tasklet(task1())
.build();
}
#Bean
public Job job1()
{
return jobBuilderFactory.get("job1")
.start(step1())
.build();
}
}
BatchApplication.java
#SpringBootApplication
#EnableBatchProcessing
#Import(QuartzConfiguration.class)
public class BatchApplication {
public static void main(String[] args) {
SpringApplication.run(BatchApplication.class, args);
}
}
error log
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.4.RELEASE)
2017-07-11 14:35:59.370 INFO 8868 --- [ main] com.schwab.cat.BatchApplication : Starting BatchApplication on KVMOF0487DVLBDC with PID 8868 (started by pankaj.k.singh in C:\Users\pankaj.k.singh\Desktop\batch\sample hello world)
2017-07-11 14:35:59.377 INFO 8868 --- [ main] com.schwab.cat.BatchApplication : No active profile set, falling back to default profiles: default
2017-07-11 14:35:59.511 INFO 8868 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#221af3c0: startup date [Tue Jul 11 14:35:59 IST 2017]; root of context hierarchy
2017-07-11 14:36:00.992 WARN 8868 --- [ main] o.s.c.a.ConfigurationClassEnhancer : #Bean method ScopeConfiguration.stepScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as #Autowired, #Resource and #PostConstruct within the method's declaring #Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see #Bean javadoc for complete details.
2017-07-11 14:36:01.013 WARN 8868 --- [ main] o.s.c.a.ConfigurationClassEnhancer : #Bean method ScopeConfiguration.jobScope is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as #Autowired, #Resource and #PostConstruct within the method's declaring #Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see #Bean javadoc for complete details.
2017-07-11 14:36:01.230 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Tomcat' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Tomcat] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.253 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$1bb5301] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.435 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.632 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'dataSource' of type [org.apache.tomcat.jdbc.pool.DataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.641 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$$EnhancerBySpringCGLIB$$e3aef661] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.672 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'dataSourceInitializer' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.679 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration' of type [org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$$EnhancerBySpringCGLIB$$17e2d67] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.718 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'jobLauncher' of type [com.sun.proxy.$Proxy41] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.732 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'jobRegistry' of type [com.sun.proxy.$Proxy43] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:01.733 INFO 8868 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'com.quantvalley.batch.quartz.QuartzConfiguration' of type [com.quantvalley.batch.quartz.QuartzConfiguration$$EnhancerBySpringCGLIB$$88291ebb] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-07-11 14:36:03.256 INFO 8868 --- [ main] o.s.b.c.r.s.JobRepositoryFactoryBean : No database type set, using meta data indicating: HSQL
2017-07-11 14:36:03.606 INFO 8868 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor.
2017-07-11 14:36:03.912 INFO 8868 --- [ main] org.quartz.impl.StdSchedulerFactory : Using default implementation for ThreadExecutor
2017-07-11 14:36:03.980 INFO 8868 --- [ main] org.quartz.core.SchedulerSignalerImpl : Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2017-07-11 14:36:03.984 INFO 8868 --- [ main] org.quartz.core.QuartzScheduler : Quartz Scheduler v.2.2.3 created.
2017-07-11 14:36:03.987 INFO 8868 --- [ main] org.quartz.simpl.RAMJobStore : RAMJobStore initialized.
2017-07-11 14:36:03.991 INFO 8868 --- [ main] org.quartz.core.QuartzScheduler : Scheduler meta-data: Quartz Scheduler (v2.2.3) 'schedulerFactoryBean' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
2017-07-11 14:36:03.993 INFO 8868 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler 'schedulerFactoryBean' initialized from an externally provided properties instance.
2017-07-11 14:36:03.993 INFO 8868 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler version: 2.2.3
2017-07-11 14:36:03.998 INFO 8868 --- [ main] org.quartz.core.QuartzScheduler : JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory#20312893
2017-07-11 14:36:04.335 INFO 8868 --- [ main] o.s.jdbc.datasource.init.ScriptUtils : Executing SQL script from class path resource [org/springframework/batch/core/schema-hsqldb.sql]
2017-07-11 14:36:04.366 INFO 8868 --- [ main] o.s.jdbc.datasource.init.ScriptUtils : Executed SQL script from class path resource [org/springframework/batch/core/schema-hsqldb.sql] in 25 ms.
2017-07-11 14:36:04.733 INFO 8868 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-07-11 14:36:04.748 INFO 8868 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2017-07-11 14:36:04.749 INFO 8868 --- [ main] o.s.s.quartz.SchedulerFactoryBean : Starting Quartz Scheduler now
2017-07-11 14:36:04.750 INFO 8868 --- [ main] org.quartz.core.QuartzScheduler : Scheduler schedulerFactoryBean_$_NON_CLUSTERED started.
2017-07-11 14:36:04.773 INFO 8868 --- [ main] com.schwab.cat.BatchApplication : Started BatchApplication in 6.481 seconds (JVM running for 11.417)
2017-07-11 14:36:20.039 ERROR 8868 --- [ryBean_Worker-1] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
2017-07-11 14:36:40.006 ERROR 8868 --- [ryBean_Worker-2] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
2017-07-11 14:37:00.001 ERROR 8868 --- [ryBean_Worker-3] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
2017-07-11 14:37:20.002 ERROR 8868 --- [ryBean_Worker-4] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
2017-07-11 14:37:40.002 ERROR 8868 --- [ryBean_Worker-5] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
2017-07-11 14:38:00.002 ERROR 8868 --- [ryBean_Worker-6] c.q.batch.quartz.QuartzJobLauncher : Encountered job execution exception!
Please someone look into it and let me know the problem.
You swallowed the exception in your try/catch and instead, you logged only the fact that exception occurrent, but not what kind of exception it was. If you change logging statement to this:
log.error("Encountered job execution exception!", e);
You'll see that the error says:
org.springframework.batch.core.launch.NoSuchJobException: No job configuration with the name [Test_Job] was registered
You have declared a job with name job1, not Test_Job so that's why you're getting the exception. You have to change job data map to:
map.put("jobName", "job1");
This will remove the exception, but your job will still run once as Spring Batch requires unique job parameters to restart it, see this answer for explanation.
So because of that, you have to modify your job execution to something like this (the simplest) to be able to run it continually:
#Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
Job job = jobLocator.getJob(jobName);
Map<String, JobParameter> parametersMap = new HashMap<>();
parametersMap.put("timestamp", new JobParameter(System.currentTimeMillis()));
JobParameters jobParameters = new JobParameters(parametersMap);
JobExecution jobExecution = jobLauncher.run(job, jobParameters);
log.info("{}_{} was completed successfully", job.getName(), jobExecution.getId());
} catch (Exception e) {
log.error("Encountered job execution exception!", e);
}
}

Resources