CAPÍTULO 3: ANÁLISE DE DOMÍNIO PARA A CONSTRUÇÃO DO
4.2 Java Enterprise Edition
4.2.6 Java Persistência API
O Java EE 5.0 possui novas APIs (Application Programming Interface) que aumentam a produtividade dos desenvolvedores, diminuindo os esforços para codificação. A Java Persistence API (JPA) padroniza as operações de persistência sobre tabelas em entidades Java, definindo uma especificação para objeto-relacional.
Na JPA, os objetos persistentes são chamados de entidades (entities), que representam um objeto simples, denominado POJO (Plain Old Java Objects) e são representadas por um conjunto de dados persistido no banco. Cada entidade possui um identificador (chave
primária). Para que uma entidade possa ser persistente devemos associá-la a um contexto de persistência (persistence context), que permite a conexão com o banco de dados. Todas as operações básicas em entidades, como criação, exclusão e alteração são controladas pelo Entity Manager, que é uma implementação da interface javax.persistence.EntityManager
A implementação da persistência é feita por um provedor de persistência, ele define o funcionamento das interfaces definidas pela especificação JPA. Dessa forma o provedor é que define a forma de sincronismo com o banco de dados. Essas configurações são realizados no arquivo presistence.xml.
<?xml version="1.0" encoding="UTF-8" ?>
- <persistence version="1.0" 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">
- <persistence-unit name="PPP">
<jta-data-source>java:/PostgresDS</jta-data-source>
- <properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
Figura 4.5 Exemplo de código do arquivo persistence.xml
A Figura 4.5, apresenta a configuração do Hibernate, que foi utilizado como o provedor de persitência para o desenvolvimento desse trabalho (HIBERNATE, 2007). Antes da especificação JPA, a utilização do Hibernate era realizada através de um mapeamento da classe/atributos com tabela/campos para uma arquivo Extensible Markup Language (XML).
Com a implementação JPA essa configuração é desnecessária. A JPA pode mapear automaticamente seus objetos Java para uma variedade de banco de dados relacionais. O desenvolvedor pode usar a JPA fora de um servidor de aplicações, em programas Java simples, usando provedores de persistência que implementam a especificação.
Na próxima seção será apresentado os mapeamentos.
4.2.6.1 Mapeamento de Entidades
Para que uma classe se torne persistente, é preciso seguir algumas convenções e definir alguns metadados (anotações). Uma entidade é uma classe, rotulada através da notação
@Entity. No código a seguir, a classe Cargo representa uma entidade e atributo codCar é o identificador da entidade, especificado através da anotação @Id.
package br.cefet.campos.info.taii20071n.perfil.model;
import javax.persistence.*;
@Entity
public class Cargo {
@Id
private int codCar;
private String titCar;
private String codCbo;
private String desCar;
public Cargo() { }
}
Figura 4.6 Mapeamento de persistência da Classe Cargo
No exemplo da Figura 4.6, o JPA considera que a tabela do banco de dados possui o mesmo nome da entidade (Cargo), e os atributos têm o mesmo nome dos campos da tabela.
Através das anotações @Table e @Columm é possível mudar a forma de mapeamento, alterando o nome da tabela e do campo.
A fim de modelar conceitos do mundo real, as entidades devem ser capazes de formar relacionamentos complexos. Diversos tipos de relacionamentos são possíveis, os mais comuns são: um para muitos (@OneToMany); muitos para um (@ManyToOne) e muitos para muitos (@ManyToMany).
@Entity
public class Cargo {
@Id
private int codCar;
private String titCar;
@Entity
public class Local {
@Id
private int codLoc;
private String nomLoc;
private String desLoc;
@Entity
public class PPRALocalCargo {
@Id
private int codppra;
@ManyToOne
@JoinColumn(name="codcar") private Cargo codcar;
@ManyToOne
@JoinColumn(name="codris") private Risco codris;
@ManyToOne
@JoinColumn(name="codloc") private Local codloc;
private String tecuti;
private String itencon;
private Date datfim;
@Entity
public class Risco {
@Id
private int codris;
private String tipris;
private String desris;
Figura 4.7 Exemplo de código do relacionamento muitos para um unidirecinal.
A figura 4.7 mostra um exemplo de relacionamento de muitos-para-um unidirecional em que a classe PPRALocalCargo possui uma referência para um objeto das classes Local, Cargo e Risco. Este relacionamento surge quando muitas entidades referenciam uma única entidade, a entidade referenciada não tem conhecimento do relacionamento.
4.2.6.2 Persistência a Entidades
Como mencionado anteriormente, a interface EntityManager é responsável pelas operações de persistência. Nesse trabalho, foi implementado a persistência a partir do servidor de Aplicação JBoss e declarada a notação @PersistenceContext para criação de um container.
As definições de configuração da conexão e entidades estão no arquivo de configuração persistence.xml.
A classe EntityManager define os principais métodos para execução de operações CRUD (Create, Read, Update e Delete) com entidades. As inserções são realizadas através do método persist(), a exclusão através do método remove() e a alteração através do método merge(). O método find() é utilizado para localizar.
@Stateless
public class CargoHelper implements ICargoHelper { @PersistenceContext (unitName = "PPP") private EntityManager entCargo;
public void save(Cargo cargo ){
Cargo car = entCargo.find(Cargo.class, cargo.getCodCar());
if (car == null)
entCargo.persist(cargo);
else
entCargo.merge(cargo);
}
public void delete(Cargo local){
Cargo mCargo = entCargo.merge(local);
entCargo.remove(mCargo);}
public Cargo busca(int codCar){
return entCargo.find(Cargo.class, codCar); } }
Figura 4.8 Implentação de persitência na classe Cargo
A figura 4.8 mostra a classe CargoHelper que utiliza uma variável Entity Manager, para realizar todas as operações de inclusão, alteração, exclusão e consulta. Nessa classe, injeção de dependências surge para simplificar a vida do programador, já que o gerenciador de entidades (EntityManager) é instanciado e controlado pelo servidor de aplicações. O código de persistência é muito simples, e até mesmo consultas que seriam complexas ficam simples na linguagem de consulta da JPA.