title: Transaction management with Spring Batch
body: <p>I am discovering actually Spring and I am able to setup some jobs. Now, I would like to save my imported datas in a database using Hibernate/JPA and I keep getting this error : </p>
  
  <pre><code>14:46:43.500 [main] ERROR o.s.b.core.step.AbstractStep   - Encountered an error executing the step javax.persistence.TransactionRequiredException: no transaction is in progress
  </code></pre>
  
  <p>I see that the problem is with the transaction. Here is my spring java config for the <code>entityManager</code> and the <code>transactionManager</code> :</p>
  
  <pre><code> @Configuration
  public class PersistenceSpringConfig implements EnvironmentAware
  {
  
  
      @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception
    {
      // Initializes the entity manager
      LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
      factoryBean.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
      factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
      factoryBean.setDataSource(dataSource());
  
      // Scans the database model
      factoryBean.setPackagesToScan(EntiteJuridiqueJPA.class.getPackage().getName());
  
      // Defines the Hibernate properties
      Properties jpaProperties = new Properties();
      jpaProperties.setProperty("hibernate.show_sql", "false");
      jpaProperties.setProperty("hibernate.format_sql", "false");
      String connectionURL = "jdbc:h2:file:" + getDatabaseLocation();
      jpaProperties.setProperty("hibernate.connection.url", connectionURL);
      jpaProperties.setProperty("hibernate.connection.username", "sa");
      jpaProperties.setProperty("hibernate.connection.driver_class", "org.h2.Driver");
      jpaProperties.setProperty("hibernate.dialect", H2Dialect.class.getName());
      jpaProperties.setProperty("hibernate.hbm2ddl.auto", "create");
      jpaProperties.setProperty("hibernate.hbm2ddl.import_files_sql_extractor", "org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor");
      jpaProperties.setProperty("hibernate.hbm2ddl.import_files",
          "org/springframework/batch/core/schema-drop-h2.sql,org/springframework/batch/core/schema-h2.sql");
  
      factoryBean.setJpaProperties(jpaProperties);
      return factoryBean;
    }
  
  
  
   @Bean
    public PlatformTransactionManager transactionManager2() throws Exception
    {
      EntityManagerFactory object = entityManagerFactory().getObject();
      JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(object);
      return jpaTransactionManager;
    }
  </code></pre>
  
  <p>I am using the <a href="http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/item/database/JpaItemWriter.html" rel="noreferrer">JpaItemWriter</a> to store the datas in the database : </p>
  
  <pre><code> @Bean
    public ItemWriter&lt;EntiteJuridiqueJPA&gt; writer()
    {
      JpaItemWriter&lt;EntiteJuridiqueJPA&gt; writer = new JpaItemWriter&lt;EntiteJuridiqueJPA&gt;();    
      writer.setEntityManagerFactory(entityManagerFactory.getObject());
      return writer;
    }
  </code></pre>
  
  <p>This is the code that causes the exception : <code>javax.persistence.TransactionRequiredException: no transaction is in progress</code></p>
  
  <p>Any idea to how to solve this problem?</p>
  
  <p>[Edit] I am putting also the Job definition and the step definition. All my Spring configuration is written in Java. </p>
  
  <pre><code> @Configuration
  @EnableBatchProcessing
  @Import(PersistenceSpringConfig.class)
  public class BatchSpringConfig
  {
    @Autowired
    private JobBuilderFactory  jobBuilders;
  
    @Autowired
    private StepBuilderFactory stepBuilders;
  
    @Autowired
    private DataSource         dataSource;
  
    @Autowired
    private LocalContainerEntityManagerFactoryBean entityManagerFactory;
  
    @Bean
    public Step step()
    {
      return stepBuilders.get("step").&lt;EntiteJuridique, EntiteJuridiqueJPA&gt; chunk(5).reader(cvsReader(null))
          .processor(processor()).writer(writer()).listener(processListener()).build();
    }
  
    @Bean
    @StepScope
    public FlatFileItemReader&lt;EntiteJuridique&gt; cvsReader(@Value("#{jobParameters[input]}") String input)
    {
      FlatFileItemReader&lt;EntiteJuridique&gt; flatFileReader = new FlatFileItemReader&lt;EntiteJuridique&gt;();
      flatFileReader.setLineMapper(lineMapper());
      flatFileReader.setResource(new ClassPathResource(input));
      return flatFileReader;
    }
  
    @Bean
    public LineMapper&lt;EntiteJuridique&gt; lineMapper()
    {
      DefaultLineMapper&lt;EntiteJuridique&gt; lineMapper = new DefaultLineMapper&lt;EntiteJuridique&gt;();
      DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
      lineTokenizer.setDelimiter(";");
      lineTokenizer.setNames(new String[] { "MEGA_ENTITE", "PORTEFEUILLE", "MEGA_ENTITE", "Libellé" });
  
      BeanWrapperFieldSetMapper&lt;EntiteJuridique&gt; fieldSetMapper = new BeanWrapperFieldSetMapper&lt;EntiteJuridique&gt;();
      fieldSetMapper.setTargetType(EntiteJuridique.class);
  
      lineMapper.setLineTokenizer(lineTokenizer);
      lineMapper.setFieldSetMapper(fieldSetMapper);
  
      return lineMapper;
    }
  
    @Bean
    public Job dataInitializer()
    {
      return jobBuilders.get("dataInitializer").listener(protocolListener()).start(step()).build();
    }
  
    @Bean
    public ItemProcessor&lt;EntiteJuridique, EntiteJuridiqueJPA&gt; processor()
    {
      return new EntiteJuridiqueProcessor();
    }
  
    @Bean
    public ItemWriter&lt;EntiteJuridiqueJPA&gt; writer()
    {
      JpaItemWriter&lt;EntiteJuridiqueJPA&gt; writer = new JpaItemWriter&lt;EntiteJuridiqueJPA&gt;();    
      writer.setEntityManagerFactory(entityManagerFactory.getObject());
      return writer;
      // return new EntiteJuridiqueWriter();
    }
  
    @Bean
    public ProtocolListener protocolListener()
    {
      return new ProtocolListener();
    }
  
    @Bean
    public CSVProcessListener processListener()
    {
      return new CSVProcessListener();
    }
  
    @Bean
    public PlatformTransactionManager transactionManager2() throws Exception
    {
      EntityManagerFactory object = entityManagerFactory.getObject();
      JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(object);
      return jpaTransactionManager;
    }
  </code></pre>
  
  <p><strong>[EDIT]</strong> I am still stuck with this problem. I have followed the suggestions of @Sean Patrick Floyd and @bellabax by setting a transaction manager for the stepBuilders, but I still get the same exception. I have tested my entityManager independtly of spring-batch and I am able to store any data in the database. </p>
  
  <p>But, when using the same entity manager with spring batch, I have this exception. </p>
  
  <p>Anyone can give more insights how transactions are managed within spring batch? Thx for your help?</p>