property file not loading spring boot - spring-boot

My property file is location in src/main/resources in eclipse checked its in the classpath - however the following class is unable to initialize the env variable. Any help?
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.solr.core.SolrTemplate;
#Configuration
#PropertySource(value = { "classpath:solr.properties" })
public class SolrConfig {
#Autowired
private Environment env;
private final static Logger logger = LoggerFactory.getLogger(SolrConfig.class);
#Bean
public SolrClient solrClient() {
if(env == null )
{
logger.error("Property file not loaded!!!");
System.exit(1);
}
String servername = env.getProperty("solr.server");
return new HttpSolrClient.Builder(servername)
.build();
}
#Bean
public SolrTemplate solrTemplate(SolrClient client) throws Exception {
return new SolrTemplate(client);
}
}

You class annotation is correct, but try the following within your method:
Properties _properties = new Properties();
_properties.load(getClass().getClassLoader().getResourceAsStream("solr.properties"));
String servername = _properties.getProperty("solr.server");

I believe you're missing a PropertySourcesPlaceholderConfigurer registered.
From Spring documentation of #PropertySource:
In order to resolve ${...} placeholders in definitions or
#Value annotations using properties from a PropertySource, one must
register a PropertySourcesPlaceholderConfigurer. This happens
automatically when using in XML, but
must be explicitly registered using a static #Bean method when using
#Configuration classes.
So consider registering this bean:
#Bean
public static PropertySourcesPlaceholderConfigurer
propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}

Related

Property or field 'config' cannot be found on null

I am trying to Implement InitializingBean on my StudentDaoImpl.class and in the function afterPropertiesSet() trying to execute an expression using ExpressionParser, but Spring is saying that property config is not found or is null even if I have declared config in my App.propperties.
AppConfig.class(Configuration Class)
package config;
import dao.StudentDAOImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
#Configuration
#PropertySource("classpath:App.properties")
public class AppConfig {
#Bean("jdbcTemplete")
public JdbcTemplate jdbcTemplate() {
JdbcTemplate template = new JdbcTemplate();
template.setDataSource(dataSource());
return template;
}
#Bean("dataSource")
public DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/springjdbc");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
#Bean("StudentDaoImpl")
public StudentDAOImpl studentDaoImpl() {
StudentDAOImpl studentdao = new StudentDAOImpl(jdbcTemplate());
return studentdao;
}
#Bean("getProperties")
public static PropertySourcesPlaceholderConfigurer getProperties() {
return new PropertySourcesPlaceholderConfigurer();
}
}
StudentDaoImpl.class (I have removed methods of StudentDao Interface from the code below for you to see properly)
package dao;
import entities.Student;
import mapper.StudentMapper;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.util.List;
public class StudentDAOImpl implements StudentDAO, InitializingBean {
private JdbcTemplate jdbcTemplate;
#Value("${config}")
String s;
public StudentDAOImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
#Override
public void afterPropertiesSet() throws Exception {
ExpressionParser expressionParser = new SpelExpressionParser();
System.out.println(s);
Expression expression = expressionParser.parseExpression("config");
String result = (String)expression.getValue();
System.out.println(result);
// if(result == true) {
// System.out.println("[Configuration]: Java Configuration");
// } else {
// System.out.println("[Configuration]: XML Configuration");
// }
}
}
App.properties
config=java
Also, I have seen that I was able to access the property from App.properties using #Value but not with ExpressionParser, Please help me solve this issue.
?
You are parsing a String, not the field; use
Expression expression = expressionParser.parseExpression(config);
to parse an expression in field config - however the value java is not a valid expression.
It is not at all clear what you are trying to do.

rabbitmq is not creating queue automatically when spring boot publisher send msg

rabbitmq is not creating queue automatically when spring boot publisher send msg ...
i did it this way so it is without manual configuration
and this is my configuration ///////rabbitmq is not creating queue automatically when spring boot publisher send msg ...
i did it this way so it is without manual configuration
and this is my configuration
package com.hariri_stocks.MQ;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
public class msgConfiguration {
public static final String ROUTING_KEY1 = "routingKey1";
public static final String STOCKS_EXCHANGE = "stocks_exchange";
public static final String STOCKS_QUEUE = "stocks_queue";
#Bean
public Queue queue() {
return new Queue(STOCKS_QUEUE , false);
}
#Bean
public TopicExchange exchange() {
return new TopicExchange(STOCKS_EXCHANGE );
}
#Bean
public Binding binding()
{
return BindingBuilder.bind(queue()).to(exchange()).with(ROUTING_KEY1);
}
#Bean
public MessageConverter converter()
{
return new Jackson2JsonMessageConverter();
}
#Bean
public AmqpTemplate template(ConnectionFactory cf) {
final RabbitTemplate rt = new RabbitTemplate(cf);
rt.setMessageConverter(converter());
return rt;
}
}
package com.hariri_stocks.MQ;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class Givver {
#Autowired
private RabbitTemplate template;
#GetMapping("/msg")
public String send() {
msgStatus m = new msgStatus("ok","damn");
template.convertSendAndReceive(msgConfiguration.STOCKS_EXCHANGE, msgConfiguration.ROUTING_KEY1,m);
return "ok";
}
}
enter image description here
spring.datasource.url=jdbc:mysql://localhost:3306/hariri_stocks
spring.datasource.username=root
spring.datasource.password=
spring.thymeleaf.enabled=true
spring.thymeleaf.check-template-location=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
server.port=9091
spring.application.name=hariri
Class msgConfiguration needs to be annotated with #Configuration for those beans to be added to the application context.
Also you don't need the template bean - Spring Boot will auto wire the converter bean into its auto-configured RabbitTemplate.

