Os primeiros parágrafos contém o "resumo da ópera". Em seguida, um pouco de código exemplificando as opções de integração.
DAOs que usam JPA necessitam de EntityManagerFactories (EMFs) e/ou EntityManagers (EMs) para realizar as operações num bancos de dados.
O Spring Framework gerencia objetos, podendo resolver dependências entre eles. Caso o Spring gerencie a(s) EMFs e os DAOs, ele pode injetar os EMFs nos DAOs, de forma transparente ao código. Então, a primeira coisa a se aprender é como fazer o Spring gerenciar a(s) EMF(s).
Uma vez configurados os beans necessários no Spring, pode-se partir para o código. É possível usar JPA com Spring de forma desacoplada, através de anotações JPA (desde que configure o Spring para reconhecer tais anotações); ou de forma acoplada, usando APIs especializadas do Spring.
DUMMY STEP) Para integrar JPA com Spring, logicamente é necessário um projeto JPA (grosso modo: entidades devidamente anotadas, e um arquivo META-INF/persistence.xml). Exemplo de projeto:
- src
- br.com.airframes
- Product.java
- META-INF
- persistence.xml
1) Configuração recomendada da EMF (LocalContainerEntityManagerFactoryBean)
Esta maneira é a mais flexível e poderosa. A linha "load-time-weaver" refere-se a questões de instrumentação de código requeridas por alguns provedores de persistência. Não será necessária quando o provedor é o Hibernate, por isso deixei comentada.
Note que está comentada a linha da propriedade dataSource. Por default, o Spring usa as configurações de acesso ao banco presentes em persistence.xml. Porém, vc pode deixar que o Spring também gerencie o seu datasource (ignorando persistence.xml), conforme item 6 deste tutorial.
2) Declarar um DAO como bean do Spring, no qual será injetada a EMF:
3) Integração de Baixo acoplamento usando anotações (Plain JPA)
3.1) Para o Spring reconhecer as anotações JPA, declarar:
ou
3.2) Codificação do Dao
Pronto! Esta é a maneira mais poderosa de integrar Spring e JPA, sem que haja qualquer dependência ao Spring explícita no código Java. A Spring Framework desempenha seu papel de forma transparente, injetando o EntityManagerFactory num mecanismo possível graças a anotações e ao PersistenceAnnotationBeanPostProcessor.
4) Outras maneiras de o Spring gerenciar o EMF.
Há duas maneiras alternativas àquelas apresentadas no passo 1 deste tutorial:
4.1) No caso da aplicação rodar em um App Server, é preferível deixar o Spring localizar o EMF na árvore JNDI:
É necessário também cuidado especial com a instrumentação de código, de modo que ela não entre em conflito com as bibliotecas do App Server. (consultar documentação do Spring).
4.2) LocalEntityManagerFactoryBean ao invés de LocalContainerEntityManagerFactoryBean
É a forma mais simples porém mais limitada de integrar JPA ao Hibernate. Ela não dá suporte, por exemplo, a transações globais. Seu uso é recomendado em aplicações simples que usam apenas JPA para acessar dados. Pode ser muito útil em aplicações standalone e ambientes de teste.
5) Integração Altamente Acoplada ao Spring
Neste caso, lida-se com JpaTemplates no lugar de EntityManagers, pois JPATemplate encapsula o EntityManager (JPATemplate gerencia internamente o EntityManager, não expondo-o ao programador).
Desta forma, como o código Java deixará de usar a API EntityManager, deve-se:
- Remover as declarações do item 3.1 deste tutorial (annotations post processors).
- Reescrever a configuração do DAO, possibilitando injeção do EMF via setter:
- Escrever método setter no DAO possibilitando o Spring injetar a dependência:
Dispostas as linhas gerais, seguem as opções para este tipo de integração:
5.1) Declarar JpaTemplate explicitamente em cada DAO da aplicação
5.2) Herdar JpaDaoSupport
JpaSupportDao já fornece o jpaTemplate, e setter para injeção do EntityManagerFactory, sem que necessidade de escrever código redundante nos DAOs
5.3) E quando precisar acessar a EntityManager API diretamente?
Escrever subclasses de JpaCallback e executá-los em JpaTemplates. Ao fornecer um JpaCallback, JpaTemplate executará o método doInJpa(EntityManager em) passando como parâmetro a sua referência interna da EntityManager.
Essa abordagem possibilita ao programador acesso indireto à EntityManager (através de um Callback). Para não inchar o sistema com estas subclasses, é possível usar herança implícita no código.
O código abaixo reescreve doSomething com Callbacks que permitem acessar o EntityManager.
6) Datasource gerenciado pelo Spring
6.1) Spring localiza datasource no JNDI
6.2) Spring lida diretamente com datasource
(Usa DBCP como Pool de Conexões - pode ser substituída por outra segundo preferência - por exemplo o C3P0).
Para configurar um datasource na JNDI, é necessário consultar a documentação do app server / container web.
Para o Tomcat: Tomcat-JNDI HowTo.
A biblioteca Simple-Jndi permite implementar uma árvore JNDI em aplicações stand-alone (pode ser útil em casos de testes).
Bibliografia http://static.springframework.org/spring/docs/2.5.x/reference/orm.html#orm-jpa http://static.springframework.org/spring/docs/2.5.x/reference/jdbc.html
Olá Fábio,
ResponderExcluirconfigurar o bean do DAO pode ser mais fácil. Ao invés de passar o EntityManager, podemos usar o Spring para se comportar como um container JPA e injetá-lo automaticamente.
Veja http://blog.springsource.com/2006/08/07/using-jpa-in-spring-without-referencing-spring/
Abraço,
..:: Thiago ::..