title: Spring Batch JpaItemWriter vs HibernateItemWriter and why HibernateTransactionManager is needed when HibernateItemWriter is used
body: <p>I'm working on Spring Batch with Spring Boot project. 
  My question is, why HibernateTransactionManager and SessionFactory from LocalSessionFactoryBean are needed when I use HibernateItemWriter as below? </p>
  
  <p>Application.java</p>
  
  <pre><code>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();
  }
  }
  </code></pre>
  
  <p>BatchConfiguration.java</p>
  
  <pre><code>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&lt;Person&gt; hibernateWriter(SessionFactory emf) {
      HibernateItemWriter&lt;Person&gt; writer = new HibernateItemWriter&lt;&gt;();
      writer.setSessionFactory(emf);
      return writer;
  }
  
  
  @Bean
  public Step step1() {
      return stepBuilderFactory.get("step1")
              .transactionManager(tManager)
          .&lt;KarvyFundInfoModel, Person&gt; chunk(2)
          .reader(reader2())
          .processor(new PersonItemProcessor())
          .writer(hibernateWriter(null))
          .build();
  }
  }
  </code></pre>
  
  <p>This is because if I didn't include it, and by getting SessionFactory from EntityManagerFactory using code as below</p>
  
  <pre><code>EntityManagerFactory.unwarp(SessionFactory.class);
  </code></pre>
  
  <p>I will get "no transaction is in progress" error. However, this is not the case when I use JpaItemWriter.</p>
  
  <p>However based on my understanding on Spring Batch, in chunk processing, a default transaction manager is already provided.</p>
  
  <p>Is it a must to provide HibernateTransactionManager and SessionFactory from LocalSessionFactoryBean(from hibernate) in order to use HibernateItemWriter?</p>
  
  <p>And, what is the main difference between JpaItemWriter and HibernateItemWriter?
  I already did research regarding these two, Jpa is a specification on how to specify entity etc. by using annotation way and hibernate is one of the implementations of Jpa. Still, I'm not very clear on this. Is it hibernate has more features over default jpa? Such as SearchCriteria etc?</p>