Я использую JpaPagingItemReader для чтения, JpaTransactionManager< /code> для управления транзакциями и SimpleAsyncTaskExecutor для параллельной обработки.
Настройка:
- Spring Boot: 3.3.4
- Spring Batch: 5.1.2
- Диспетчер транзакций: JpaTransactionManager
Исполнитель задач: SimpleAsyncTaskExecutor
Код: Выделить всё
@Entity
public class Customer {
@Id
private Long id;
@ManyToOne
@JoinColumn(name = "order_id")
private Order order;
}
Отношение @OneToMany по умолчанию равно FetchType.LAZY .
Код: Выделить всё
@Entity
public class Order {
@Id
private Long id;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List types;
// Other @OneToMany collection fields...
}
Я использую JpaPagingItemReader и ItemProcessor. Этот шаг распараллеливается с помощью SimpleAsyncTaskExecutor.
Код: Выделить всё
@Bean
public JpaPagingItemReader customerItemReader(EntityManagerFactory entityManagerFactory) {
return new JpaPagingItemReaderBuilder()
.name("customerItemReader")
.entityManagerFactory(entityManagerFactory)
.queryString("SELECT c FROM Customer c")
.pageSize(100)
.build();
}
@Bean
public Step processCustomersStep(JobRepository jobRepository,
PlatformTransactionManager transactionManager,
JpaPagingItemReader customerItemReader,
ItemProcessor customerItemProcessor,
ItemWriter customerItemWriter,
TaskExecutor taskExecutor) {
return new StepBuilder("processCustomersStep", jobRepository)
.chunk(100, transactionManager)
.reader(customerItemReader)
.processor(customerItemProcessor)
.writer(customerItemWriter)
.taskExecutor(taskExecutor)
.build();
}
Код: Выделить всё
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.myapp.Order.types: could not initialize proxy - no Session
- Извлечение с помощью JOIN FETCH : Я не могу использовать JOIN FETCH, потому что
содержит несколько вложенных коллекций с отложенной загрузкой,
Код: Выделить всё
OrderОбъект
что приводит к большим и неэффективным запросам. - Поскольку я использую JpaTransactionManager, я предполагал, что он справится
область транзакции правильно, но исключение LazyInitializationException
по-прежнему возникает при доступе к вложенным лениво загруженным коллекциям в
ItemProcessor.
Как предотвратить исключение LazyInitializationException на этапе Spring Batch с параллельными фрагментами, когда используя JpaPagingItemReader и JpaTransactionManager?
Должен ли я обрабатывать EntityManager по-другому или есть другой шаблон для обработки сущностей с вложенными коллекциями с отложенной загрузкой в параллельно?
Подробнее здесь: https://stackoverflow.com/questions/790 ... arallel-ch
Мобильная версия