The scenario (assuming you're familiarized with JPA, Spring, and overall dependency injection)
I have a utility class that is responsible for indexing entities using Lucene. I wanted to add this utility to a JPA listener so that it can create or update the index on the entity in a @PrePersist method. Why this way, and not through a service? Good question. The entity could be persisted directly through a service, directly using Entity Manager, or as a cascade effect when persisting an entity that contains this entity as a property. So, in order to ensure that the index is created/updated, I wanted to provide a listener that would do that prior to saving the entity.
The service class that creates/updates indexes needs to be instantiated by Spring context so that it can have all the indexing dependencies, such as the location of the indexes, so if I wanted a Listener to do this task, I needed to inject this instantiated bean by Spring context into the listener. But, JPA listeners are supposed to be stateless, Entity Manager does not call Spring context to get a reference of an instantiated listener, rather it uses the class specified in the @EntityListeners annotation and instantiates it directly. So, what to do?
If the search service, the service that does the indexing as well, can be declared as static in the Listener, surely it will be accessible when JPA executes a persist of the entity by any method.
public class EntityIndexListener
static private SearchService searchService;
Declaring static is part of the solution, we still need to inject the instantiated class by Spring context to it. For this we create a set method, the same as we would as for any other dependency.
@Autowired(required = true)
public void setSearchService(SearchService searchService)
this.searchService = searchService;