Olá a todos.
Recentemente escolhi desenvolver uma aplicação Web com JPA/Hibernate, Spring e VRaptor. Estou estudando DDD, então pensei em utilizar o Spring pra injetar as implementações dos repositórios. Não criei uma camada de serviços (de “fachada”, não Domain Service) e meus Controllers (Components do VRaptor) acabam fazendo toda a orquestração, logo injeto as implementações neles com o plugin do Spring.
A hierarquia dos repositórios é a seguinte (usando a entidade User como exemplo):
pacote domain.repositories
IRepository (interface mais genérica) -> IUserRepository (interface que estende IRepository com métodos mais específicos)
pacote datamapper.dao
GenericDAOWithJPA (classe abstrata que implementa IRepositoy) -> UserDAOWithJPA (classe que estende GenericDAOWithJPA e implementa IUserRepository)
Isso tudo usa Generics pra trabalhar com todas as entidades sem duplicar código.
Exemplo simples:
Controller (usando um método bem simples, apenas de exemplo das anotações e do uso do repositório):
(...)
@Component("user")
public class UserController
private final IUserRepository userRepository;
public UsuarioController(IUserRepository userRepository){
this.userRepository = userRepository;
}
@Transaction(required=true)
public void home() {
this.usuarioRepository.refresh();
}
end
No applicationContext.xml:
<bean id="domain.repositories.IUserRepository" class=""datamapper.dao.UserDAOWithJPA"/>
A injeção nesse caso funciona muito bem.
O EntityManager está configurado no persistence.xml (a persistence unit tem o nome “default”, padrão do VRaptor) e é declarado no DAO genérico:
(...)
public abstract class GenericDAOWithJPA<T, ID extends Serializable> implements IRepository<T, ID> {
(...)
@PersistenceContext
protected EntityManager entityManager;
(...)
public void refresh(T entity) {
entityManager.refresh(entity);
}
}
O problema é que aí a injeção não funciona e o EntityManager fica sempre nulo. Acredito que isso ocorre porque o Controller é gerenciado pelo VRaptor, enquanto os DAOs são beans gerenciados pelo Spring, logo eles estão em contexto diferentes.
Pensei em configurar o EntityManagerFactory no Spring, deixar de usar o plugin JPA do VRaptor e passar a injetar essa factory no DAO genérico para instanciar o EntityManager, mas já tentei tanta coisa que nem sei se isso funcionaria.
Sugestões? 