I am trying to take benefit of this: https://github.com/spring-projects/spring-framework/issues/20852,
so I annotate my entity with @EntityListener(MyListener.class)
and then use the listener as:
public MyListener {
@Autowired
AnotherDependency anotherDependency;
@PostLoad
public void onRead(Entity entity) {
//
}
}
with that, it seems we finally can get rid of the nasty static hack and get the bean spring-processed.
But as fine as this works for listener own dependencies, it did not work for me for autowiring the listener itself.
Looks like EntityManagerFactory/Hibernate manages it as if it were a Spring bean, but it does not exposes it in the context for another bean to inject it.
I checked documentation and I saw someone claimed the listener had to be annotated with @Component
(although it worked in my case without it in regards to its internal autowires), and after I did this, the bean was managed by Spring and I could inject it, but then, I realized it was instantiated twice:
- LocalEntityManagerFactory reads the @EntityListener annotation and instantiates it and sets up dependencies (and this instance is the only one that handles the events)
- And then Spring seems to parse the @Component and do the operation again (and this instance is the only one that gets injected when you @Autowire the listener in some other bean)
Is this an expected behavior? Do I have a bug in my code? Is it an issue on Hibernate's side perhaps?
Comment From: quaff
I think it's expected behavior. hibernate get bean from SpringBeanContainer
with useJpaCompliantCreation=true
, It will create new bean instead of get existed bean.
https://github.com/hibernate/hibernate-orm/blob/e76241a3091078713dd4b57de085f5fadce5e0db/hibernate-core/src/main/java/org/hibernate/resource/beans/internal/ManagedBeanRegistryImpl.java#L43-L46
Comment From: nightswimmings
Hi @quaff ! Thanks for the point! Sadly, it seems it is a quite hardcoded setup, maybe prepared for future flexibility... or is there any creative solution for it? I cannot post-process it because the value is hardcoded and not settable
Comment From: snicoll
You need to separate the two concepts as @quaff mentioned. Or you can disable the integration between Hibernate and Spring if you don't need it (but it looks like you are).