Spring boot + MyBatis, multiple datasources and mappers (java and xml), getting "Invalid bound statement (not found)" error

I am trying to create a maven project to access Oracle database with more than one datasource configurations. Here is my code:
First DataSource Config:
package com.business.data.datasource;
import javax.sql.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
#Configuration
public class FirstDbConfig {
#Primary
#Bean(name = "firstDataSourceProperties")
#ConfigurationProperties("first.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
#Primary
#Bean(name = "firstDataSource")
#ConfigurationProperties(prefix = "first.datasource")
public DataSource dataSource(#Qualifier("firstDataSourceProperties") DataSourceProperties properties) {
return DataSourceBuilder.create().build();
}
#Bean(name = "firstSessionFactory")
#Primary
public SqlSessionFactoryBean firstSessionFactory(#Qualifier("firstDataSource") final DataSource firstDataSource)
throws Exception {
final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(firstDataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:./mapper/FirstDbMapper.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("com.business.data.model");
return sqlSessionFactoryBean;
}
}
Second DataSource Config:
package com.business.data.datasource;
import javax.sql.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
#Configuration
public class SecondDbConfig {
#Primary
#Bean(name = "secondDataSourceProperties")
#ConfigurationProperties("second.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
#Bean(name = "secondDataSource")
#ConfigurationProperties(prefix = "second.datasource")
public DataSource dataSource(#Qualifier("secondDataSourceProperties") DataSourceProperties properties) {
return DataSourceBuilder.create().build();
}
#Bean(name = "secondSessionFactory")
public SqlSessionFactoryBean secondSessionFactory(#Qualifier("secondDataSource") final DataSource firstDataSource)
throws Exception {
final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(firstDataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:./mapper/SecondDbMapper.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("com.business.data.model");
return sqlSessionFactoryBean;
}
}
First Mapper interface:
package com.business.data.repository;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.business.data.model.PersonDetail;
import org.springframework.stereotype.Repository;
#Repository
#Mapper
public interface FirstDbMapper {
public List<PersonDetail> getUserData(#Param("firstName") String firstName, #Param("lastName") String lastName);
}
Second Mapper interface:
package com.business.data.repository;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.business.data.model.PersonDetail;
import org.springframework.stereotype.Repository;
#Repository
#Mapper
public interface SecondDbMapper {
public List<PersonDetail> getStaffData(#Param("firstName") String firstName, #Param("lastName") String lastName);
}
src/main/resources/mapper/FirstMapper.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace must indicate mapper interface full package path . It is an alias here-->
<mapper namespace = "com.business.data.repository.FirstDbMapper">
<select id = "getUserData" parameterType = "map" resultMap = "personDetailMap">
SELECT *
FROM user
WHERE UPPER(first_name) LIKE UPPER(#{firstName}||'%')
AND UPPER(last_name) LIKE UPPER(#{lastName}||'%')
</select>
...
</mapper>
src/main/resources/mapper/SecondMapper.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace must indicate mapper interface full package path . It is an alias here-->
<mapper namespace = "com.business.data.repository.SecondDbMapper">
<select id = "getStaffData" parameterType = "map" resultMap = "personDetailMap">
SELECT *
FROM staff
WHERE UPPER(first_name) LIKE UPPER(#{firstName}||'%')
AND UPPER(last_name) LIKE UPPER(#{lastName}||'%')
</select>
...
</mapper>
Service class is like
#Autowired
FirstDbMapper firstDbMapper;
public List<PersonDetail> getUser(String fName, String lName) throws MyServiceException {
...
try {
userList = firstDbMapper.getUserData(fName, lName);
} catch (Exception e) {
...
}
return userList;
}
application.properties:
first.datasource.jdbc-url=jdbc:oracle:thin:#host01:1561:db1
first.datasource.username=user1
first.datasource.password=password1
second.datasource.jdbc-url=jdbc:oracle:thin:#host02:1561:db2
second.datasource.username=user2
second.datasource.password=password2
I also have #MapperScan("com.business.data.repository") in my spring boot application java.
I can only make one datasource work, which is the one with #Primary annotation. I swapped #Primary between the two configuration, always the one with #Primary worked, the other got "Invalid bound statement (not found)" error.
Can anyone help me out?
Thanks!
You can use the #MapperScan annotation on a configuration class to attach mappers to the different session factories. I find it convenient to place mappers in different packages like this:
#MapperScan(basePackages="mapper.package1", sqlSessionFactoryRef="firstSessionFactory")
#MapperScan(basePackages="mapper.package2", sqlSessionFactoryRef="secondSessionFactory")
The issue was resolved by using HikariDataSource.
#Primary
#Bean(name = FIRST_DATASOURCE)
#ConfigurationProperties(prefix = "first.datasource")
public DataSource dataSourceFirst() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}

How to create same Bean using Constructor Injection in Spring boot for different property values

I have to create multiple beans of same type for different property value which is to be injected using constructor.
Currently I have used Bean scope as Prototype & created multiple methods to read different properties to create new object. How to combine all the different methods into single method and to supply different values at run time to create new bean.
package com.demo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
#Configuration
public class ConfigClass {
#Bean(name="RC")
public JavaClient getClient(#Autowired Environment env)
{
String sName=env.getProperty("RCSName");
String aUrl=env.getProperty("RCAUrl");
String dUrl=env.getProperty("RCDUrl");
return new JavaClient(sName,aUrl,dUrl);
}
#Bean(name="O")
public JavaClient getOClient(#Autowired Environment env)
{
String sName=env.getProperty("OSName");
String aUrl=env.getProperty("OAUrl");
String dUrl=env.getProperty("ODUrl");
return new JavaClient(sName,aUrl,dUrl);
}
}
Now it is creating 2 beans as per above code. Expectation: How to combine getClient & getOClient into single method, but the property to be supplied in a loop to create multiple beans of same type JavaClient
I have modified my ConfigClass as below & created ApplicationContextAware to inject beans by reading file properties.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.EnableScheduling;
#Configuration
#EnableScheduling
public class ConfigClass {
#Bean
#Scope("prototype")
public JavaClient getClient(String sName,String aUrl,String dUrl)
{
return new JavaClient(sName,aUrl,dUrl);
}
}
Then Have created ApplicationContextAware to create Beans.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Iterator;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
#Component
public class ApplicationContextProvider implements ApplicationContextAware {
private ApplicationContext applicationContext;
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public ApplicationContext getContext() {
return applicationContext;
}
#PostConstruct
public void init()
{
try {
String fileName = "Url.txt";
Resource resource = new ClassPathResource(fileName);
File file = resource.getFile();
List<String> lines = Files.readAllLines(file.toPath());
for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
String line = (String) iterator.next();
String[] s = line.split(",");
applicationContext.getBean(JavaClient.class,s[0], s[1], s[2]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Spring boot with spring batch and jpa -configuration

I have simple batch application, reading csv to postgres database.
I have uploaded the code in this below repo in bitbucket
https://github.com/soasathish/spring-batch-with-jpa.git
I have problems in configuring the writing to database using spring data JPA.
I am getting manage bean not found .issue.
This same jpa spring data configuration works in different project when i tried to integrate with spring batch it fails with manage bean not found.
The batch config has spring job
There is only one step
1) reader -read from csv files.
processor applies some rules on the files .. Drools
please run schema-postgresql.sql to setup database
WRITER USES THE SPRING DATA JPA TO WRITE TO DB
could one help
I have uploaded the code in this below repo in bitbucket
https://github.com/soasathish/spring-batch-with-jpa.git
i know its a minor issue , but any direction or help will be grateful
code for creating repo
=======================
package uk.gov.iebr.batch.config;
import static uk.gov.iebr.batch.config.AppProperties.DRIVER_CLASS_NAME;
import static uk.gov.iebr.batch.config.AppProperties.IEBR_DB_PASSWORD_KEY;
import static uk.gov.iebr.batch.config.AppProperties.IEBR_DB_URL_KEY;
import static uk.gov.iebr.batch.config.AppProperties.IEBR_DB_USER_KEY;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#PropertySource({"classpath:application.properties"})
#EnableJpaRepositories({"uk.gov.iebr.batch.repository"})
#EnableTransactionManagement
#ComponentScan(basePackages="uk.gov.iebr.batch.repository")
public class DataSourceConfiguration {
#Autowired
Environment env;
#Bean(name = "allsparkEntityMF")
public LocalContainerEntityManagerFactoryBean allsparkEntityMF() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(allsparkDS());
em.setPersistenceUnitName("allsparkEntityMF");
em.setPackagesToScan(new String[] { "uk.gov.iebr.batch"});
em.setPackagesToScan(new String[] { "uk.gov.iebr.batch.repository"});
em.setPersistenceProvider(new HibernatePersistenceProvider());
HibernateJpaVendorAdapter a = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(a);
Properties p = hibernateSpecificProperties();
p.setProperty("hibernate.ejb.entitymanager_factory_name", "allsparkEntityMF");
em.setJpaProperties(p);
return em;
}
#Bean(name = "allsparkDS")
public DataSource allsparkDS() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty(DRIVER_CLASS_NAME));
dataSource.setUrl(env.getProperty(IEBR_DB_URL_KEY));
dataSource.setUsername(env.getProperty(IEBR_DB_USER_KEY));
dataSource.setPassword(env.getProperty(IEBR_DB_PASSWORD_KEY));
return dataSource;
}
#Bean
public Properties hibernateSpecificProperties(){
final Properties p = new Properties();
p.setProperty("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.ddl-auto"));
p.setProperty("hibernate.dialect", env.getProperty("spring.jpa.hibernate.dialect"));
p.setProperty("hibernate.show-sql", env.getProperty("spring.jpa.show-sql"));
p.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("spring.jpa.hibernate.cache.use_second_level_cache"));
p.setProperty("hibernate.cache.use_query_cache", env.getProperty("spring.jpa.hibernate.cache.use_query_cache"));
return p;
}
#Bean(name = "defaultTm")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(allsparkEntityMF().getObject());
return txManager;
}
}
Batch config file:
package uk.gov.iebr.batch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import uk.gov.iebr.batch.config.AllSparkDataSourceConfiguration;
import uk.gov.iebr.batch.config.DataSourceConfiguration;
import uk.gov.iebr.batch.dao.PersonDao;
import uk.gov.iebr.batch.model.Person;
import uk.gov.iebr.batch.step.Listener;
import uk.gov.iebr.batch.step.Processor;
import uk.gov.iebr.batch.step.Reader;
import uk.gov.iebr.batch.step.Writer;
#Configuration
#EnableBatchProcessing
//spring boot configuration
#EnableAutoConfiguration
//file that contains the properties
#PropertySource("classpath:application.properties")
#Import({DataSourceConfiguration.class, AllSparkDataSourceConfiguration.class})
public class BatchConfig {
private static final Logger log = LoggerFactory.getLogger(BatchConfig.class);
#Autowired
public JobBuilderFactory jobBuilderFactory;
#Autowired
public StepBuilderFactory stepBuilderFactory;
#Autowired
public PersonDao PersonDao;
#Autowired
public DataSourceConfiguration dataSourceConfiguration;
#Bean
public Job job() {
long startTime = System.currentTimeMillis();
log.info("START OF BATCH ========================================================================" +startTime);
return jobBuilderFactory.get("job").incrementer(new RunIdIncrementer())
//.listener(new Listener(PersonDao))
.flow(step1()).end().build();
}
#Bean
public Step step1() {
return stepBuilderFactory.get("step1").<Person, Person>chunk(10)
.reader(Reader.reader("tram-data.csv"))
.processor(new Processor()).writer(new Writer(PersonDao)).build();
}
}
Writer calls this PersonDaoImpl:
public class PersonDaoImpl implements PersonDao {
#Autowired
DataSourceConfiguration dataSource;
#Autowired
PersonRepository personrepo;
#Override
public void insert(List<? extends Person> Persons) {
personrepo.save(Persons);
}
}
Based on the code you provided and the stack trace in your comment.
It's complaining that it can't find a #Bean named entityManagerFactory.
The reason this is happening is because you are using #EnableJpaRepositories and the entityManagerFactoryRef property defaults to entityManagerFactory. This property defines the name of the #Bean for the EntityManagerFactory.
I think your application configuration is preventing the normal auto-configuration from spring-boot from being processed.
I would recommend removing the IEBRFileProcessApplication class and following this example for configuring your spring-boot application (you could use ServletInitializer if you want).
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
I also can't really see a need for DataSourceConfiguration and AllSparkDataSourceConfiguration, so I would recommend removing them. If you really need to specify your own DataSource, let me know and I can provide an additional example.
Between the #SpringBootApplication and #EnableBatchProcessing annotations, everything that is necessary will be bootstrapped for you.
All you need on BatchConfig is #Configuration and #EnableBatchProcessing.
If you make these changes to simplify your code base, then your problems should disappear.
UPDATE:
I created a pull request located here https://github.com/soasathish/spring-batch-with-jpa/pull/1
Please take a look at the javadoc here for an explanation on how #EnableBatchProcessing works. http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.html

Resources