Spring-Cloud, Hystrix and JPA - LazyInitializationException - spring

I have the following problem trying to integrate Hystrix into an existent Spring Boot application. I am using boot with spring data (jpa repositories). The structure of the app is pretty simple,
we have Resources -> Services -> Repositories.
I enabled Hystrix support and annotated one of the service methods that returns an entity as follow:
#HystrixCommand(fallback="getDealsFallback")
public Page<Deal> getDeals(...) {
// Get the deals from the Index Server.
return indexServerRepository.findDealsBy(...);
}
public Page<Deal> getDealsFallback(...) {
// If IndexServer is down, query the DB.
return dealsRepository.findDealsBy(...);
}
So this works as expected, the real problem resides actually when I return the Entity to the client. I am using OpenEntityManagerInViewFilter so I can serialize my model with its relations.
When I use #HystrixCommand in my service method, I get a LazyInitializatioException when It tries to serialize.
I know the cause (or at least I suspect what is the problem), and is because Hystrix is executing in another thread
so is not part of the transaction. Changing the Hystrix isolation strategy from THREAD to SEMAPHORE, works correctly since its the same thread, but I understand that is not the correct way to approach the problem.
So my question is, How can I make the Hystrix executing thread be part of the transaction. Is there any workaround that I can apply?
Thanks!

It is a little old thread, but maybe someone meets this problems too. There is an issue in github about this.
The reason is, hystrix will run in separate thread, which is different from where the previous transaction is. So the transaction and serialization for lazy will not work.
And the 'THREAD' is the recommended execution strategy too. So if you want to use both hystrix and transaction, you should use them in 2 level calls. Like, in first level service function, use transaction, and in second level service function, use hystrix and call first level transactional function.

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

Downside/Performace Impact in using reactive spring data (mongdb) with blocking methods

I am very new to reactive programming, and currently working on microservice where in spring mvc is used and Spring Data MongoDb for database connectivity.
As I am going through spring data mongo db docs, there is support for reactive repositories, reative template api etc.
So Is there going to be any downside if I choose to use reactive templates and repository with blocking nature ?
Ex.
reactiveMongoTemplate.add(entity).block()
reactiveMongoTemplate.update(id, entity).block()
Also is there any significant difference with using calls like above than using blocking repository and template api itself ?
The answer depends on which stack you use: Spring WebFlux or Spring Web MVC.
In case of Spring WebFlux the choice is obvious: you have to use ReactiveMongoTemplate and never call block on it, instead return Mono/Flux as you get it from the template.
In case of Spring Web MVC you are free to use both the regular blocking MongoTemplate and ReactiveMongoTemplate with block. Although, in most cases you should go with the good old MongoTemplate for sake of simplicity and performance. ReactiveMongoTemplate has some overhead compared to the blocking MongoTemplate because the reactive types Mono/Flux put some additional pressure on memory.
I can imagine one use case where ReactiveMongoTemplate can provide some advantage even in Spring MVC: when during one HTTP request you have to execute multiple Mono operations concurrently. If you used blocking MongoTemplate then you would need to set up a thread pool and delegate the query execution there. However, with ReactiveMongoTemplate you could use the many operators of Mono and Flux to accomplish this task without worrying about threads, thread pools and scaling issues.
In the traditional programming you usually own the thread that you're running on, in the reactive programming its not the case. This "underlying unit of execution" (cpu resources consumer if you wish) is not yours, but rather a "global" thing that currently happens to execute your task, but can switch to do other things really soon.
So when you block, you say to this "global unit of execution" like "hey, stop doing anything else, wait for me". In the traditional approach, its kind of ok, because you have a thread associated with the current request, other requests (or flows if your system is not web based) are supposed to be executed with other threads taken from a fairly large thread pool. In the reactive system however, its not the case since you're trying to utilize a small amount of these "global units of execution".
Ok, so if you block, the events all over the place will stop emitting and will get start to buffer. And this may lead to the whole system becoming unusable.

