Я работаю над Spring Batch с проектом Spring Boot. Мой вопрос: зачем нужны HibernateTransactionManager и SessionFactory из LocalSessionFactoryBean, когда я использую HibernateItemWriter, как показано ниже?
Application.java
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBuilder;
import org.springframework.transaction.PlatformTransactionManager;
@SpringBootApplication
@EnableBatchProcessing
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
@Bean
public PlatformTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory(null));
return transactionManager;
}
@Bean
public SessionFactory sessionFactory(DataSource datasource) {
Properties properties = new Properties();
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
return new LocalSessionFactoryBuilder(datasource).scanPackages("hello")
.addProperties(properties)
.buildSessionFactory();
}
}
BatchConfiguration.java
import org.hibernate.SessionFactory;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.HibernateItemWriter;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import
org.springframework.batch.item.file.transform.DelimitedLineAggregator;
import org.springframework.batch.item.file.transform.FieldExtractor;
import org.springframework.batch.item.file.transform.LineAggregator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.web.client.RestTemplate;
@Configuration
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autowired
public RestTemplate restTemplate;
@Autowired
public PlatformTransactionManager tManager;
@Value("${file.name}")
public String fileName;
@Bean
@StepScope
public RestItemReader reader2() {
return new RestItemReader(restTemplate);
}
@Bean
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
@Bean
public HibernateItemWriter<Person> hibernateWriter(SessionFactory emf) {
HibernateItemWriter<Person> writer = new HibernateItemWriter<>();
writer.setSessionFactory(emf);
return writer;
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.transactionManager(tManager)
.<KarvyFundInfoModel, Person> chunk(2)
.reader(reader2())
.processor(new PersonItemProcessor())
.writer(hibernateWriter(null))
.build();
}
}
Это потому, что если бы я его не включил, и получив SessionFactory из EntityManagerFactory, используя код, как показано ниже
EntityManagerFactory.unwarp(SessionFactory.class);
Я получаю сообщение об ошибке «транзакция не выполняется». Однако это не тот случай, когда я использую JpaItemWriter.
Однако, исходя из моего понимания Spring Batch, при обработке фрагментов менеджер транзакций по умолчанию уже предоставляется.
Обязательно ли предоставлять HibernateTransactionManager и SessionFactory из LocalSessionFactoryBean (из спящего режима), чтобы использовать HibernateItemWriter?
И в чем основное различие между JpaItemWriter и HibernateItemWriter? Я уже проводил исследования по этим двум вопросам, Jpa - это спецификация того, как указать сущность и т. д. С использованием способа аннотации, а спящий режим - одна из реализаций Jpa. Тем не менее, я не очень понимаю это. Имеет ли спящий режим больше функций по сравнению с jpa по умолчанию? Например, SearchCriteria и т. д.?




why HibernateTransactionManager and SessionFactory from LocalSessionFactoryBean are needed when I use HibernateItemWriter
По умолчанию, если вы предоставляете bean-компонент DataSource, Spring Batch будет использовать DataSourceTransactionManager для управления транзакциями. Этот менеджер транзакций ничего не знает о вашем контексте JPA / Hibernate. Таким образом, HibernateItemWriter, который использует Hibernate Session за сценой, не «знает» о текущей транзакции, управляемой DataSourceTransactionManager. Отсюда ошибка: no transaction is in progress.
HibernateTransactionManager - это то, что заставляет Hibernate Session участвовать в весенних управляемых транзакциях.
what is the main difference between JpaItemWriter and HibernateItemWriter?
JpaItemWriter использует API-интерфейсы JPA (EntityManagerFactory и EntityManager) для записи элементов. Он не использует API-интерфейсы, специфичные для JPA-провайдеров. Это позволяет переключать провайдера JPA без изменения вашего писателя.
HibernateItemWriter с другой стороны использует специальные API-интерфейсы Hibernate (SessionFactory и Session) и относится только к Hibernate. Этот компонент может быть полезен для приложений, использующих спящий режим напрямую, без использования JPA. У вас может быть такой же писатель, но для другого поставщика JPA, такого как OpenJpaItemWriter или EclipseLinkItemWriter, который использует определенные API от этих поставщиков.
NB: Есть вопрос, похожий на этот, я добавляю его сюда для справки: Управление транзакциями с помощью Spring Batch
Хорошее объяснение! Большое спасибо!