ustify>
Clique aqui para ler todos os artigos desta edição
Persistência com EJB 3.0
A API de Persistência Java (JPA)
Enterprise Java Beans foram por muito tempo o patinho feio da especificação JEE. Muitos desenvolvedores já descobriram funcionalidades poderosas como Session Beans, Message Driven Beans e TimeServices, entretanto a complexidade de uso de tais recursos aliado à deficiência dos serviços de persistência dificultaram a adoção da tecnologia e impulsionaram o uso de soluções alternativas como o Hibernate e o Oracle TopLink. A boa notícia é que a especificação EJB 3.0, mais simples e turbinada, pretende colocar os polêmicos Enterprise Java Beans novamente em foco, mas desta vez, como atores principais e não meros coadjuvantes.
A finalidade do EJB 3.0 é melhorar a arquitetura EJB reduzindo a sua complexidade do ponto de vista dos desenvolvedores. A especificação EJB 3.0 foi definida pela JSR-220 (Enterprise JavaBeans, Version 3.0), finalizada em 11 de maio de 2006. Parte dessa especificação é a nova API de persistência Java (JPA). Esta API de persistência é o novo padrão para soluções de mapeamento objeto-relacional em Java. Este artigo vai explorar os fundamentos desta nova API e fornecerá exemplos práticos de códigos que servirão como ferramentas para ajudar os desenvolvedores a começarem rapidamente a utilizar esta API.
O que é a persistência em EJB 3.0
A persistência EJB 3.0 utiliza o mapeamento objeto-relacional para minimizar o “gap” existente entre o nosso modelo orientado a objetos e o banco de dados relacional. As aplicações escritas usando a API de persistência Java devem ser portáveis para muitas bases de dados relacionais.
A implementação da JPA é feita por um “provider” de persistência. Esse “provider” define como as coisas funcionam através da implementação de todas as interfaces definidas pela especificação da JPA. Com isso, podem existir várias implementações da JPA. Além de ser portável entre bases de dados relacionais, uma aplicação bem projetada em EJB 3.0 deve ser portável também em termos do “provider” de persistência. Essa portabilidade significa que a aplicação deverá funcionar com implementações de “providers” de fabricantes distintos, que estejam em conformidade com a JSR-220, sem nenhum esforço adicional.
Enterprise Java Beans foram tradicionalmente associados com containers pesados como JBoss, Websphere, WebLogic e outros. Estes containers fornecem muitos serviços para as aplicações distribuídas, porém eles não são necessariamente parte de uma aplicação EJB 3.0. Para muitas aplicações, este cenário de distribuição pode ainda fazer sentido, entretanto, a API de Persistência Java é especificamente projetada para ser usada com ou sem um container. Em particular, o “provider” de persistência é necessário pela especificação para trabalhar fora do “container”.
Os requisitos
Para começar a trabalhar com a persistência em EJB 3.0 precisamos de alguns itens instalados:
· Provider de persistência EJB 3.0;
· Banco de dados relacional;
· Driver JDBC.
Os exemplos apresentados nesse artigo devem trabalhar com muitas combinações das ferramentas apresentadas na lista anterior. Recordando que um dos grandes benefícios de utilizarmos os padrões especificados é que você não está amarrado a um fornecedor.
O Hibernate é o framework livre e de código aberto mais popular que implementa a JPA. Os exemplos apresentados aqui foram desenvolvidos usando o Hibernate 3.2.0 em conjunto com o Hibernate Entity Manager 3.2.0. Todos os códigos apresentados neste artigo devem funcionar com essas versões de Hibernate ou qualquer outra implementação, de outro fabricante, que esteja em conformidade com a JSR-220. Lembre-se de que a JSR-220 é apenas uma especificação e podem existir várias implementações desta especificação.
O EntityManager
O EntityManager no EJB 3.0 é responsável por consultar e gerenciar as entidades persistentes conhecidas como Entidades. O EntityManager é o início da maioria das operações de persistência. A técnica para recuperar um EntityManager em um ambiente Java EE é ligeiramente diferente da técnica para recuperar um EntityManager em um ambiente Java SE. Por simplicidade, os exemplos aqui apresentados estão focados no ambiente Java SE, assim, nenhum container precisa ser configurado. Na Listagem 1 temos o trecho de código referente à criação do EntityManager a partir de uma EntityManager Factory em um ambiente Java SE.
Listagem 1. Criação do EntityManager.
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
...
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("mycontext");
EntityManager em = emf.createEntityManager();
Para que uma entidade se torne persistente é necessário associá-la a um contexto de persistência, que fornece a conexão entre as instâncias e o banco de dados. A manipulação destas instâncias é feita, a partir desse contexto, por meio do gerenciador de entidades (EntityManager). O gerenciador de entidades na JPA é uma instância da interface javax.persistence.EntityManager.
O primeiro parâmetro do método createEntityManagerFactory é o nome do contexto persistente. Este contexto de persistência precisa ser configurado no arquivo persistence.xml. Este arquivo de configuração precisa estar localizado no diretório /META-INF ou em algum arquivo “.jar” que esteja no seu CLASSPATH. Se o arquivo de configuração não estiver em um arquivo “.jar”, tenha cuidado como o CLASSPATH é configurado. O arquivo de configuração precisa ser carregado como um recurso chamado META-INF/persistence.xml, então se o arquivo está em /local/dev/stuff/META-INF/persistence.xml precisamos ter o caminho /local/dev/stuff/ no CLASSPATH, e não /local/dev/stuff/META-INF/. Na Listagem 2 é apresentado o exemplo de um descritor de contexto de persistência.
Listagem 2. Descritor do contexto de persistência.
Na Listagem 2, o nome da unidade de persistência (
O elemento
O arquivo descritor contém ainda o elemento
Como pode ser visto na Listagem 2, dentro do elemento
O arquivo descritor é o único lugar onde veremos detalhes sobre qualquer implementação particular da JPA. Todo o código da aplicação mostrado a seguir é independente de fornecedor, e por isso um padrão. Nós usaremos Hibernate e MySQL.
Entidades
Como se sabe, existem quatro tipos de EJBs (ler Nota 1): Stateless Session Beans, Stateful Session Beans, Entity Beans e Message-driven Beans; e a especificação EJB 3.0 trouxe algumas mudanças para cada tipo de EJB. Estamos interessados aqui apenas nos EJBs do tipo Entity Beans.
Entidades são instâncias que podem ser armazenadas e recuperadas usando a API JPA. Uma entidade é quase um Plain Old Java Object (POJO) (ler Nota 2). Os requisitos para ser considerado uma Entidade (Entity Bean) são:
· Precisa possuir um construtor sem argumentos;
· Não possuir nenhum método final;
· A classe não pode ser final;
· Precisa ser marcada com @Entity (ou ter um descritor XML apropriado).
Nota 1. Tipos EJB
Cada um dos outros tipos de EJBs possuem características específicas que não entraremos em detalhe nesse artigo, mas como exemplo: Stateless Session Beans precisam ter a anotação (ler Nota 3) @Stateless, já os do tipo Stateful Session Beans precisam da anotação @Stateful e os do tipo Message-driven Beans precisam da anotação @MessageDriven.
Nota 2. POJO
POJO, um acrônimo para Plain Old Java Objects, define um objeto que não possui nenhuma característica especial. Um POJO é um objeto Java normal que não implementa nenhuma interface nem estende nenhuma classe específica de um framework.
POJO
Na Listagem 3 é apresentado um POJO simples que poderemos armazenar utilizando o padrão de persistência EJB 3.
Listagem 3. Nosso primeiro exemplo de um POJO.
package com.persistencedemo;
public class Pessoa {
private String nome;
private String sobrenome;
public Pessoa() {
}
public Pessoa(String nome, String sobrenome) {
this.nome = nome;
this.sobrenome = sobrenome;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getSobrenome() {
return sobrenome;
}