I am developing Spring Boot Batch Example
. In this example, I have created BatchJPA
core module which has Entities, JPARepository and DB configurations
.
This module adding into another Spring Module as dependency and in this module, I am adding code related specific batch jobs (like custom repository etc). I have total 15 batch jobs and I will be creating separate Spring Boot project with BatchJPA dependency.
Now I am getting below error:
10-08-2018 20:13:10.122 [main] WARN org.springframework.context.support.ClassPathXmlApplicationContext.refresh - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CustMstrCustomRepository': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available
10-08-2018 20:13:10.124 [main] INFO org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener.logAutoConfigurationReport -
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
10-08-2018 20:13:10.251 [main] ERROR org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter.report -
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean of type 'javax.persistence.EntityManagerFactory' that could not be found.
- User-defined bean method 'entityManagerFactory' in 'CommonDatabaseConfig'
Action:
Consider revisiting the entries above or defining a bean of type 'javax.persistence.EntityManagerFactory' in your configuration.
CommonDatabaseConfig.java
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.XXXXX.ABC.repository",
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager")
public class CommonDatabaseConfig {
// This is needed
@Bean
@Primary
@ConfigurationProperties("ABC.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "ABC.datasource")
public DataSource dataSource() {
return dataSourceProperties().initializeDataSourceBuilder().build();
}
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("dataSource") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("com.XXXXX.ABC.Entity")
.persistenceUnit("MyDBDev")
.build();
}
@Primary
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
@Bean
public PersistenceAnnotationBeanPostProcessor beanPostProcessor() {
return new PersistenceAnnotationBeanPostProcessor();
}
}
DataTasklet.java
@Service
@Qualifier("DataTasklet")
@Transactional(value="transactionManager")
public class DataTasklet implements Tasklet {
// TODO - Here I am getting null - unable to create @Bean here
@Autowired
private CustMstrCustomRepository custMstrCustomRepository;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
List<CustomCustomEntity> data = CustMstrCustomRepository.getData();
chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put("data", data);
return RepeatStatus.FINISHED;
}
}
CustMstrCustomRepository.java
@Configuration
@Service
public class CustMstrCustomRepository {
private static final String SQL= "MY COMPEX JOIN QUERY HERE - ";
@PersistenceContext
@Qualifier(value = "entityManagerFactory")
private EntityManager entityManager;
@SuppressWarnings("unchecked")
public List<CustomCustomEntity> getData()() {
Query q = entityManager.createNativeQuery(SQL);
q.setParameter("isActv", "Y");
List<Object[]> resultList = q.getResultList();
List<CustomCustomEntity> results = new ArrayList<>();
for (Object[] objects : resultList) {
results.add(CustomCustomEntity.builder()
.XX((BigDecimal) objects[0])
.YY((BigDecimal) objects[1])
.ZZ((Date) objects[2])
.AA((Date) objects[3])
.BB((String) objects[4]).build());
}
return results;
}
}
MainApplication.java
@SpringBootApplication
@EnableBatchProcessing
public class MainApplication implements CommandLineRunner {
@Autowired
private DataBatchJobLauncher jobLauncher;
@Bean
public Tasklet dataTasklet() {
return new DataTasklet();
}
public static void main(String[] args) {
SpringApplication.run(EdsMainApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
jobLauncher.executeBillingJob();
}
}
ABC.XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<batch:job id="Q" >
<batch:step id="step1" next="dataDecision">
<batch:tasklet transaction-manager="transactionManager" ref="QQContextTasklet" />
</batch:step>
<batch:decision id="dataDecision" decider="dataDecider">
<batch:next on="SUCCESS" to="ADataStep" />
</batch:decision>
<batch:step id="ADataStep">
<batch:tasklet ref="dataTasklet" />
</batch:step>
</batch:job>
<bean id="stepScope" class="org.springframework.batch.core.scope.StepScope">
<property name="autoProxy" value="true"/>
</bean>
<bean id="QQContextTasklet" class="com.XXXXXX.batch.tasklet.UpdateBillingContextTasklet" scope="step">
<property name="billRunMode" value="#{jobParameters['runMode']}" />
<property name="executionContext" value="#{stepExecution.jobExecution.executionContext}" />
</bean>
<bean id="dataTasklet" class="com.XXXXXX.batch.tasklet.dataTasklet" />
<bean id="dataDecider" class="com.XXXXXX.batch.decider.dataDecider" />
<bean id="custMstrCustomRepository" class="com.XXXXXX.custom.repository.CustMstrCustomRepository" />
</beans>