스프링 배치 및 jpa와 스프링 부트 통합
스프링 부트 프로젝트와 스프링 배치 및 데이터 jpa 프로젝트를 통합하고 있습니다. 작업 및 데이터 구성과 관련된 모든 것이 옳습니다. 내 작업 작성자 결과를 데이터베이스에 유지하는 것을 제외하고. 파일을 읽고 처리한 후에는 mysql 데이터베이스에 쓸 수 없습니다.오류는 없지만 삽입할 수는 없습니다. 흥미로운 것은 제 데이터 소스가 구성되어 있다는 것입니다. 삽입하기 전에 데이터베이스에서 샘플 레코드를 가져올 수 있기 때문입니다. 이 문제를 해결할 수 있도록 도와주세요.
my application.properties:
spring.datasource.url = jdbc:mysql://localhost:3306/batchtest? characterEncoding=UTF-8&autoReconnect=true
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
배치 구성:
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Bean
public ResourcelessTransactionManager transactionManager() {
return new ResourcelessTransactionManager();
}
@Bean
public JobRepository jobRepository(ResourcelessTransactionManager transactionManager) throws Exception {
MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean = new MapJobRepositoryFactoryBean(transactionManager);
mapJobRepositoryFactoryBean.setTransactionManager(transactionManager);
return mapJobRepositoryFactoryBean.getObject();
}
@Bean
public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
simpleJobLauncher.setJobRepository(jobRepository);
return simpleJobLauncher;
}
@Bean
public FlatFileItemReader<Person> reader() {
FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>();
reader.setResource(new ClassPathResource("sample-data.csv"));
reader.setLineMapper(new DefaultLineMapper<Person>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(new String[] { "firstName", "lastName" });
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}});
}});
return reader;
}
@Bean
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
@Bean
public ItemWriter<Person> writer() throws Exception {
return new PersonWriter();
}
@Bean
public Job importUserJob() throws Exception{
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.build();
}
@Bean
public Step step1() throws Exception{
return stepBuilderFactory.get("step1")
.<Person, Person> chunk(1)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
Dao 클래스:
public interface PersonDao extends CrudRepository<Person,Integer> {
}
작가 클래스:
public class PersonWriter implements ItemWriter<Person> {
@Autowired
PersonDao personDao;
@Override
public void write(List<? extends Person> items) throws Exception {
LOGGER.info("Received the information of {} students", items.size());
for(Person person:items)
{
LOGGER.info(String.format("inserting for customre %s %s", person.getFirstName(), person.getLastName()));
Person tempPerson = personDao.findOne(1);
personDao.save(person) ;
LOGGER.info(String.format("person id : %d",person.getId()));
}
}
tempPerson은 jpa 데이터를 테스트하기 위한 객체로 데이터베이스에서 id1의 person 객체를 가져오지만 다음 줄에는 오류 없이 데이터베이스에 삽입할 수 없습니다.그냥 라인을 실행하고 루프를 계속합니다.
이 문제에 대한 해결책이 예상보다 근접할 수 있습니다.단순히 거래 매니저 빈의 이름을 바꾸려고 한 것입니까?다른 이름으로 Spring Data JPA에서는 기본적으로 사용되지 않습니다.
당신의 문제를 재현하고 난 다음에 그냥 이걸 바꿨습니다.
@Bean
public ResourcelessTransactionManager transactionManager() {
return new ResourcelessTransactionManager();
}
다음 항목에 대해:
@Bean
public ResourcelessTransactionManager resourcelessTransactionManager() {
return new ResourcelessTransactionManager();
}
그리고 그것이 문제를 해결했다고 생각합니다.'transactionManager'는 Spring Data JPA에서 transactionManager의 기본 bean 이름입니다(적어도 제가 알기로는 Spring Boot는 해당 이름의 bean을 찾지 못하면 자동으로 구성하고, 만약 그런 이름이라면 발견된 bean을 사용하며, 데이터베이스 트랜잭션은 리소스리스(Resourceless)를 거칩니다).
다음 사항도 생략할 수 있습니다.
@Bean
public JobRepository jobRepository(ResourcelessTransactionManager transactionManager) throws Exception {
return new MapJobRepositoryFactoryBean(transactionManager).getObject();
}
그리고 빈에 직접 전화를 걸게 됩니다(적절한 트랜잭션 관리자가 배치와 함께 사용되는지 '더 확실하게' 확인하기 위해).
@Bean
public JobRepository jobRepository() throws Exception {
return new MapJobRepositoryFactoryBean(resourcelessTransactionManager()).getObject();
}
테스트해보시면 알려주시고, 주된 문제였기를 바랍니다 :)
놓쳤을 수도 있지만, 어떤 DB 접근 방식(JPA, Hibernate, JDBC 등)을 사용하는지 어디에 명시되어 있는지 알 수가 없습니다.JPA를 가정하고 있지만, 귀하의 ItemWriter는 DB 인식 ItemWriter(RepositoryItemWriter, JpaItemWriter, JdbcBatchItemWriter, HibernateItemWriter) 중 하나를 확장해야 한다고 생각합니다.기본 ItemWriter는 트랜잭션과 모든 리소스를 직접 관리하기를 기대합니다.대신 RepositoryItemWriter(또는 적절한 것 중 하나)를 사용해 보십시오.Entity Manager를 제공하고 트랜잭션 내에서 쓰기가 호출되는지 확인해야 합니다(예: 일부).@Transactional방법).
언급URL : https://stackoverflow.com/questions/37821028/spring-boot-integration-with-spring-batch-and-jpa
'programing' 카테고리의 다른 글
| JS를 이용하여 h1 태그의 값을 얻는 방법은? (0) | 2023.10.04 |
|---|---|
| 사용자 입력에 따라 긴 쿼리에 대한 MySQL 오류를 PHP에 표시하려면 어떻게 해야 합니까? (0) | 2023.10.04 |
| jQuery의 "val()"이(가) 작동하지 않습니다. (0) | 2023.10.04 |
| 기본 앵커 동작 방지 AngularJS (0) | 2023.10.04 |
| AngularJS에서 $http 업로드 파일 진행률 (0) | 2023.10.04 |