Existe um truque sujo:
Crie uma classe assim:
public class RichDomainObjectFactory implements BeanFactoryAware {
private AutowireCapableBeanFactory factory = null;
private static RichDomainObjectFactory singleton = new RichDomainObjectFactory();
public static RichDomainObjectFactory autoWireFactory() {
return singleton;
}
public void autowire(Object instance) {
factory.autowireBeanProperties(instance)
}
public void setBeanFactory(BeanFactory factory) throws BeansException {
this.factory = (AutowireCapableBeanFactory) factory;
}
}
E declare um bean no Spring assim:
<bean class="my.package.RichDomainObjectFactory" factory-method="autoWireFactory"/>
O que acontece?
A primeira classe é um Singleton, que devolve uma factory. Existem dois métodos: o método setBeanFactory recebe um BeanFactory do Spring, e o método autowire realiza a injeção de qualquer objeto.
A anotação em XML garante a criação de um bean, mas note o pulo do gato, a propriedade “factory-method”, que garante que o Singleton retornado seja transformado em um bean do Spring, consequentemente tendo um BeanFactory injetado. Isso garante que você tenha acesso a um BeanFactory em qualquer lugar da sua aplicação.
Agora vem a parte 2. Crie um interceptor para o Hibernate (estendendo EmptyInterceptor), e sobrescreva o método onLoad(), que é chamado antes da inicialização de um entity do Hibernate.
public class DependencyInjector extends EmptyInterceptor {
public boolean onLoad(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
RichDomainObjectFactory.autoWireFactory().autowire(entity);
return false;
}
}
Declare o interceptor no seu PersistenceUnit
<property name="hibernate.ejb.interceptor" value="my.package.DependencyInjector" />
ou no seu hibernate.cfg.xml
<listener class="my.package.DependencyInjector" />
Agora, anote suas dependências do seu entity com @Autowired, carregue-as pelo Hibernate primeiro, e seu bean estará injetado.