Transaction Management while performing Functional Testing Spring Rest Interface

I am trying to write a Functional Testing suite. The test utilizes a bunch of Rest calls to execute workflows (The testing is black-box testing, using the rest interface.). The application under rest is Spring 3 and uses Spring's transaction management(DataSourceTransactionManager). To avoid individual setup and tear-down methods, I was thinking of making the transaction rollback-able.This is accomplished by using #TransactionConfiguration(defaultRollback = true) when doing unit\integration testing, but I am not aware of a straight forward way of doing it, while performing integration testing(since they are individual rest calls).
The application under test is not single threaded and multiple concurrent testing suite might be running at the same time on the same database instance\application.
My preliminary analysis leads me to believe that I should force spring to use the same rollback-able transaction for all the methods in a test suite.(Like using a Factory method that returns a Transaction based on a unique identifier. Passing a unique request parameter and using AOP to somehow inject a transaction for this thread)
Have any of you done anything similar. I would really appreciate some ideas.
Thank you.
Good Question,
I am planning to use transaction in my Junit test too
Please use if the following works for you
#Test
#Transactional
#Rollback(true)
It will take some time for me to implement this in my project but hope, this will help you before I need this.
One more thing which i read is the program is multithreaded.
Do you not wish to use the Isolation level which are provided by spring ? But I think it will be developers who should take care of this.

Is there a better way of detecting if a Spring DB transaction is active than using TransactionSynchronizationManager.isActualTransactionActive()?

I have some legacy code that I am now trying to re-use under Spring. This code is deeply nested in other code so it's not practical to redesign and is called in many situations, only some of which are through Spring. What I'd like to do is to use the Spring transaction if one has been started; otherwise, continue to use the existing (legacy) db connection mechanism. Our first thought was to make our legacy class a bean and use an injected TransactionPlatformManager, but that does not seem to have any methods germane to our situation. Some research showed that Spring has a class called TransactionSynchronizationManager which has a static method isActualTransactionActive(). My testing indicates this method is a reliable way of detecting if a Spring transaction is active:
When called via Spring service without the #Transactional annotation, it returns false
When called via Spring service with #Transactional, it returns true
In my legacy method called the existing way, it returns false
My question: Is there a better way of detecting if a transaction is active?
No better way than the TransactionSynchronizationManager.isActualTransactionActive(). It is the utility method used by spring to handle the transactions. Although it is not advisable to use it within your code, for some specific cases you should - that's why it's public.
Another way might be to use the entity manager / session / connection and check there if there's an existing transaction, but I'd prefer the synchronization manager.

spring + struts2, inject DAO into external thread

I have a web application that uses Struts2 + Spring for the resource injection, basically my DAO. Now I would like to create a thread that periodically polls the database and, if needed, send email notifications to users.
I would like to know how I can implement this in a way that this thread can use my DAO. I haven't been able to manage Spring to inject it the way I've done it. So I would like to hear suggestions and see if someone can point me to the right way.
Right now I have a thread started by a ServletContextListener, that just creates a timer and schedules an action every 5 minutes. But I can't get this action to use my DAO. I don't have any need to use this structure, I'm open to using whichever solution works.
Thanks for your help!
Edit: As axtavt suggested, I used Spring task Execution Scheduling and it works perfectly, the thing is that my task gets injected with the DAO but then I get LazyInitializationException every time I try to access a property of my fetched objects, any suggestion on how to solve that??
Perhaps the best option is to use Spring's own scheduling support, see 25. Task Execution and Scheduling (if necessary - with Quartz, see 25.6 Using the OpenSymphony Quartz Scheduler). This apporach allows you to configure your scheduled action as Spring beans, so you can wire them with other beans such as DAO.
Alternatively, you can use the following to obtain any Spring bean in web application (for example, to obtain DAO from your thread):
WebApplicationContextUtils.getWebApplicationContext(servletContext).getBean(...)

Resources