Whats new? | Login | Parceiros
Cadastre-se | Atendimento | RSS
+ Java:
artigos   |   vídeos   |    cursos   |    mais

Spring 2, JPA e Hibernate – Parte III

Após esse overview de JPA, iremos aprender a como configurar uma EntityManager com Spring 2, configurando o Hibernate como provider, em uma aplicação WEB.

GABRIEL NASCIMENTO
Gabriel Nascimento (gamnascimento@yahoo.com.br), é arquiteto de soluções corporativas. Trabalha com Java a 5 anos. Atualmente, é responsável pela área de sistemas de alta disponibilidade J2EE para canais lotéricos da Caixa Econômica Federal.


Ver space do autor


Estatísticas:
Visualizações:
28385
Favoritado:
 11 vez(es)
Conteúdo:
Didática:
Utilidade:
8 4
votos: 13

Serviços:



Spring 2, JPA e Hibernate – Parte III

 

Spring + JPA

Após esse overview de JPA, iremos aprender a como configurar uma EntityManager com Spring 2, configurando o Hibernate como provider, em uma aplicação WEB.

 

Nesse exemplo, iremos utilizar a factory org.springframework.orm.jpa.LocalEntityManagerFactoryBean. Essa classe é responsável por criar um EntityManager para ser executado em ambientes Java SE. Porém, caso queira executar em ambientes J2EE utilize a factory org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.

 

Agora precisamos mapear as classes que contém referência ao EntityManager para realizar as operações de persistência: persist, merge, remove, find, etc. Geralmente, essas classes de acesso aos dados são os DAOs (Data Access Object).

 

Porém, para que não tenhamos que fazer injeção de dependência do EntityManager em todos os nossos DAOs, utilizaremos a “milagrosa” classe org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor. Ela procura todas as classes que contém a annotation @PersistenceContext ou @PersistenceUnit e faz a injeção de dependência “automagicamente” para você!! Portanto basta que nossos DAOs contenham a seguinte declaração:

 

public class EntityDAO{

...
  @PersistenceContext
  private EntityManager entityManager
;
...

}

Dessa forma não é necessário que seus DAOs não tenham que estender a classe org.springframework.orm.jpa.support .JpaDaoSupport para ter acesso as operações da EntityManager por meio do org.springframework.orm.jpa. JpaTemplate (método getJpaTemplate da classe JpaDaoSupport).

 

No seu application-context.xml, os seguintes beans, abaixo, devem ser declarados. Veja que o bean entityDAO não contém referência ao bean entityManagerFactory.

 

<bean id="entityManagerFactory"

        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">

        <property name="persistenceUnitName"

               value="persistenceUnit" />

</bean>

 

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPost

Processor" />

 

<bean id="entityDAO"

               class="example.dao.EntityDAO" />

 

Agora vamos criar nosso arquivo de configuração do JPA, o persistence.xml, para um banco de dados PostGreSQL e provider Hibernate. Lembrando que esse arquivo deve estar localizado no diretório META-INF do seu jar.

<persistence>

        <persistence-unit name="persistenceUnit"

               transaction-type="RESOURCE_LOCAL">

               <provider>org.hibernate.ejb.HibernatePersistence</provider>

               <non-jta-data-source>java:/example-ds</non-jta-data-source>

               <class>example.pojo.Entity1</class>

<class>example.pojo.Entity2</class>

               <properties>

                       <property name="hibernate.dialect"

                               value="org.hibernate.dialect.PostgreSQLDialect" />

                       <property name="transaction.factory_class"

                               value="

                               org.hibernate.transaction.JDBCTransactionFactory" />

               </properties>

        </persistence-unit>

</persistence>

 

Observe que para configurarmos o Hibernate como provider, basta mapear a classe org.hibernate.ejb.HibernatePersistence na tag provider, e definir as properties específicas do Hibernate na tag properties, como por exemplo, hibernate.dialect para o PostGreSQL.

Agora queremos delegar o controle de transações da JPA para o Spring. Considero a maneira mais fácil de fazer isso por meio da utilização de aspectos (AOP) do Spring.

Novamente no seu application-context.xml adicione a configuração do bean abaixo:

 

<bean id="transactionManager"

        class="org.springframework.orm.jpa.JpaTransactionManager">

        <property name="entityManagerFactory"

               ref="entityManagerFactory" />

</bean>

 

O JpaTransactionManager é recomendado para aplicações que utilizam apenas uma EntityManager. Dessa forma, não é necessário utilizar JTA, pois não estaremos acessando diversos recursos transacionais dentro de uma mesma transação.

 

Configuremos, agora, as classes que realizarão o acesso aos DAOs e, portanto é aonde devemos demarcar as transações. O atributo propagation configurado como REQUIRED, significa que se já não existir uma transação quando o método mapeado for invocado, o Spring inicia uma nova. Caso já exista o método é inserido no contexto da transação.

 

