我正在使用 Spring Boot 项目开发 Spring Batch。 我的问题是,当我如下使用 HibernateItemWriter 时,为什么需要来自 LocalSessionFactoryBean 的 HibernateTransactionManager 和 SessionFactory?
应用程序.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();
}
}
批量配置.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();
}
}
这是因为如果我不包含它,并且使用下面的代码从 EntityManagerFactory 获取 SessionFactory
EntityManagerFactory.unwarp(SessionFactory.class);
我会收到“没有正在进行的交易”错误。但是,当我使用 JpaItemWriter 时,情况并非如此。
但是根据我对Spring Batch的理解,在 block 处理中,已经提供了一个默认的事务管理器。
是否必须从 LocalSessionFactoryBean(来自 hibernate)提供 HibernateTransactionManager 和 SessionFactory 才能使用 HibernateItemWriter?
而且,JpaItemWriter 和 HibernateItemWriter 之间的主要区别是什么? 我已经研究过这两个,Jpa是关于如何使用注释方式指定实体等的规范,hibernate是Jpa的实现之一。不过,我对此不是很清楚。 hibernate 是否比默认 jpa 具有更多功能?比如 SearchCriteria 等?
最佳答案
why HibernateTransactionManager and SessionFactory from LocalSessionFactoryBean are needed when I use HibernateItemWriter
默认情况下,如果您提供一个DataSource
bean,Spring Batch 将使用一个DataSourceTransactionManager
来管理事务。该事务管理器对您的 JPA/Hibernate 上下文一无所知。因此,在后台使用 Hibernate Session
的 HibernateItemWriter
不会“意识到”由 DataSourceTransactionManager
管理的正在进行的事务。因此出现错误:没有正在进行的事务
。
HibernateTransactionManager
使 Hibernate Session
参与 spring 管理的事务。
what is the main difference between JpaItemWriter and HibernateItemWriter?
JpaItemWriter
使用 JPA API(EntityManagerFactory
和 EntityManager
)写入项目。它不使用任何 JPA 提供程序特定的 API。这使得在不更改编写器的情况下切换 JPA 提供程序成为可能。
另一方面,HibernateItemWriter
使用 Hibernate 特定的 API(SessionFactory
和 Session
)并且仅特定于 Hibernate。该组件对于直接使用 hibernate 而不使用 JPA 的应用程序很有用。您可以拥有相同的编写器,但使用来自这些提供程序的特定 API 的另一个 JPA 提供程序,例如 OpenJpaItemWriter
或 EclipseLinkItemWriter
。
注意:有一个类似的问题,我在这里添加它以供引用:Transaction management with Spring Batch
关于java - Spring Batch JpaItemWriter vs HibernateItemWriter 以及为什么在使用 HibernateItemWriter 时需要 HibernateTransactionManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52354066/