I have the following problem that is preventing me from launching the batch correctly:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaSharedEM_entityManagerFactory': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument
Here's the main class:
@EnableBatchProcessing(dataSourceRef = "batchDataSource", transactionManagerRef = "batchTransactionManager")
@SpringBootApplication
public class SpringBatchApplicationDemo {
@Value("classpath:schema-postgresql.sql")
private Resource schemaScript;
@Value("schema-drop-postgresql.sql")
private Resource dropSchemaScript;
@Bean
public DataSource batchDataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.url("jdbc:postgresql://localhost:5432/database?currentSchema=batchmetadata");
dataSourceBuilder.username("postgres");
dataSourceBuilder.password("password");
DataSource dataSource = dataSourceBuilder.build();
DatabasePopulatorUtils.execute(databasePopulator(), dataSource);
return dataSource;
}
private DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(dropSchemaScript);
populator.addScript(schemaScript);
return populator;
}
@Bean
public DataSource dataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.url("jdbc:postgresql://localhost:5432/database?currentSchema=schema_name");
dataSourceBuilder.username("postgres");
dataSourceBuilder.password("password");
return dataSourceBuilder.build();
}
@Bean
public JdbcTransactionManager batchTransactionManager(@Qualifier("batchDataSource") DataSource batchDataSource) {
return new JdbcTransactionManager(batchDataSource);
}
public static void main(String e []) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringBatchApplicationDemo.class);
JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis()).toJobParameters();
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
JobExecution jobExecution = jobLauncher.run(context.getBean(Job.class), jobParameters);
System.out.println("Job Exit Status : " + jobExecution.getStatus());
}
@Bean
public JdbcTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new JdbcTransactionManager(dataSource);
}
@Bean
public Job job(JobRepository jobRepository, @Qualifier("transactionManager") PlatformTransactionManager transactionManager) {
return new JobBuilder("job", jobRepository)
.start(step(jobRepository, transactionManager))
.build();
}
@Bean
public JdbcCursorItemReader<Person> itemReader() {
String sql = "select * from person";
return new JdbcCursorItemReaderBuilder<Person>()
.name("personItemReader")
.dataSource(dataSource())
.sql(sql)
.beanRowMapper(Person.class)
.build();
}
@Bean
public FlatFileItemWriter<Person> itemWriter() {
return new FlatFileItemWriterBuilder<Person>()
.resource(new FileSystemResource("persons.csv"))
.name("personItemWriter")
.delimited()
.names("id", "name")
.build();
}
@Bean
public Step step(JobRepository jobRepository, @Qualifier("transactionManager") PlatformTransactionManager transactionManager) {
return new StepBuilder("step-persons", jobRepository)
.<Person, Person>chunk(5, transactionManager)
.reader(itemReader())
.writer(itemWriter())
.build();
}
}
Entity class:
@Entity
@Data
@Table(name = "person")
public class Person {
@Id
private String id;
private String name;
// Getters and setters...
}
application.properties
:
spring.batch.jdbc.initialize-schema=ALWAYS
spring.batch.job.enabled=false
spring.batch.initialize-schema=always
spring.jpa.properties.org.hibernate.envers.audit_table_suffix=batchmetadata
spring.jpa.properties.org.hibernate.envers.default_schema=batchmetadata
spring.jpa.hibernate.ddl-auto=create
In essence, I want to have two schemas:
batchmetadata
: Where I store batch metadata.
schema_name
: Where I store data coming from a CSV file into the person table.