hamwac5
hamwac5

Reputation: 99

how to fix no transaction is in progress in spring batch

when I try persist some data that I recovered from my csv file on my database using my job processor in spring batch this error appear in the console , for my dao i'm using hibernate

I already tried 2 methode but the same probleme !

first :

    Session session = factory.getCurrentSession();
    session.saveOrUpdate(p);

second :

    Session session = factory.openSession();
    session.beginTransaction();
    session.save(p);
    session.getTransaction().commit();
    session.close();

data source in my spring xml config : all my spring xml config here https://pastebin.com/RZPr1GKL

<bean name="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/yassir" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>


    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>tp.entities.Personne</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>


    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven />

the error : javax.persistence.TransactionRequiredException: no transaction is in progress at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3450) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1418) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1414) ...

Upvotes: 2

Views: 16572

Answers (2)

Bharathiraja
Bharathiraja

Reputation: 812

When we use spring batch especially for tasklet in spring boot project @EnableBatchProcessing annotations will create its own transactions (Spring Batch Transactions) for its default tables. Hence if you want to perform any insert, update or delete in your application tables(acutal table performing CRUD). We have to explicitly mention JpaTransactionManager instead of default spring batch transactions.

@Configuration
@EnableBatchProcessing
public class MyJob extends DefaultBatchConfigurer {
       
       @Autowired
       private DataSource dataSource;

       @Bean
       @Primary
       public JpaTransactionManager jpaTransactionManager() {
            final JpaTransactionManager tm = new JpaTransactionManager();
            tm.setDataSource(dataSource);
            return tm;
       }
}

@Primary is most important one to mention else two transaction managers will be loaded. Mention jpaTransactionManager() in your job.

return stepBuilderFactory.get("stepOne")
                .transactionManager(jpaTransactionManager())
                .<DetailDTO,DetailDTO>chunk(100)
                .reader(reportReader) 
                .processor(reportProcessor)
                .writer(reportWriter)
                .build();

Error which i got - Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress.

Click Up Vote if this is useful for you.

Upvotes: 8

Mahmoud Ben Hassine
Mahmoud Ben Hassine

Reputation: 31590

You configured Spring Batch to use a DataSourceTransactionManager to drive transactions. This transaction manager knows nothing about your Hibernate context. You need to use the HibernateTransactionManager to make the Hibernate Session in your writer participate in Spring Batch managed transactions.

I would also recommend to use the HibernateItemWriter instead of creating a custom writer (PersonneWriter) and manually creating the session and managing transactions.

A similar question/answer can be found here: Spring Batch JpaItemWriter vs HibernateItemWriter and why HibernateTransactionManager is needed when HibernateItemWriter is used

Hope this helps.

Upvotes: 5

Related Questions