How to keep an EntityManager/Session open across multiple transactions in a single thread? - spring

Is there any way to prevent spring data from closing the underlying hibernate session after an #Transactional method in a #Service component? I am writing a simple command line app that reads data from a web service, does some processing and writes to the database. Some of the operations span multiple entities and must be transactional.
However, I am running into too many LazyLoadingExceptions. Apparently the hibernate session is automatically closed by spring after the transaction commits.
In other words, what I am trying to achieve is something like OpenSessionInView, but for a command line app. I could achieve this by using pure JPA and manually handling the entity manager and transactions. However, I would like to know if is there a solution which enables to leverage the spring-data and still achieve the desired behavior.

Related

Kotlin coroutines with Spring JPA blocking repository

I'm trying to use kotlin coroutines with "old-style" Spring JPA repository.
I create a new coroutines scope and run all JPA calls in "async".
I see that even with non reactive JDBC I improve my throughput.
But I wonder, may be exists some coroutines wrapper on Spring JPA repository?
Something created with reflection and Spring "magic"?
First I'd like to clarify one thing to prevent a possible confusion:
If you're using Spring Data JPA, then you should know that this framework uses JDBC driver underhood, that is actually a blocking API, that means all the database calls make the calling thread block until the total result is completed and ready to be consumed.
Having that knowledge I presume you're using suspend functions with coroutines that run on Dispatcher.IO for making such calls.
This dispatcher provides you with one thread (as far as I know, it scales up to 64 threads) for each call. And that thread actually blocks while making your database call, which means coroutines and suspend does not make any magic in this kind of situation except for switching your blocking call to another thread (which eventually will be blocked).
Maybe you should take a look at r2dbc (reactive SQL driver) and use CoroutineCrudRepository<T, ID> from Spring Data instead of using standard JpaRepostitory<T, ID>.
CoroutineCrudRepository<T, ID> has all the methods with suspend which means you can use them for creating "truly" async API without blocking at all.
However, r2dbc may be not suitable for your use cases since it has a lot of limitations, such as mapping relations, caching and etc.
UPDATED:
As far as I know there is no Spring-way to automatically wrap blocking calls, but you can take a look at this library

Transaction management in database when two spring boot application trying to access the same record

Two spring boot applications are connected to the common database.
I just wanted to know, how to handle the transaction if both the application try to update the record at the same time?
Since you seem to use JPA (via Spring Data JPA) there isn't much to handle.
The database itself will prevent two transactions to update the record at the same time. So one will always be first.
If you use optimistic locking (which is the default with JPA) the second transaction will notice the modified row and rollback.
Without that the second transaction will simply overwrite the changes with it's own changes.

Execute a method once every transaction begins inside methods annotated with spring - #Transactional

I want to make a database call before every method within my Spring application annotated with #Transactional started executing transaction.
There are few requirements for this:
This database call has to be part of the actual transaction that is about to begin.
The database connection used for the Transaction has to be same to be used for this database call and should setup some database data before 'real' transaction begins.
Is there something that Spring supports to achieve this goal ? One way I am thinking is to write own Aspect cloning more or less all Transactional code as is. Other way is to write Aspect. Not sure if there are more ways.

Should one close Hibernate Session object every time after performing any CRUD operation?

I am working with enterprise application that uses Spring 3.x with Hibernate annotated programming.I am working with hibernate Session object for performing db operations in my XYZDaoImpl class.
And my doubt is "Is it correct way to close Hibernate Session object every time after performing any CRUD operation?"
If it is not the correct way, please advise me the recommended way of opening/closing of hibernate Session Object.
can you post a bit daoImpl code......
If you use sessionFactory.getCurrentSession(), you will get current session..in this case framework automatically flushed and closed when the transaction ends (commit or rollback).
If you use sessionFactory.openSession(), you have to manage the session yourself and to flush and close it "manually".
No, when using hibernate with spring, you should not (manually) open or close sessions, but let spring manage the hibernate session for you. Spring manages the session as a transactional resource, so you have to configure transaction management correctly.
If you open/close the hibernate session manually, you are hardly using the integration between these two frameworks: the session management is the main feature of the integration.
The only reason to open/close a hibernate session in a spring context is to use the same session to span multiple transactions.

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.

Resources