【发布时间】:2019-05-09 03:17:20
【问题描述】:
我目前正在开发一个应用程序,该应用程序处理一个大文件文件并将其存储在一个带有 Spring Batch 的 JPA 数据库中。这应要求发生。批处理完成后,您可以使用相同的服务来获取有关根据请求加载到数据库中的数据的信息。
这些请求单独工作,但如果我尝试将它们组合起来,当通过 TestEntityManger 持久化和刷新数据库中的实体时,我的单元测试会出错。
错误是:
javax.persistence.TransactionRequiredException: no transaction is in progress
批处理完成后数据库会话似乎没有正确关闭。但这应该由春季批次处理,但事实并非如此。我的配置有问题还是需要手动关闭会话?如果是这样,我该怎么做?
我的批处理配置如下:
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autowired
public CustomerRepository customerRepository;
@Bean
public JsonItemReader<Klant> jsonItemReader() {
return new JsonItemReaderBuilder<Klant>()
.jsonObjectReader(new JacksonJsonObjectReader<> (Klant.class))
.resource(new ClassPathResource("sample-data.json"))
.name("tradeJsonItemReader")
.build();
}
@Bean
public KlantItemProcessor processor() {
return new KlantItemProcessor();
}
@Bean
public RepositoryItemWriter<Customer> writer(){
return new RepositoryItemWriterBuilder<Customer>()
.methodName("save")
.repository(customerRepository)
.build();
}
@Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1)
.end()
.build();
}
@Bean
public Step step1(RepositoryItemWriter<Customer> writer) {
return stepBuilderFactory.get("step1")
.<Klant, Customer> chunk(1)
.reader(jsonItemReader())
.processor(processor())
.writer(writer)
.build();
}
}
有人可以向我解释我可以做些什么来解决它吗?
存储库代码:
public interface CustomerRepository extends
PagingAndSortingRepository<Customer, String> {
Optional<Customer> findCustomerByCustomerProspectNumber(int customerProspectNumber);
}
单元测试:
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@DataJpaTest
@Import({SecurityAutoConfiguration.class})
public abstract class BaseAccountRepositoryTest {
private static final String[] DATA = {
"/backend/model/exampleCustomer.json"
};
@Autowired
protected TestEntityManager em;
@Autowired
protected CustomerRepository customerRepository;
@Autowired
protected TransactionRepository transactionRepository;
@Autowired
protected AccountRepository accountRepository;
@Before
public void init(){
List<Customer> customersList = GsonUtil.fromJson(Customer.class, DATA);
customersList.forEach(customer -> {
em.persistAndFlush(customer);
customer.getAccounts().forEach(account -> {
account.setCustomer(customer);
em.persistAndFlush(account);
account.getTransactions().forEach(transaction -> {
transaction.setAccount(account);
em.persistAndFlush(transaction);
});
});
});
assertEquals(DATA.length, customerRepository.count());
assertEquals(1, transactionRepository.count());
assertEquals(1, accountRepository.count());
}
}
【问题讨论】:
-
嗨 Ylona 你能在 github 上分享你的代码吗?我解决了类似的问题,但在很久以前,我需要一些上下文
-
你也在你的存储库上使用@Transactional 吗?
-
我添加了更多代码。目前我无法分享完整的代码,因为我们使用了很多内部公司包。我将尝试在我可以分享的项目中重现该问题。我没有在单元测试的存储库中使用事务。仅在直接使用存储库的代码类中。我已经尝试将它放在存储库类中,但这并没有改变任何东西。
标签: spring spring-data-jpa spring-batch