我正在使用Spring Boot项目进行Spring Batch。我的问题是,当我使用HibernateItemWriter时,为什么需要LocalSessionFactoryBean的HibernateTransactionManager和SessionFactory?
应用程序
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(); } }
这是因为如果我不包含它,并通过使用以下代码从EntityManagerFactory获取SessionFactory的原因
EntityManagerFactory.unwarp(SessionFactory.class);
我将收到“没有正在进行的交易”错误。但是,当我使用JpaItemWriter时,情况并非如此。
但是基于我对Spring Batch的理解,在块处理中,已经提供了默认的事务管理器。
为了使用HibernateItemWriter,是否必须从LocalSessionFactoryBean(来自hibernate)提供HibernateTransactionManager和SessionFactory?
而且,JpaItemWriter和HibernateItemWriter之间的主要区别是什么?我已经做过关于这两个方面的研究,Jpa是关于如何通过使用批注方式指定实体等的规范,而hibernate是Jpa的实现之一。不过,我对此并不十分清楚。hibernate是否比默认的jpa具有更多功能?例如SearchCriteria等?
为什么在使用HibernateItemWriter时需要LocalSessionFactoryBean的HibernateTransactionManager和SessionFactory
默认情况下,如果提供DataSourcebean,Spring Batch将使用DataSourceTransactionManager来管理事务。该事务管理器对您的JPA /hibernate上下文一无所知。因此,HibernateItemWriter在Session后台使用Hibernate 的并没有“意识到” DataSourceTransactionManager。因此,错误:no transaction is in progress。
DataSource
DataSourceTransactionManager
HibernateItemWriter
Session
no transaction is in progress
这HibernateTransactionManager就是使Hibernate Session参与Spring托管事务的原因。
HibernateTransactionManager
JpaItemWriter和HibernateItemWriter之间的主要区别是什么?
在JpaItemWriter使用JPA的API(EntityManagerFactory和EntityManager)写的项目。它不使用任何JPA提供程序特定的API。这样就可以在不更改编写器的情况下切换JPA提供程序。
JpaItemWriter
EntityManagerFactory
EntityManager
在HibernateItemWriter在另一侧使用Hibernate特定API(SessionFactory和Session)和特定于仅hibernate。该组件对于直接使用hibernate而不使用JPA的应用程序很有用。您可能具有相同的编写器,但对于另一个JPA提供程序,例如,OpenJpaItemWriter或EclipseLinkItemWriter使用这些提供程序中的特定API。
SessionFactory
OpenJpaItemWriter
EclipseLinkItemWriter