Description
Petr Dvorak opened BATCH-2642 and commented
We are using Spring Boot and we were struggling with a following issue: We needed to use our Spring Data JPA repositories (interfaces extending 'CrudRepository') in a Spring Batch writer and for some reason, the 'save(s)' method did not work for us - method got called, no exception or error was in the log, but the object was not persisted. In principle, it was exactly the same issue as the one reported here:
The offending part was this one:
@Component
public class MessagesDigestMailerItemWriter implements ItemWriter<UserAccount> {
@Autowired
private MessageRepository messageRepository;
@Autowired
private MailerService mailerService;
@Override
public void write(List<? extends UserAccount> userAccounts) throws Exception {
for (UserAccount userAccount : userAccounts) {
if (userAccount.isEmailNotification()) {
mailerService.mailMessagesDigest(userAccount);
}
for (Message message : userAccount.getReceivedMessages()) {
message.setNotificationSent(true);
messageRepository.save(message); //NOT SAVING!!
}
}
}
}
We finally fixed the issue by adding following code:
@Configuration
public class JpaConfig {
private final DataSource dataSource;
@Autowired
public JpaConfig(@Qualifier("dataSource") DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
@Primary
public JpaTransactionManager jpaTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
... and later, using autowired transaction manager for the step config:
@Autowired
private PlatformTransactionManager transactionManager;
private TaskletStep buildTaskletStep() {
return stepBuilderFactory.get("SendCampaignStep")
.<UserAccount, UserAccount>chunk(pushServiceConfiguration.getCampaignBatchSize())
.reader(userAccountItemReader)
.processor(userAccountItemProcessor)
.writer(userAccountItemWriter)
.transactionManager(transactionManager)
.build();
}
}
... which replaces the default DataSourceTransactionManager
in our extension of DefaultBatchConfigurer
- suddenly, the data is written in the repository correctly.
However, the whole fix feels a bit magical and we could use some official documentation on how to use Spring Boot Data JPA repositories inside Spring Batch writer (or other Spring Batch contexts).
Affects: 3.0.9, 4.0.1
Issue Links:
- BATCH-2294 Overriding transaction management
("depends on")
Referenced from: pull request #620
Backported to: 4.1.0.M3