I want to write my own JPA entity listener which will perform some actions before an entity will be created/updated/deleted:
public class MyEntityListener {
@PrePersist
public void beforeCreate(Object entity) {
...
}
@PreUpdate
public void beforeUpdate(Object entity) {
...
}
@PreRemove
public void beforeDelete(Object entity) {
...
}
}
But I also need a Spring-managed bean instance to perform such actions:
public class MyEntityListener {
@PrePersist
public void beforeCreate(Object entity) {
someSpringManagedBean.doSomething("Creating an entity: " + entity);
}
...
}
I know that there are problems with injecting Spring-managed beans into JPA entity listeners (Injecting a Spring dependency into a JPA EntityListener), so this code will not work:
@Component
public class MyEntityListener {
@Autowired
private SomeSpringManagedBean someSpringManagedBean;
....
}
But I have found that Spring's AuditingEntityListener
uses a plain setter (but also @Configurable
and ObjectFactory
) for the same purpose:
@Configurable
public class AuditingEntityListener {
private ObjectFactory<AuditingHandler> handler;
public void setAuditingHandler(ObjectFactory<AuditingHandler> auditingHandler) {
...
this.handler = auditingHandler;
}
@PrePersist
public void touchForCreate(Object target) {
if (handler != null) {
handler.getObject().markCreated(target);
}
}
@PreUpdate
public void touchForUpdate(Object target) {
if (handler != null) {
handler.getObject().markModified(target);
}
}
...
}
AuditingHandler
is a Spring-managed bean (I have tried to inject it in my own Spring-managed bean and it works fine). Looks like Spring is able to provide it to its own JPA entity listener somehow.
I want to do the same, but with my own JPA entity listener and a Spring-managed bean.
I know that it is possible to store a reference to an ApplicationContext
in a static variable so I can use it to obtain the required Spring-managed bean:
@Component
public class SomeClass implements ApplicationContextAware {
public static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
SomeClass.applicationContext = applicationContext;
}
}
public class MyEntityListener {
@PrePersist
public void beforeCreate(Object entity) {
SomeClass.applicationContext.getBean(SomeSpringManagedBean.class)
.doSomething("Creating an entity: " + entity);
}
...
}
But this solution looks very ugly for me. I think there is a better solution for this.