Enabling @Autowired in Hibernate entities.
Create an EventListener that kicks in after a Hibernate LOAD event. Using AutowireCapableBeanFactory to wire @Autowire’d dependencies.
package be.esus.core.infrastructure.hibernate; import be.core.architecture.common.locator.SpringLocator; import org.hibernate.event.spi.PostLoadEvent; import org.hibernate.event.spi.PostLoadEventListener; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; // https://jira.spring.io/browse/SPR-9187 public class MyPostLoadEventListener implements PostLoadEventListener { @Override public void onPostLoad(PostLoadEvent postLoadEvent) { Object entity = postLoadEvent.getEntity(); AutowireCapableBeanFactory spring = SpringLocator.getApplicationContext().getAutowireCapableBeanFactory(); spring.autowireBean(entity); } }
(SpringLocator is a simple custom class that is ApplicationContextAware in order to have static access to the ApplicationContext)
Register your new listener in Hibernate’s EventListenerRegistry.
package be.esus.core.infrastructure.hibernate; import org.hibernate.cfg.Configuration; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; import org.hibernate.integrator.spi.Integrator; import org.hibernate.metamodel.source.MetadataImplementor; import org.hibernate.service.spi.SessionFactoryServiceRegistry; import org.springframework.stereotype.Component; @Component public class MyEventListenerIntegrator implements Integrator { @Override public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class ); eventListenerRegistry.appendListeners(EventType.POST_LOAD, new MyPostLoadEventListener()); } @Override public void integrate(MetadataImplementor metadataImplementor, SessionFactoryImplementor sessionFactoryImplementor, SessionFactoryServiceRegistry sessionFactoryServiceRegistry) { } @Override public void disintegrate(SessionFactoryImplementor sessionFactoryImplementor, SessionFactoryServiceRegistry sessionFactoryServiceRegistry) { } }
To register your SPI (see service loader), create
a (text) file called org.hibernate.integrator.spi.Integrator in META-INF/services/ and put the FQCN of your integrator in it:
be.esus.core.infrastructure.hibernate.MyEventListenerIntegrator