As especificações EJB 3.0 fornecem algumas revisões importantes (alguns dizem necessárias) do modelo de programação EJB. Com ênfase no uso de POJOs (plain old Java objects) anotados, todo o modelo de programação EJB é radicalmente diferente das especificações EJB passadas. Um aspecto desse novo modelo de programação que está recebendo muita atenção é a arquitetura de persistência. Este artigo apresenta essa nova Java Persistence API com um exemplo completo de como aproveitar alguns desses recursos agora usando o WebSphere Application Server V6.1.
Este artigo coloca ênfase no uso de OpenJPA em WebSphere Application Server V6.1 sem o EJB 3.0 Feature Pack. O EJB 3.0 Feature Pack não foi atualizado para dar suporte à especificação JPA 2.0, mas se você considerar as limitações de integração de JPA descritas neste artigo aceitáveis, é possível usar OpenJPA 2.x com o WebSphere Application Server V6.1.
Este artigo foi atualizado com base nestes níveis de software:
- WebSphere Application Server V6.1.0.35
- Application Server Toolkit V6.1.1.9
- Apache OpenJPA V2.0.1
A Java Persistence API 1.0 (JPA) foi um membro da família Java EE 5 EJB 3.0 (EJB 3) de especificações. O grupo especialista em EJB 3 produziu três especificações:
- JB Core Contracts and Requirements
- API simplificada EJB 3.0
- Java Persistence API 1.0.
Em julho de 2007, o JPA 2.0 foi proposto como sua própria especificação, JSR-317. Ele permanece um membro da família de especificações Java EE 6, mas não está mais vinculado à especificação EJB.
A especificação JPA define o gerenciamento de mapeamento de objeto/relacional e persistência com ambientes Java EE e Java SE.
Em resumo, a especificação JPA cobre as seguintes áreas principais:
Um novo modelo de programação com base em POJO é apresentado, que se aplica igualmente bem a ambientes Java EE e Java SE. As anotações agora podem ser usadas para definir metadados diretamente no código do aplicativo, além de ter um mecanismo com base em XML. Ainda, os POJOs da entidade não é mais necessária para implementar qualquer interface com base em estrutura EJB.
- O modelo de programação também define um modelo de desconexão para objetos POJO (Entidade). Isso deve ser um benefício para o cliente/servidor e ambientes de aplicativo da web.
- Além de aprimorar a EJB Query Language (também conhecida como JPQL), o modelo de programação também permite o uso de consultas SQL nativas.
A especificação JPA também define explicitamente o mapeamento de objeto/relacional (O/R), em vez de contar com mapeamento O/R específico do fornecedor de liberações anteriores. Isso deve ajudar na migração de aplicativo e na capacidade de conexão do fornecedor.
Alguns outros itens relacionados à persistência também foram padronizados:
- Controle de versão de objeto para controle de simultaneidade otimista
- Geração de chave de banco de dados
- Carregamento lento vs. rápido de campos
- Herança.
O JPA 2.0 apresentou:
- Aprimoramentos adicionais de Mapeamento de O/R para uma solução mais completa.
- Um gerenciador de bloqueio pessimista padronizado.
- Acesso a um cache L2 do provedor da JPA, se disponível.
- Uma interface de programação para recursos de consulta usando as APIs de Metamodelo e Critérios.
- Integração com Validação de Bean (JSR 303).
Toda essa simplificação vem com um pequeno custo. Devido à grande mudança no modelo de programação, aplicativos EJB 2.x existentes precisarão ser reescritos para aproveitar os novos recursos da JPA. Ainda, a nova especificação da JPA não inclui manutenção automática de container-managed relationship (CMR). A manutenção de relacionamento agora é gerenciada por aplicativo.
Detalhes adicionais sobre a Java Persistence API podem ser encontradas no website de Java Community Process, bem como em diversos whitepapers, artigos, apresentações e livros (consulte Recursos).
O projeto Apache OpenJPA é uma implementação de software livre licenciada por Apache da Java Persistence API. A OpenJPA é focada no desenvolvimento de uma implementação robusta, de alto desempenho e escalável da especificação JPA.
Em função do interesse do segmento de mercado nesse projeto de OpenJPA, este artigo ajudará a explicar como aproveitar imediatamente essa implementação nos seus ambientes do WebSphere Application Server.
Este artigo aplica-se igualmente bem aos padrões JPA 1.0 e JPA 2.0. Os conceitos, amostras, explicações e capturas de tela aplicam-se independentemente do release específico da OpenJPA usada.
Uma visão do aplicativo de amostra
Para o nosso exemplo, estamos usando um Customer Order System, em que um cliente cria um pedido, adiciona itens de linha e então envia o pedido. A Figura 1 ilustra os casos de uso no nosso sistema de amostra.
Figura 1. Casos de uso do aplicativo de amostra
O diagrama de atividade na Figura 2 ilustra a sequência em que os casos de uso são executados.
Figura 2. Sequência de caso de uso do aplicativo de amostra
Neste exemplo, estamos enfatizando apenas a camada de Persistência, uma vez que a meta é mostrar como é possível usar OpenJPA como sua camada de persistência no WebSphere Application Server V6.1.
Figura 3. Modelo de dados do banco de dados
No nosso banco de dados de amostra, há quatro tabelas:
- CUSTOMER:
- ORDER:
- LINEITEM:
- PRODUCT:
No aplicativo de amostra, temos quatro entidades JPA correspondentes, como mostrado no diagrama de classe na Figura 4.
Figura 4. Diagrama de classe
Alguns pontos interessantes a observar sobre mapeamento:
A Customer Entity tem um relacionamento unidirecional de um para um com CustomerOrder, enquanto Order tem um relacionamento unidirecional de muitos para um de volta com o Customer. O motivo pelo qual esse não é um relacionamento bidirecional é que o Customer mantém apenas uma instância do pedido aberto atual. A Order Table, porém, tem todos os pedidos para o cliente, não importa qual é o estado do pedido. Porque temos apenas relacionamentos unidirecionais, isso afeta a maneira como os relacionamentos são configurados, já que cada lado precisa ser definido.
CustomerOrder e Line Item têm um relacionamento bidirecional e, portanto, gerenciado.
Usamos uma camada de fachada de sessão do EJB para representar os casos de uso. Porque o WebSphere Application Server V6.1 tem suporte para EJB 2.1, usamos os beans de sessão do EJB 2.1. Contudo, percebendo o suporte a ser lançado em breve para EJB 3, passamos toda a lógica de fachada para um POJO. Assim, quando você passa para os beans de sessão do EJB 3, tudo o que precisa fazer é remover a camada de bean de sessão do EJB 2.1 e anotar o POJO. A Figura 5 é o diagrama de classe para o bean de sessão e o POJO correspondente.
Figura 5. Diagrama de classe para bean de sessão e POJO
Para ilustrar o fluxo, o diagrama de sequência mostra a implementação do caso de uso de Find Customer. Toda a lógica de fachada é feita no POJO OrderProcessor. O Order Processor interage com o gerenciador de entidade do JPA e os POJOs do JPA para conseguir seu código de persistência. O bean de sessão do EJB 2.1 delega para o POJO. É possível examinar o código mais tarde.
Figura 6. Diagrama de sequência
De maneira similar, a implementação de Open Order é mostrada na Figura 7. Todos os casos de uso seguem esse fluxo básico de bean de sessão do EJB 2.1, chamando um POJO de fachada, que, por sua vez, interage com o gerenciador de entidade da JPA.
Figura 7. Implementação de Open Order
Configurando o ambiente de desenvolvimento da JPA com o Application Server Toolkit
Para executar esse exemplo, será preciso efetuar o download dos materiais que acompanham este artigo.
Acessar o desenvolvimento da OpenJPA
Uma vez que o uso da OpenJPA neste artigo é para um ambiente de persistência gerenciado por aplicativo, é possível usar qualquer uma destas liberações da OpenJPA:
- OpenJPA v1.0.4 (release mais recente que corresponde ao Feature Pack do WebSphere Application Server V6.1 para EJB 3.0)
- OpenJPA v1.2.2 (release mais recente que corresponde ao WebSphere Application Server V7.0)
- OpenJPA v2.0.1 (release mais recente que corresponde ao Feature Pack do WebSphere Application Server V7.0 para OSGi Applications e JPA 2.0)
É possível acessar o desenvolvimento da OpenJPA 2.0.1 efetuando o download do arquivo openjpa-0.9.6-incubating.zip. Para mais detalhes sobre outras maneiras de efetuar o download da OpenJPA, consulte Recursos.
É possível descompactar o arquivo obtido por download em qualquer lugar. A raiz do arquivo ZIP contém o arquivo JAR da implementação da OpenJPA, como mostrado na Figura 8.
Figura 8. Arquivo JAR de implementação da OpenJPA
(As liberações de OpenJPA 2.x apresentaram um arquivo "todo" JAR (p. ex., openjpa-all-2.0.1.jar) que contém todas as dependências necessárias em um arquivo JAR fácil de usar. Entretanto, para permitir que este artigo seja usado com qualquer release de OpenJPA, as dependências serão manipuladas separadamente.
Sob o diretório lib, você encontrará as dependências necessárias.
Figura 9. Dependências de JAR
Mais tarde mostraremos como empacotar esses arquivos JAR no EAR.
Configurar o espaço de trabalho
O WebSphere Application Server V6.1 é enviado com o Application Server Toolkit (AST) V6.1. O AST é um superconjunto do projeto Eclipse Web Tools, que adiciona funcionalidade específica do WebSphere Application Server, como um servidor de teste do WebSphere Application Server. Nesta seção, você verá como configurar seu AST para desenvolvimento de OpenJPA sem interrupção.
Inicie o Application Server Toolkit:
Abra um espaço de trabalho vazio.
Figura 10. Abrir o espaço de trabalho
Feche a tela Welcome.
Figura 11. Tela Welcome do AST
Troque para a perspectiva de J2EE.
Figura 12. Selecione a perspectiva J2EE
A primeira coisa que se precisa fazer é configurar o WebSphere Application Server V6.1 como um ambiente de teste de unidade. Estamos presumindo que você possui uma instalação do WebSphere Application Server V6.1 de servidor único local já estabelecida. Também presumimos que você criou um perfil. (Consulte Recursos para mais informações sobre instalação e perfis.)
Acesse a visualização de Servers e clique com o botão direito do mouse dentro da visualização.
Selecione New => Server (Figura 13).
Figura 13. Criar um novo servidor
Selecione BM=>WebSphere v6.1 Server e Create New runtime, depois pressione Next (Figura 14).
Figura 14. Create new runtime
Mantenha o valor padrão para Name, e aponte para o diretório de instalação do WebSphere Application Server V6.1. Pressione Next.
Figura 15. Definir um novo tempo de execução
Selecione um perfil de servidor de aplicativo com os números de porta SOAP adequados. No nosso exemplo, usamos um perfil não seguro. Pressione Finish.
Figura 16. Definir um novo servidor
Seu AST pode ser configurado para usar um JRE e JDK Java 1.4 por padrão. É preciso atualizar as preferências para que você possa compilar o código Java 5, uma vez que JPA conta com anotações e recursos Java 5.
Selecione Window no menu principal e depois Preferences.
Figura 17. Alterar as preferências
Expanda a seção Java e selecione Compiler.
Troque o nível de conformidade de Compiler para 5.0 e depois Apply .
Figura 18. Alterar o nível de conformidade do compilador
Alterne para Installed JREs e selecione WebSphere Application Server v6.1 JRE.
Figura 19. Alternar para JRE
Pressione OK para salvar as alterações e então Yes para realizar um desenvolvimento.
Figura 20. Alterar as configurações e o desenvolvimento do compilador
Nesta seção, apresentaremos a criação de diversos projetos Java EE e configuraremos o arquivo EAR para conter JPA.
Para criar um Enterprise Application Project e seus subprojetos correspondentes (um projeto EJB e um projeto da web), clique com o botão direito em Enterprise Applicationsno Project Explorer e selecione New => Enterprise Application Project.
Figura 21. Criar um Enterprise Application Project
Para o Nome do Projeto, insira
OpenJPATestEAR, e para Target runtime, selecione WebSphere Application Server v6.1 (Figura 22). Tenha cuidado para não selecionar por engano WebSphere Application Server v6.1 stub. Deixe as configurações como<custom>. Pressione Next.
Figura 22. Definir o Enterprise Application Project
Aceite os padrões na página Select Project Facets e pressione Next (Figura 23).
Figura 23. Selecionar facetas do projeto
No painel J2EE Modules to Add to EAR, certifique-se de que o Content Directory esteja definido para EarContent. Pressione New Module... para iniciar o assistente New J2EE Module (Figura 24).
Figura 24. Iniciar o assistente New J2EE Module
Crie um projeto EJB e um projeto da web com estes nomes (Figura 25):
- EJB module:
OpenJPATest - Web module:
OpenJPATestWeb
Pressione Finish.
Figura 25. Criar módulos J2EE padrão
- EJB module:
Os módulos recém-criados serão listados na janela do projeto. Pressione Finish para concluir a criação do projeto EAR (Figura 26).
Figura 26. Criação do projeto EAR concluída
Esteja ciente de que terá alguns erros de compilação até que todos os artefatos necessários sejam criados e as dependências necessárias sejam importadas.
Configurar o banco de dados DB2 e a configuração do banco de dados do WebSphere Application Server
Para executar o aplicativo, é preciso configurar o banco de dados. No nosso exemplo, usamos DB2® Versão 9, e fornecemos uma tabela de dados de teste e de script DDL. Dependendo do banco de dados usado, é preciso modificar o esquema. (Como alternativa, é possível usar a documentação OpenJPA para gerar um DDL para seu banco de dados. Consulte Recursos para obter mais informações.)
Localize os scripts de que precisará na pasta OrderEntryDB do arquivo de download fornecido.
Use uma janela de comando DB2 para executar esses scripts. Para acessar uma janela de comando do DB2, navegue para IBM DB2 => Command Line Tools => Command Window.
Crie um banco de dados DB2 inserindo um comando do DB2 como este:
db2 create db JPATESTQuando o banco de dados tiver sido criado, conecte-se ao banco de dados a partir da mesma janela de comando com um comando como este:
db2 connect to JPATEST user db2admin using db2adminExecute o script DDL incluído no arquivo de download emitindo este comando:
db2 –tvf C:\<directory>\createTables.DDLÉ possível executar os scripts de criação de dados de maneira similar:
db2 –tvf C:\<directory>\createData.sql
Para simplificar esse exemplo, usamos um recurso no WebSphere Application Server chamado enhanced EAR. Esse recurso permite armazenar a configuração do banco de dados no aplicativo. À instalação do aplicativo, o WebSphere Application Server usará essas informações para criar a configuração adequada. Isso economizará tempo ao configurar o driver do JDBC e a DataSource necessário pelo servidor de aplicativos.
(Tenha em mente que o recurso EAR aprimorado é usado para prototipagem rápida, mas é boa prática configurar os recursos exigidos no servidor usando os scripts wsadmin (ou o console administrativo) de modo que os aplicativos possam ser administrados adequadamente em vários ambientes de teste e produção.)
Para adicionar a configuração do banco de dados ao aplicativo, abra o arquivo application.xml no projeto EAR. É possível fazer isso clicando duas vezes no ícone do descritor de implementação OpenJPATestEAR, mostrado na Figura 27.
Figura 27. Abrir o projeto EAR
Selecione a guia Deployment . A Figura 28 destaca os itens de configuração de interesse.
Figura 28. Configuração do descritor de implementação
Como você pode ver, há várias seções dentro do painel de configuração. Para inserir valores, pressione Add para iniciar um assistente para um item de configuração específico. Abaixo está um resumo dos valores que serão inseridos ou selecionados para cada seção. Quando concluir esse painel de configuração, lembre-se de salvar o descritor Application Deployment.
Driver JDBC usado:
- Tela 1:
- Tipo de banco de dados: IBM DB2
- Tipo de provedor JDBC: DB2 Universal JDBC Provider (XA)
(Certifique-se de usar o Universal Driver tipo 4, que usa as APIs do JDBC 3.0 necessárias).
- Tela 2:
- Nome:
DB2XA - Nome da classe de implementação:
com.ibm.db2.jcc.DB2XADataSource - Aceite o caminho de classe e o caminho nativo padrão
- Nome:
DataSource usado:
- Tela 1:
- Tipo de provedor: DB2 Universal JDBC Driver Provider (XA)
- Origem de dados Versão 5.0
- Tela 2:
- Nome:
OrderDS - Nome JNDI:
jdbc/orderds - Alias de autenticação gerenciado por contêiner:
DBUser
- Nome:
- Tela 3:
- Nome do banco de dados:
JPATEST - Nome do servidor:
localhost
- Nome do banco de dados:
Alias de autenticação:
- Alias:
DBUser - ID do usuário:
<<database id>> - Senha:
<<password>>
Variáveis de substituição:
- DB2UNIVERSAL_JDBC_DRIVER_PATH:
<<DB2 Root>>/java - Exemplo:
C:\Progra~1\IBM\SQLLIB\java
- Tela 1:
Adicionar arquivos JAR da JPA ao seu aplicativo corporativo
É preciso adicionar o JAR da OpenJPA e dependências ao arquivo EAR importando-os para o arquivo EarContent do Enterprise Application Project:
Primeiro, adicione o arquivos JAR dependentes:
Clique com o botão direito do mouse na pasta EarContent sob o projeto OpenJPATestEAR e selecione Import... , conforme mostra abaixo.
Figura 29. Importar arquivos JAR
Selecione File system e depois Next (Figura 30).
Figura 30. Selecionar o sistema de arquivos
A partir do campo Directory, navegue para o diretório para o qual a JPA foi transferida por download, e então para o diretório lib dentro dele. Selecione os seguintes arquivos JAR (Figura 31):
- common-collections-3.2.1.jar
- common-lang-2.1.jar
- commons-pool-1.5.3.jar
- geronimo-jpa_2.0_spec-1.1.jar
- serp-1.13.1.jar
(Arquivos JAR similares com nomes de release ligeiramente diferentes precisam ser selecionados se você estiver usando uma liberação alternativa da OpenJPA. Os outros arquivos JAR de dependência não são necessários porque o WebSphere Application Server fornece os JARs de J2EE necessários, bem como registro comum. Ainda, uma vez que este exemplo está usando DB2, o JAR de tempo de execução Derby não é necessário também.)
Pressione Finish.
Figura 31. Selecionar arquivos JAR para importar
A seguir, precisamos importar o arquivo JAR de implementação JPA. Clique com o botão direito do mouse na pasta EarContent sob o projeto OpenJPATestEAR e selecione Import.... Como antes, aponte para a raiz do diretório de instalação da JPA e selecione o seguinte jar para importar: openjpa-2.0.1.jar e depois Finish.
Figura 32. Importar um arquivo JAr de implementação da JPA
A seguir, atualize o caminho de classe de projeto do EJB de modo que ele encontrará os arquivos JAR:
Sob a pasta EJB Projects, clique com o botão direito do mouse no projeto OpenJPATest e selecione Properties (Figura 33).
Figura 33. Abrir as propriedades do projeto
Altere o diretório de saída para ser igual ao diretório de origem. Isso garantirá que a etapa JPA Enhancement funcione corretamente. Para fazer isso, selecione o item Java Build Path e altere a Default Output Folder para OpenJPATest/ejbModule (Figura 34).
Figura 34. Tornar o diretório de saída e o diretório de origem iguais
Troque para J2EE Module Dependencies e selecione todos os JARs, como mostrado na Figura 35.
Figura 35. Selecionar todos os arquivos JAR dependentes
Agora é possível importar a origem Java para o seu projeto.
Clique com o botão direito do mouse na pasta ejbModule sob o OpenJPATest Project e selecione Import.
Selecione File system e depois Next.
Presumindo que você expandiu os materiais de download em um diretório, insira a pasta
ejbModulesob o diretório de download (Figura 36).
Figura 36. Importar recursos obtidos por download
Quando solicitado a fornecer permissão para substituir, selecione Yes To All.
Configurar o desenvolvimento do Eclipse para incluir aprimoramento
A OpenJPA conta com aprimoramento de código de byte para adicionar comportamento de persistência aos objetos JPA. Há várias maneiras de aprimorar uma classe (consulte os Recursos). No nosso exemplo, fornecemos um script ANT simples que executa o otimizador. Para tornar o processo de desenvolvimento mais simples, você incorporará um desenvolvimento Ant como parte do desenvolvimento do Eclipse. Dessa maneira, ao compilar suas classes no Eclipse, o otimizador da JPA executará como parte do desenvolvimento. Isso simplificará o processo de desenvolvimento.
O script ANT é um script simples que utiliza a ferramenta de otimizador da OpenJPA. Abra o arquivo build.xml localizado na raiz do diretório ejbModule. O arquivo ANT aponta para o pacote de entidade, bem como para o arquivo persistence.xml. (Examinaremos esse arquivo na próxima seção.)
Figura 37. Abrir o arquivo build.xml
Listagem 1<project name="enhanceJPA"> <target name="enhance"> <!-- define the openjpac task; this can be done at the top of the --> <!-- build.xml file, so it will be available for all targets --> <taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask"/> <openjpac> <config propertiesFile="./META-INF/persistence.xml"/> <fileset dir="."> <include name="**/com/ibm/persistence/ejb3/order/entity/*.java" /> </fileset> <classpath> <pathelement location=”${basedir}” /> </classpath> </openjpac> </target> </project>
Para executar o otimizador como parte do desenvolvimento do Eclipse, é preciso configurar um otimizador:
Clique com o botão direito do mouse no projeto OpenJPATest EJB e selecione Properties.
Figura 38. Abrir as propriedades do projeto
Na seção Builders , pressione New e selecione Ant Build (Figura 39).
Figura 39. Configurar o desenvolvimento Ant
Atribua ao construtor o nome de
JPAEnhance.Na guia Main , navegue para o espaço de trabalho e selecione o arquivo build.xml sob o diretório ejbModule.
Na seção Base Directory, procure no espaço de trabalho e selecione ejbModule .
Na seção Arguments , adicione os sinalizadores
"-verbose -debug". A configuração final deve se parecer com a Figura 40.
Figura 40. Configurar construtor
Na guia Refresh , selecione Refresh resources upon completion para atualizar todo o espaço de trabalho uma vez que o aprimoramento estiver concluído (Figura 41).
Figura 41. Atualizar o espaço de trabalho à conclusão
Alterne para a guia Targets e selecione as tarefas enhance em Clean, Manual Build e Auto Build (Figura 42).
Figura 42. Selecionar tarefas enhance
Na guia Classpath (Figura 43), adicione todos os JARs da JPA pressionando Add Jar e adicionando todo o conteúdo de EAR procurando no espaço de trabalho e selecionando o arquivo EAR.
Por fim, adicione o arquivo j2ee.jar, que está no diretóro lib da sua instalação do WebSphere Application Server. Faça isso selecionando Add external JARs....
Figura 43. Adicionar arquivos JAR à configuração
Pressione OK para salvar o construtor.
A tarefa JPAEnhance deve ser a última coisa a acontecer no seu desenvolvimento (Figura 44). Se você tiver desenvolvimento automático, seu otimizador deve executar (Figura 45). A Figura 46 mostra um exemplo de saída de uma execução de aprimoramento bem-sucedida.
Figura 44. Tarefas de desenvolvimento
Figura 45. Ativar desenvolvimento automático
Figura 46. Saída de uma execução de aprimoramento bem-sucedida
Examinar o aplicativo de exemplo
Agora que configuramos o banco de dados, a configuração do servidor e o espaço de trabalho, vamos examinar o aplicativo. Já fornecemos uma visão geral da arquitetura, então apenas destacaremos o pacote e o visual da configuração da OpenJPA.
Usando o Project Explorer, expanda a pasta ejbModule para ver todos os pacotes. A Figura 47 resume o local dos pacotes.
O pacote de entidades JPA contém os objetos da entidade JPA anotados.
Figura 47. Todos os pacotes ejbModule
Examine as entidades. A Listagem 2 mostra o objeto Customer Entity. É possível torná-lo habilitado para persistência adicionando as anotações, como mostrado na classe abaixo.
Listagem 2package com.ibm.persistence.ejb3.order.entity; import java.io.Serializable; import javax.persistence.*; @Entity @Table(name="CUSTOMER", schema="CUSTSCH") public class Customer implements Serializable { private Integer id; private String name; private CustomerOrder currentOrder; @Id @Column(name="CUST_ID") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(name="NAME") public String getName() { return name; } public void setName(String name) { this.name = name; } @OneToOne(fetch=FetchType.EAGER,cascade = {CascadeType.MERGE,CascadeType.REFRESH},optional=true ) @JoinColumn(name="OPEN_ORDER_ID",referencedColumnName=" ORDER_ID") public CustomerOrder getCurrentOrder() { return currentOrder; } public void setCurrentOrder(CustomerOrder currentOrder) { this.currentOrder = currentOrder; } }
Além disso, é possível ver o pacote de fachada POJO contendo OrderProcessorBean. O pacote usa JPA para acessar e atualizar as entidades. A Listagem 3 mostra uma parte do OrderProcessorBean. Observe que no construtor buscamos dois EntityManagerFactories. Veremos por que na próxima seção.
Listagem 3public class OrderProcessorBean implements OrderProcessor { private EntityManagerFactory emf; private EntityManagerFactory emfPessLock; public OrderProcessorBean() { emf = EntityManagerFactoryHelper.getEntityManagerFactory("OrderDB"); emfPessLock = EntityManagerFactoryHelper.getEntityManagerFactory("OrderDBPessLock"); } public Customer findCustomerById(int customerId) throws CustomerDoesNotExist{ //1. Finds customers by ID. EntityManager em = null; try { em = emf.createEntityManager(); Customer customer = findCustomerByIdInternal(customerId,em); return customer; } finally { if (em != null) { em.close(); } } }
(Estamos usando gerenciadores de entidade gerenciadas por aplicativo. Isso significa que não podemos injetar o gerenciador de entidade no código de chamada. Em vez disso, devemos carregar EntityManagerFactory nós mesmos. Além disso, é preciso ter cuidado e fechar EntityManager quando tiver terminado de usá-lo. Isso será detalhado na próxima seção.)
O persistence.xml é o descritor que define a unidade de persistência que contém a configuração necessária para as entidades JPA e o banco de dados.
Abra o persistence.xml e examine os conteúdos.
Figura 48. Abrir persistence.xml
A Listagem 4 mostra persistence.xml. Observe que há duas unidades de persistência diferentes. Anteriormente, mencionamos que a classe OrderProcessor usava dois EntityMangerFactories. Uma vez que ambos têm padrões de acesso de leitura e gravação, precisamos definir um para cada tipo, um para leituras otimistas, outro para atualizações pessimistas. Diversas propriedades são definidas:
- Provedor da JPA: neste caso, OpenJPA.
- jta-data-source: neste caso, é uma referência de recurso definida no bean de sessão de chamada.
- TransactionMode: gerenciado; permite que a OpenJPA delegue transações ao contêiner EJB subjacente.
- ConnectionFactoryMode: gerenciado; permite que o servidor de aplicativos gerencie o acesso de conexão.
- DBDictionary property: permite a conversão adequada para consultas do DB2. Se estiver usando outro banco de dados, é preciso ajustar para o valor adequado (consulte a documentação da OpenJPA nos Recursos para os bancos de dados suportados).
- Propriedade LockManager: na segunda unidade persistente, define o bloqueio para pessimista, permitindo, por exemplo, que OpenJPA use "select for update" quando adequado.
- Propriedade Log: comentada, mas pode ser usada para ajudar a depurar possíveis problemas de uso da OpenJPA.
Listagem 4<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="OrderDB"> <provider> org.apache.openjpa.persistence.PersistenceProviderImpl </provider> <jta-data-source> java:comp/env/jdbc/orderds </jta-data-source> <properties> <property name="openjpa.TransactionMode" value="managed"/> <property name="openjpa.ConnectionFactoryMode" value="managed"/> <property name="openjpa.jdbc.DBDictionary" value="db2"/> <!-- <property name=”openjpa.Log” value=”Default=TRACE”/> --> </properties> </persistence-unit> <persistence-unit name="OrderDBPessLock"> <provider> org.apache.openjpa.persistence.PersistenceProviderImpl </provider> <jta-data-source>java:comp/env/jdbc/orderds</jta-data-source> <properties> <property name="openjpa.TransactionMode" value="managed"/> <property name="openjpa.ConnectionFactoryMode" value="managed"/> <property name="openjpa.jdbc.DBDictionary" value="db2"/> <property name="openjpa.LockManager" value="pessimistic(VersionCheckOnReadLock=true,VersionUpdate OnWriteLock=true)"/> <!-- <property name=”openjpa.Log” value=”Default=TRACE”/> --> </properties> </persistence-unit> </persistence>
Há dois tipos de configuração de EM:
- O tipo configurado por JTA recebe eventos transacionais (begin/commit/rollback) diretamente do serviço de transação.
- O tipo Recurso-Local aprende sobre esses eventos pelo aplicativo chamando a interface EntityTransaction.
Executar Open JPA no WebSphere Application Server V6.1 permite o processamento de transações JTA através da configuração acima. Porém, a JPA define a noção de gerenciador de entidade gerenciada por contêiner versus gerenciador de entidade gerenciada por aplicativo. Para entender a diferença, é preciso primeiro entender o que significa um conexto de persistência.
Um contexto de persistência é um conjunto de instâncias de entidade gerenciada em que, para qualquer identidade de entidade persistente, há uma única instância de entidade. Dentro do contexto de persistência, a associação da entidade com o armazenamento de persistência subjacente é gerenciada pelo entity manager (EM).
Uma instância de EM gerenciada por contêiner é criada direcionando o contêiner para injetar uma instância (seja através de injeção direta ou por consulta JNDI semelhante à injeção); a vida útil dessa instância de EM é controlada pelo contêiner; a instância corresponde à vida útil do componente no qual foi injetada. Para cada instância de EM gerenciada por contêiner, há um ou mais persistence contexts (PC) gerenciados por contêiner correspondentes . No momento em que o PC é criado, ele é vinculado à transação simultaneamente em vigor e propagado pelo contêiner, junto com o contexto de transação, para outros componentes chamados dentro da mesma JVM. O cenário de uso gerenciado por contêiner é subclassificado ainda em de escopo de transação (a vida útil é controlada pela transação) e estendido (a vida útil é controlada por uma ou mais instâncias de bean de sessão stateful).
Uma transação no estilo instância de EM gerenciada por aplicativo é criada chamando o (que pode, ele mesmo, ser injetado, ou consultado, em um JNDI), e a vida útil dessa instância é controlada pelo aplicativo. Para cada instância de EM gerenciada por aplicativo, há um ou mais contextos de persistência gerenciada por aplicativo correspondente, que não estão vinculados a nenhuma transação (isolada) e não são propagados para outros componentes. Isso não significa que os gerenciadores de entidade gerenciada por aplicativo não podem ser configurados como gerenciadores de entidade JTA. Entretanto, é importante perceber a necessidade de abrir e fechar o gerenciador de entidade você mesmo.
Gerenciadores de entidade gerenciada por contêiner e gerenciadores de entidade gerenciada por aplicativo (e seus contextos de persistência) precisam ser suportados nos contêineres da web Java EE Versão 5 e EJB. Dentro de um ambiente EJB, normalmente são usados gerenciadores de entidade gerenciada por contêiner. Ao usar OpenJPA com o WebSphere Application Server V6.1, apenas gerenciadores de entidade gerenciada por aplicativo podem ser utilizados. Contudo, conforme dito, o gerenciador de entidade gerenciada por aplicativo ainda pode ser configurado usando JTA. A criação de camadas adequada do código deve ajudar na transferência para gerenciadores de entidade gerenciada por contêiner ao passar para o Feature Pack EJB 3.0 ou posterior.
Para testar nosso aplicativo, fornecemos um servlet de teste simples que executa nossos casos de uso na sequência desejada.
Primeiro, é preciso importar os artefatos da web:
Clique com o botão direito do mouse no projeto OpenJPATestWeb e selecione Import (Figura 49).
Figura 49. Importar artefatos da web
Selecione File System e depois Next.
No campo Directory, navegue para <<download materials>>/WebClient (Figura 50). Certifique-se de que a pasta Into esteja na raiz do projeto da web. Pressione Finish.
Figura 50. Navegar para o cliente da web obtido por download
Pressione Yes to All para substituir o padrão.
Figura 51. Substituir a configuração padrão
A seguir, é preciso atualizar o caminho de classe do projeto da web para apontar para o arquivo JAR do EJB.
Clique com o botão direito do mouse no projeto da web e selecione Properties (Figura 52).
Figura 52. Atualizar as propriedades do projeto
Sob J2EE Module Dependencies, selecione o arquivo OpenJPATest.jar e pressione OK (Figura 53).
Figura 53. Selecionar arquivo JAR
Executar aplicativo no WebSphere Application Server V6.1 através do Application Server Toolkit
Executar o aplicativo envolve apenas instalar o arquivo EAR e chamar o servlet de teste. É possível fazer isso em qualquer um dos modelos de implementação suportados do WebSphere Application Server. Na nossa amostra, apenas testamos diretamente a partir do Application Server Toolkit.
Para instalar o aplicativo a partir do Application Server Toolkit, tudo o que você precisa fazer é adicionar o aplicativo ao servidor:
Na visualização Server, clique com o botão direito do mouse em WebSphere v6.1 Server e selecione Add and Remove Projects... (Figura 54).
Figura 54. Adicionar um projeto ao servidor
Selecione o aplicativo OpenJPATestEAR em Available projects e selecione Add para transferi-lo para Configured projects (Figura 55). Pressione Finish.
Figura 55. transferir projetos disponíveis para projetos configurados
Monitore o console para o servidor inicial e o aplicativo (Figura 56). (Se o servidor não iniciar, clique com o botão direito do mouse e pressione Start.)
Figura 56. Mensagens do console para aplicativo e servidor
Quando o aplicativo for iniciado, é possível testar o servlet:
Expanda OpenJPATestWeb => Servlets => JPATester. Clique com o botão direito do mouse em JPATester e depois selecione Run As => Run on Server (Figura 57).
Figura 57. Testar servlet
Consulte Set server as project default (Figura 58). (Isso acontece apenas na primeira vez que o projeto é executado.)
Figura 58. Definir padrão do projeto
O navegador deve abrir e exibir os resultados mostrados na Figura 59. O servlet executando adequadamente exibirá um cliente sem um pedido, abrir o pedido para um cliente, adicionar alguns itens de linha e então enviará o pedido.
Figura 59. Resultados do teste
O EJB 3 é uma importante atualização à especificação EJB que simplifica muito a programação de EJB. A Java Persistence API (JPA) representa um grande aprimoramento à programação de persistência da especificação EJB 3. A Apache OpenJPA fornece uma grande oportunidade para começar a usar JPA na plataforma WebSphere Application Server. Configurando e executando o aplicativo de amostra, você viu como pode ser simples começar a usar JPA para novos projetos de desenvolvimento hoje.
Os autores gostariam de agradecer Randy Schnier, Jim Knutson, Jonathan Marshall e Robert Peterson pelas suas contribuições a este artigo.
| Descrição | Nome | Tamanho | Método de download |
|---|---|---|---|
| Sample application | OpenJPASample.kws.zip | 26 KB | HTTP |
Informações sobre métodos de download
-
SR 220: Especificação de Enterprise JavaBeans 3.0
-
JSR 317: Java Persistence API 2.0
-
JSR 303: Validação de Bean
-
Apache OpenJPA
-
An Update on Java Persistence API 2.0
-
Dynamic, typesafe Queries in JPA 2.0
-
OpenJPA Enhancement
-
Pro EJB 3, Java Persistence API
-
Pro JPA 2, Mastering the Java Persistence API
-
Enterprise JavaBeans 3.0
-
Examining the EJB 3.0 Simplified API
-
IBM WebSphere: Deployment and Advanced Configuration
-
Developing custom mediations for WebSphere Enterprise Service Bus
-
IBM WebSphere System Administration
-
WebSphere Application Server: Step-by-step
-
WebSphere Application Server Information Center

Kevin Sutter é um Engenheiro de Software Senior do grupo de desenvolvimento do WebSphere Application Server. Ele é atualmente o arquiteto principal para a solução Java Persistence API para o WebSphere Application Server. Kevin também é committer e membro do PMC para o projeto Apache OpenJPA. As funções anteriores de Kevin incluem realizar a liderança e arquitetura de soluções WebSphere para J2EE Connector Architecture (JCA) e WebSphere eXtremeScale (estrutura de armazenamento em cache).

Roland Barcia é Senior Technical Staff Member e Arquiteto líder de Web 2.0 para O IBM Software Services para WebSphere.