2

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) ...

hamwac5
  • 99
  • 1
  • 2
  • 14
  • 1. Since you're using Hibernate, you should use a HibernateTransactionManager. 2. Since you're using annotation-based transactions, the bean method that is supposed to be transactional should be annotated with `@Transactional`. https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#orm-hibernate – JB Nizet Dec 28 '18 at 16:33
  • I added the annotation @Transactional public void savePersonne(Personne p) { Session session = factory.getCurrentSession(); session.saveOrUpdate(p); } but the problem is still there – hamwac5 Dec 28 '18 at 16:42
  • Well, apparently you read the second part of my comment, but not the first one. – JB Nizet Dec 28 '18 at 16:42
  • how to use a HibernateTransactionManager. ? – hamwac5 Dec 28 '18 at 16:58
  • As shown in the link I posted in my first comment. – JB Nizet Dec 28 '18 at 16:58
  • but i already have DataSourceTransactionManager ? – hamwac5 Dec 28 '18 at 17:13
  • Which is helpful if you use JDBC to access your database. But you're using Hibernate. – JB Nizet Dec 28 '18 at 17:13
  • You are using the wrong transaction manager, use the transaction manager that matches your persistence technology. In your case you should be using the `HibernateTransactionManager` (from the same package as your `LocalSessionFactoryBean`). That will make the first approach work (at least it should, if it doesn't you are doing things you shouldn't be doing in the first place). – M. Deinum Dec 28 '18 at 18:43

2 Answers2

6

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.

Bharathiraja
  • 714
  • 1
  • 12
  • 20
  • still same problem javax.persistence.TransactionRequiredException: no transaction is in progress at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3466) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final] at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1426) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final] at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1422) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final] – Szymon Roziewski Jul 23 '21 at 14:33
4

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.

Mahmoud Ben Hassine
  • 28,519
  • 3
  • 32
  • 50
  • thanks when i'm using HibernateTransactionManager it work : – hamwac5 Dec 28 '18 at 21:16
  • so we just need to create bean, rest spring will take care? or do we need to specify it while running jobs – user124 Apr 11 '21 at 21:12
  • @user124 Creating a transaction manager bean is not enough. If you want to use a custom transaction manager, you need to provide a `BatchConfigurer` bean and override `getTransactionManager` to return your transaction manager, see: https://docs.spring.io/spring-batch/docs/4.3.x/reference/html/job.html#javaConfig. – Mahmoud Ben Hassine Apr 12 '21 at 11:46
  • can u help here https://stackoverflow.com/questions/67056392/how-to-add-hibernatetransaction-manager-to-spring-batch – user124 Apr 12 '21 at 12:03
  • but the link you mentioned in the answer, it provides transaction manager when configuring step byt .transactionManager(tManager), it is not overriding BatchConfigurer as you are saying? – user124 Apr 13 '21 at 21:12
  • @user124 which link are you referring to? As requested, I added a comment on your question here https://stackoverflow.com/questions/67056392/how-to-add-hibernatetransaction-manager-to-spring-batch so please reply on that question. It is not efficient to cross links like this because no one can be sure we are talking about the same thing. Thank you. – Mahmoud Ben Hassine Apr 14 '21 at 07:39
  • Sorry if you are confused. I am referring to current question only. I will add queries related to other question on that thread only. What I am saying is the link you mentioned in the answer in this post only ": Spring Batch JpaItemWriter vs HibernateItemWriter and why HibernateTransactionManager is needed when HibernateItemWriter is used" . it is not using BatchConfigurer as you are saying? – user124 Apr 14 '21 at 19:35