Adding #EnableBatchProcessing causes TransactionRequiredException errors - spring

I have a Spring Boot 2 application (still in the development stage) running well with JPA, hibernate and so on. The single persistence test I've got right now goes thru fine.
However, when I add #EnableBatchProcessing to the main boot class (the one annotated with #SpringBootApplication) I get the following error during the test phase of the maven build:
javax.persistence.TransactionRequiredException: no transaction is in
progress
If I just remove this annotation the test runs successfully again.
I read somewhere that spring Batch uses a different transaction manager than that used for JPA persistence.
How can I fix this issue?
Thanks in advance.

This is very simple.#EnableBatchProcessing annotation causes Spring Batch to automatically register a transaction manager to use for its transactions, and your JpaTransactionManager never gets used.
Reason:
By default, #EnableBatchProcessing triggers the creation of a DataSourceTransactionManager. This transaction manager knows nothing about JPA/Hibernate which causes the problem you're seeing.
Solution:
Now, if you want to change the transaction manager that Spring Batch uses for transactions, you have to implement the interface BatchConfigurer. There is a link to an example where a user has done this. What he is doing is switching the transaction manager to his own transactionmanager.

Related

Configuring Spring Boot to use both H2 AND Oracle at the same time

I am writing a Spring Batch job and don't care about restarts and don't want the hassle of creating, securing and managing an Oracle schema for Spring Batch database objects. H2 on the file system is more than enough for us.
The issue is that I am writing an batch job that needs to connect to an Oracle database and failing miserably just trying to get 2 data sources, transaction managers and entity managers. Right now I am trying two H2 database and haven't even tried configuring Oracle database yet.
I have used two Oracle data sources in other Spring Boot applications successfully in the past but this is my first attempt with Spring Batch that has configuration code to create the data source.
I have tried creating two DataSource, EntityManagerFactoryBean and TransactionManager with one using default spring.datasources configuration, default bean names and #Primary.
I have tried creating just a second DataSource, EntityManagerFactoryBean and TransactionManager with different bean names. This seems to have an issue that the TransactionManager orEntityManager is already assigned to the thread.
I have tried creating a dataSource for batch but run into circular bean creation errors.
I have tried creating a BatchConfigurer and that runs into circular bean creation errors.
I have tried creating a JobRepositoryFactoryBean but a default one is still created.
I have tried using a #PersistenceContext on my #Entity classes.
It shouldn't be this hard so I must be missing something. Any help would be appreciated.
Thanks, Wes.
I think I have some success. I am able to eventually run the batch job using Spring Boot 2.2.0 and Spring Batch 4.2.0 but I have to wait for a 5 minute timeout while creating the Entity Manager for H2 for the Spring Batch repository. The Oracle Entity Manager is registered really quickly and before the H2 Entity Manager despite the H2 Entity Manager being #Primary.
I have a separate configuration class for each of my two DataSources. Each one is annotated with #Configuration, #EnableTransactionManagement and #EnableJPARepository.
The one for Spring Batch is using the standard bean names, dataSource, entityManagerFactory and transactionManager. Each #Bean is annotated with #Primary.
One setting that I needed was to add a .packages("org") to the entityManagerFactory bean. This would pick up all of org.springframework including Spring Batch.
The only other real change I have made from common implementations is to set the dialect in the JPA Properties of the Entity Manager.
I needed the spring.main.allow-bean-definition-overriding: true setting.
There may be more to my solution that I should share but I have been at this for a couple of days and have gone in circles. I even remember getting what appeared as a hung process time and and killed the job thinking it was hung. I may have had some "success" early on but just was too quick to kill the execution.
I would still like to know why it is taking so long to create the H2 Entity Manager.
Thanks, Wes.

Spring DataSourceTransactionManager makes saves to fail

I am working on a Spring Boot (2.0.2.RELEASE) application. Recently I enabled transaction management and created a DataSourceTransactionManager in the app configuration. We are using Spring Data JPA with Hibernate.
I noticed some time later that many (but not all) saves were not actual happening, but all log entries state everything was fine. Only affected saves were made by a Quartz job. Some of them were successful, but most of them not. No errors in the logs.
I since removed the transaction manager and now everything works as expected.
I assume now that DataSourceTransactionManager isn't meant to be used with JPA or Hibernate. I still don't know what to use and why this error happened.
Any help is appreciated.

Using multiple embedded datastores with Spring Boot

I'm trying to set up a Spring Boot application using Spring Data JPA, Neo4J and MongoDB. The goal is to be able to save different entities in each datastore, as well as using cross-store entities.
The project seems to work well with each store individually, but saving a JPA entity raises this exception :
org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call; nested exception is javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
This exception is not raised if I remove all neo4J and mongoDB related code.
Here is a link to the project on github :
GitHub
I managed to get it working by using the configuration of this project.
It looks like I had to add an "transactionManagerRef" attribute to the #EnableJpaRepositories annotation, a bit more configuration for Transition Managers, and modify some dependencies.

Making specific method non transactional in Spring

I have a spring application which is based on Spring Batch. By default spring batch introduces transaction for its steps (i.e. at reader,writer and processor) . There are certain stages where I don't really need transaction to be enabled. Because transaction is enabled unnecessary for these methods its giving me some runtime errors as I am making call to two different databases in one method.
Is there any annotation which spring provides to DISABLE transaction for a specific set of methods ?
OR is there anything available in spring batch which can allow me to get rid of transaction either completely or declarative
I am even open to the solution which can disable transaction globally.
Any link , paper will greatly be appreciated.
Thanks in advance
Samir
Spring Batch is inherently transactional. Even if your datasources are not transactional, the semantics of the JobRepository require it. The closest you can get with Spring Batch and not being transactional is using the ResourcelessTransactionManager. This transaction manager is essentially a no-op transaction manager that just keeps track of if an operation is within the scope of a transaction or not.

spring 3 configuration without transaction manager

How to not use (disable) transaction manager in spring configuration?
I'm doing simple app that will add rows to database, so no need in any transactions.
So, is it possible configure in xml, not to create any transaction managers?
PS: i use hibernate if this matters anyhow.
If you don't configure a Transaction Manager, neither will Spring. Just don't add any <tx:> tags and don't configure any PlatformTransactionManager beans (in your case HibernateTransactionManager).

Resources