Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA Repositories and blocking I/O

I'm having a problem where I need to perform several slow HTTP requests on a separate thread after having written to the database using a JpaRepository. The problem is that doActualJob() blocks while waiting for a series of futures to resolve. This seems to prevent the underlying Hibernate session from closing, causing the application to run out of connections shortly after.

How do I write this function so the database connection isn't kept open while doing the blocking I/O? Is it even possible using JpaRepositories, or do I need to use a lower level API like EntityManager/SessionFactory?

@Service
class SomeJobRunner {

    private final SomeJobRepository mSomeJobRepository; //extends JpaRepository

    @AutoWired
    public SomeJobRunner(final SomeJobRepository someJobRepository) {
        mSomeJobRepository = someJobRepository;
    }

    @Async
    public void doSlowJob(final long someJobId) {
        SomeJob someJob = mSomeJobRepository.findOne(someJobId);
        someJob.setJobStarted(Instant.now());
        mSomeJobRepository.saveAndFlush(someJob);

        doActualjob(); // Synchronous job doing several requests using Unirest in series

        someJob = mSomeJobRepository.findOne(someJobId);
        someJob.setJobEnded(Instant.now());
        mSomeJobRepository.saveAndFlush(someJob);
}
like image 270
Mattias Hermansson Avatar asked Sep 17 '25 16:09

Mattias Hermansson


1 Answers

Well - non-blocking database IO is not possible in Java/JDBC world in a standard way .To put it simply - your Spring data repository would be eventually using JPA ORM Implementation ( likes of Hibernate) which in turn will use JDBC to interact with the database which is essentially blocking in nature. There is work being done on this currently by Oracle (Asynchronous Database Access API ) to provide a similar API as JDBC but non-blocking. They intend to propose this as a standard. Also there is an exciting and parallel effort by Spring guys on this namely R2DBC – Reactive Relational Database Connectivity. They have actually integrated this with Spring data as well (link) so that may help you integrate in your solution. A good tutorial by Spring on this can be found here.

EDIT: As of 2022 Hibernate has reactive option as well

like image 171
Shailendra Avatar answered Sep 19 '25 05:09

Shailendra