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.
Asked
Active
Viewed 427 times
0

Archimedes Trajano
- 35,625
- 19
- 175
- 265
-
1As an alternative to prevent passing the `ApplicationContext` around and to prevent fetching beans in an entity-class: is using an [`EntityListener`](https://docs.jboss.org/hibernate/core/4.0/hem/en-US/html/listeners.html) a possibility? – Turing85 Aug 09 '20 at 02:36
-
Then why aren't you just passing the `Support` bean? – chrylis -cautiouslyoptimistic- Aug 09 '20 at 02:38
-
Sounds plausible. I am presuming that EntityListeners can be Spring managed components? – Archimedes Trajano Aug 09 '20 at 02:39
-
@chrylis-cautiouslyoptimistic- what `Support` bean? – Archimedes Trajano Aug 09 '20 at 02:40
-
@ArchimedesTrajano no, does not seem like it. There are some [more or less dirty workarounds](https://stackoverflow.com/questions/12155632/injecting-a-spring-dependency-into-a-jpa-entitylistener) though (some of which - admittedly - could also be used on the entity class instead of the entity listener). – Turing85 Aug 09 '20 at 02:54
-
@ArchimedesTrajano care to explain why you need the `Support` bean in the prepersist-phase? – Turing85 Aug 09 '20 at 02:57
-
You specifically said that the only thing you're doing is `getBean(Support.class)`. Just pass that instance instead of the context. – chrylis -cautiouslyoptimistic- Aug 09 '20 at 03:01
-
I can't get the instance inside a PrePersist method in an Entity class. – Archimedes Trajano Aug 09 '20 at 03:04
-
@ArchimedesTrajano I think what chrysilis meant is: only pass the `Support`-bean around in the `ThreadLocal`. – Turing85 Aug 09 '20 at 03:09
-
Because in case other parts of the code uses self-managed singletons, I can at least migrate them to use the one inside Spring. – Archimedes Trajano Aug 09 '20 at 03:16
-
@Turing85 your original comment about the EntityListener seems to work at least from my SpringData test. Going to see if it works in the app. – Archimedes Trajano Aug 09 '20 at 03:17
-
Though for the OP, it's more of a question whether using a ThreadLocal is safe. – Archimedes Trajano Aug 09 '20 at 03:31
-
@Turing85 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. – Archimedes Trajano Aug 09 '20 at 03:42
1 Answers
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

Martin Frey
- 10,025
- 4
- 25
- 30
-
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. – Archimedes Trajano Aug 09 '20 at 07:20
-
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! – Martin Frey Aug 09 '20 at 08:20
-
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. – Martin Frey Aug 09 '20 at 08:24