Is it safe to pass in the Spring Application Context into a ThreadLocal associated with a request?
Asked Answered
F

1

0

In JPA I want to utilize the PrePersist annotated method to perform some operations but rather than making the things it needs to implement the Singleton pattern (with getInstance() etc.) I was wondering if I pass the Spring ApplicationContext through a ThreadLocal (which I close release after the request) would be a safe thing to do so. I am only using it primarilly to getBean(Support.class) and not modifying the context.

Flaviaflavian answered 9/8, 2020 at 2:21 Comment(13)
As an alternative to prevent passing the ApplicationContext around and to prevent fetching beans in an entity-class: is using an EntityListener a possibility?Clique
Then why aren't you just passing the Support bean?Wavellite
Sounds plausible. I am presuming that EntityListeners can be Spring managed components?Flaviaflavian
@chrylis-cautiouslyoptimistic- what Support bean?Flaviaflavian
@ArchimedesTrajano no, does not seem like it. There are some more or less dirty workarounds though (some of which - admittedly - could also be used on the entity class instead of the entity listener).Clique
@ArchimedesTrajano care to explain why you need the Support bean in the prepersist-phase?Clique
You specifically said that the only thing you're doing is getBean(Support.class). Just pass that instance instead of the context.Wavellite
I can't get the instance inside a PrePersist method in an Entity class.Flaviaflavian
@ArchimedesTrajano I think what chrysilis meant is: only pass the Support-bean around in the ThreadLocal.Clique
Because in case other parts of the code uses self-managed singletons, I can at least migrate them to use the one inside Spring.Flaviaflavian
@Clique your original comment about the EntityListener seems to work at least from my SpringData test. Going to see if it works in the app.Flaviaflavian
Though for the OP, it's more of a question whether using a ThreadLocal is safe.Flaviaflavian
@Clique seems the EntityListener works in a proper SpringBoot environment, but not in a legacy system where Spring was shoehorned in (maybe part of the shoehorn didn't handle some things, but basically the entity listener is called by Hibernate without the Spring proxies.Flaviaflavian
L
1

If you can use Hibernate event listeners I wrote once a response with a possible approach for Spring managed event listeners here:

Using Hibernate 4's Integrator pattern and Spring's dependency injection

Lita answered 9/8, 2020 at 7:16 Comment(3)
Thanks, though I gave a context of JPA, my question is whether there may be any ill effects of using ThreadLocal to pass the ApplicationContext.Flaviaflavian
You dont need to pass the ApplicationContext in a threadlocal. You can just create a class with a static member (autowired with the setter) to retrieve the context. You need to be aware that the context can be missing on startup though!Lita
Other than that you need to be aware that you can not do anything you like in those listeners. Creating other entities for example might fail as the whole hibernate process will not take place recursively and another prepersist will not be called. At least it was like that with Hibernate 4. The documentation mentions some pitfalls if I remember right.Lita

© 2022 - 2025 — McMap. All rights reserved.