<aop:config>

        <aop:pointcut id="entityTransaction"

               expression="execution(* example.EntityControl.*(..))" />

        <aop:advisor advice-ref="entityTransactionAdvice"

               pointcut-ref="entityTransaction" />

</aop:config>

 

<tx:advice id="entityTransactionAdvice"

        transaction-manager="transactionManager">

        <tx:attributes>

               <tx:method name="persistEntity" propagation="REQUIRED" />

               <tx:method name="removeEntity" propagation="REQUIRED" />

               <tx:method name="mergeEntity" propagation="REQUIRED" />

               <tx:method name="findEntity" propagation="REQUIRED" />

        </tx:attributes>

</tx:advice>

 

Poderíamos ter configurado as transações para que o JpaTransactionManager fosse injetado no código do EntityControl, automaticamente, por meio da utilização da annotation @Transactional, nos métodos declarados acima.

 

<tx:annotation-driven transaction-manager="jpaTransactionManager" proxy-target-class="false"/>

Porém, isso não seria considerado uma boa prática, pois essa annotation faz parte da API do Spring 2 (org.springframework.transaction.annotation.Transactional ), e dessa forma seu código estaria dependente do framework Spring.

 

Hibernate Open Session In View

O Spring fornece suporte ao famoso pattern Open Session in View, para permitir que sejam carregados relacionamentos do tipo LAZY, mesmo após a transação ter finalizado.

 

O problema é quando as Entities carregadas do banco de dados são passadas para a camada de apresentação em seu estado detached os atributos anotados com fetch=LAZY podem estar indisponíveis. O filter serve justamente para que não tenha que ser criada uma nova Hibernate Session para carregar esses dados.

 

Isso é feito através do filter org.springframework.orm.hibernate.support .OpenSessionInViewFilter. Ele faz com que existe apenas uma Hibernate Session para cada thread (no caso das aplicações WEB, um Hibernate Session para cada request).

 

Para habilitar o filter, basta configurá-lo no seu arquivo web.xml, conforme abaixo. A tag url-pattern deve conter o padrão de endereços da sua aplicação. Neste exemplo, as URLs que terminam com .do, por exemplo, http://localhost:8080/testeEntity.do.

 

<filter>

        <filter-name>openEntityManager</filter-name>

        <filter-class>

               org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter

        </filter-class>

</filter>

<filter-mapping>

        <filter-name>openEntityManager</filter-name>

        <url-pattern>*.do</url-pattern>
</
filter-mapping>

 

Conclusão

Vimos nesse artigo os principais aspectos da nova API de persistência da especificação EJB 3, a JPA.

 

Foram discutidas, também, boas práticas de implementação dessa nova API, e como integrá-la com Spring 2, utilizando o Hibernate como provider, por meio apenas da configuração do persistence.xml, possibilitando a utilização de qualquer meio de persistência, por meio de uma implementação padrão.





Participe! Inclua um comentário
[Fechar]

Este post é fechado - você precisa ter acesso ao post para incluir um comentário.


Zeovaldo
21/9/2007 19:06
Exemplo Parabéns pelos Artigos.. Gostei das boas Práticas.. Espero que tenha a Parte IV com exemplos(De preferencia Aplicacao Web).. Incluindo as Boas Práticas :)

[responder]

 
Gabriel Nascimento
25/9/2007 21:11
RE:   Obrigado! Vou postar a Parte IV com um exemplo e o codigo-fonte em anexo!

[responder]
 
Mauricio Nunes
5/5/2008 12:49
faltaou um exemplo Bacana esse Post, só faltou criar uma pequena aplicação utilizando o exemplo de forma prática. Abraços

[responder]

 
Wellington Moscon
16/6/2008 20:39
E o exemplo? Muito bom o post, só deixou a desejar por não ter o exemplo disponível depois de tanto tempo.

[responder]

 



 


[Fechar]
Este post está disponível para assinantes da Java Magazine, WebMobile ou para quem possui Créditos DevMedia.

  Conheça os planos de créditos DevMedia e visualize esse post agora mesmo!

Plano conveniência – Neste plano este post custa R$ 0,00 (Compre agora)
Esse plano permite que você compre somente um post, pagando por ele seu preço sem desconto.

Plano ocasional: Aqui este post custa: R$ -1,00 (assinante) ou R$ -1,00 (não-assinante)
Este plano é ideal para quem tem interesse em mais de um post. Você compra um mínimo de R$ 50,00 em créditos e ganha, em média, 50% de desconto no preço do post. Compre Créditos agora!

Assinatura de Créditos (Plano econômico) – Aqui este post custa R$ -1,00
Este plano é ideal para quem tem interesse em muitos posts. Com esse plano você compra R$ 180,00 em créditos e ganha, em média, 80% de desconto no preço do post. Assine este plano agora!

> Saiba mais sobre o Sistema de Créditos DevMedia
DevMedia Group   www.devmedia.com.br   |   www.javafree.org   |   www.mrbool.com
2010 - Todos os Direitos Reservados a DevMedia Group - (21) 3382-5038