Buscar

JPA-com-Hibernate

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 13 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 13 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 13 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

JPA com Hibernate
Rascunho
Autor:Ivan Salvadori
1. Introdução ao JPA com Hibernate.
JPA ou Java Persistence API, é uma padronização da linguagem Java, para mapeamento 
objeto/relacional. Em outras palavras, é a padronização de um mecanismo capaz de armazenar no 
banco de dados as classes do modelo da aplicação que necessitam de persistência. Este mecanismo 
visa promover todos os recursos de banco de dados, sem a necessidade de manipulação direta de 
instruções SQL.
Hibernate é um framework que implementa a especificação do JPA. É o verdadeiro 
responsável pela execução do mecanismo de persistência de dados. JPA define as regras enquanto o 
Hibernate as executa. Existem várias outras implementações do JPA, como o TopLink da Oracle. 
Essas implementações são também são chamadas de Provider, ( Provedor ). 
Para mostrar realmente o objetivo do JPA, imagine o seguinte cenário:
Desejo gravar no banco de dados informações de cadastros dos meus clientes.
A forma tradicional de manipulação de banco de dados em Java trabalha diretamente com 
criação de conexões, elaboração de instruções SQL, atribuição de valores a estas instruções seguido 
da execução das querys. 
Para inserir um cliente, uma classe responsável pela manipulação do banco, geralmente um 
DAO, recebe o objeto do tipo Cliente, com as informações desejadas já definidas no objeto. De 
posse desse objeto, as informações são extraídas através dos métodos getter's, e inseridas na 
instrução SQL de INSERT.
String comando = "insert into Cliente (nome, cpf, rg, telefone ,data_nasc) 
 values (?, ?, ?, ?, ?)";
Ilustração 1: Classe Cliente.
Ilustração 2: Mecanismo Tradicional de Gravação.
O trecho de código abaixo mostra a forma tradicional de gravação de informações dos 
clientes no banco de dados MySql.
java.sql.Connection con;
 
try {
 con = DriverManager.getConnection("jdbc:mysql://localhost:3306/base", "user","senha");
} catch(SQLException e) {
 throw new RuntimeException(e);
}
 String comando = "insert into Cliente (nome, data_nasc, telefone, rg, cpf) 
values (?,?,?,?,?)";
 
 PreparedStatement stmt;
try {
stmt = con.prepareStatement(comando);
stmt.setString(1, cliente.getNome() );
 stmt.setDate(2, new 
java.sql.Date(cliente.getDataNasc().getTime() ) ); //formata data para sql
 
stmt.setString(3, cliente.getTelefone() );
 stmt.setString(4, cliente.getRg() );
 stmt.setString(5, cliente.getCpf() );
 
 stmt.execute();
 stmt.close();
 con.close();
} catch (SQLException e) {
e.printStackTrace();
}
Para listar os clientes gravados o banco, executa-se um instrução SQL SELECT, com os 
dados obtidos do banco é construído um objeto do tipo Cliente, e definido as suas propriedades 
através dos métodos setter's.
PreparedStatement stmt = con.prepareStatement("select * from Cliente");
while (rs.next()) {
Cliente c = new Cliente();
c.setCodigo(rs.getInt("codigo"));
c.setNome(rs.getString("nome"));
c.setRg(rs.getString("rg"));
c.setCpf(rs.getString("cpf"));
c.setTelefone(rs.getString("telefone"));
c.setDataNasc( rs.getDate("data_nasc") );
}
Ilustração 3: Mecanismo Tradicional de Seleção.
Analisando os mecanismos e códigos ilustrados anteriormente, nota-se que para implementar um 
sistema de médio a grande porte, uma esforço consideravelmente grande se faz necessário para 
tratar os assuntos de manipulação do banco de dados, observa-se também que as classes com essas 
responsabilidades são extensas, qualquer alteração no banco de dados implica em manutenção do 
código. 
JPA se propõem a facilitar esse trabalho, abstraindo os detalhes do banco de dados e 
concentrando-se nas suas funções. Imagine agora gravar o mesmo objeto cliente citado no esquema 
anterior, mas agora sem se preocupar com os detalhes físicos da tabelas, nome dos campos, 
conversões de tipos dentre outros detalhes. O trecho de código abaixo mostra como seria o processo 
de gravação no banco de dados utilizando o JPA com Hibernate.
public void gravar(Cliente cliente) {
hibernate.gravar(cliente);
}
Mecanismo de procura por um determinado cliente a partir do seu código:
public Cliente procurar(int codigo) {
return hibernate.procurar(Cliente.class, codigo);
}
Lembrando que os códigos acima apenas demonstram a filosofia do mecanismo utilizado 
pelo JPA, em um caso real, um pouco mais de código é necessário.
Com os exemplos anteriores, pode-se notar que toda a implementação da persistência dos 
dados fica sob responsabilidade do FrameWork, retirando toda a manipulação direta com o banco 
de dados. Caso alguma alteração seja feita na classe Cliente, que consequentemente provoque 
alguma alteração na tabela que armazena seus dados, nenhum código sofrerá alteração, diminuindo 
muito o custo de manutenção. Isso é possível pois o JPA com Hibernate representa uma camada 
extra entre a aplicação e o JDBC, até então programado diretamente pelo desenvolvedor.
JPA nos possibilita desenvolver toda a persistência com o mínimo de código possível através 
de uma forma fantástica, mas como é possível realizar essa facilidade? Será o Assunto dos 
próximos capítulos.
Ilustração 4: Estrutura JPA – Hibernate . Adaptado de Bellia, Renato. 
Revista Java Magazine, ed. 44, p. 28. 
 Banco de Dados
Aplicação
JPA
Hibernate
JDBC
2. Entendendo o Framework.
Segundo FLÁVIO HENRIQUE CURTE, Antares Information Systems:
A ideia da persistência O/R é reunir as vantagens de se utilizar um modelo orientado a 
objetos para a construção de uma aplicação, com a performance e a confiabilidade dos bancos de 
dados relacionais. (adaptado de JPA: Persistência padronizada em Java).
O modelo orientado a objetos nos dá muito mais recursos para a representação da 
informação, fica muito mais fácil de entender e principalmente desenvolver software fazendo uso 
do paradigma dos objetos, por outro lado, o modelo relacional é excelente para armazenamento 
físico das informações. Criou-se ai um empasse, sendo necessário uma especie de tradução entre um 
modelo para o outro. A introdução desse material exemplificou a forma que essa “tradução” é 
realizada via JDBC. A Especificação JPA possibilita trabalhar com o modelo relacional dos bancos 
de dados, com a representação do modelo orientado a objetos. Observe o código a seguir:
public void gravar(Cliente cliente) {
hibernate.gravar(cliente);
}
Como é possível o framework Hibernate realizar a gravação das informações do objeto 
cliente no banco de dados?
Para que isso seja possível, o Hibernate deve ter conhecimento das informações do objeto 
cliente, assim como conhecer os detalhes do banco de dados. É necessário o conhecimento do 
conteúdo das tabelas dentre outras informações ligadas ao projeto relacional. 
Vamos recorrer ao nosso problema de cadastro de clientes, temos a nossa Classe Cliente que 
deve ter as suas propriedades gravadas. A tabela Cliente da suporte para a gravação de todas as 
informações da classe. Dessa forma a classe cliente será armazenada na tabela Cliente. Cada 
atributo da classe será gravado em uma coluna da tabela com seu respectivo nome. A Ilustração 5 
demonstra como deve ser o mapeamento da classe Cliente para a tabela Cliente.
Ilustração 5: Mapeamento classe Cliente para a tabela Cliente.
A configuração do Hibernate envolve a especificação deste mapeamento, definido quais 
atributos serão gravados em cada campo de uma tabela no banco de dados. Essa configuração se faz 
por meio de anotações. Anotações são instruções que descrevem informações sobre a classe. Vamos 
um exemplo prático. O código abaixo mostra a classe Cliente, totalmente anotada, trazendo as 
informações que o frameworknecessita para realizar o mapeamento para a tabela do banco de 
dados que irá armazená-la. 
@Entity
@Table(name = "Cliente")
public class Cliente implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(unique=true, nullable=false)
private int codigo;
@Column(length=45)
private String cpf;
@Column(length=45)
private String rg;
@Column(length=45)
private String nome;
@Column(length=45)
private String telefone;
@Column(name = "data_nasc")
@Temporal(TemporalType.DATE)
private Date dataNascimento;
set's()
get's()
}
Repare a presença de estruturas que iniciam com “ @ ”, são as anotações. Existe diferentes 
tipos de anotações, cada uma denota uma configuração diferente, definido informações a 
componentes que a procedem, vamos explicar algumas:
@Entity - Esta anotação diz que essa classe é uma entidade, portanto será persistida. ( uma 
classe é chamada de entidade quando caracterizar necessidade de gravação no banco de dados de 
suas propriedades ).
@Table(name = "Cliente") – Anotação responsável por apontar em qual tabela a classe será 
armazenada, neste caso na tabela Cliente.
@Id - Define o identificador único da entidade, será a chave primária da tabela. 
@GeneratedValue(strategy=GenerationType.IDENTITY) – Código auto incrementável.
@Column(unique=true, nullable=false) – Diz que o atributo será gravado na coluna 
especificada. Caso não seja informado um nome, a coluna assume o mesmo nome do atributo. As 
opções de (unique=true, nullable=false) informam que o código é único e não aceita valores nulos.
@Column(name = "data_nasc") – Define um nome da coluna da tabela diferente do nome 
do atributo da classe. O atributo dataNascimento será gravado na coluna data_nasc.
@Temporal(TemporalType.DATE) – Anotação que indica que o tipo de atributo é uma data 
e será armazenado com essa característica.
Com as anotações anteriores a instrução “ hibernate.gravar(cliente); ” agora parece 
totalmente possível de acontecer, pois a classe Cliente possui todas as informações referentes a sua 
gravação no banco. A configuração requer ainda as informações para realizar a conexão com o 
banco de dados, como por exemplo endereço ip do servidor, usuário e senha. Há um arquivo 
especifico destinado a guardar essa configuração, persistence.xml. A listagem a seguir mostra um 
exemplo dessa configuração.
<?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="ClienteJPA">
<class>Cliente</class>
<properties>
<property name="hibernate.dialect" 
value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.connection.driver_class" 
value="org.gjt.mm.mysql.Driver" />
<property name="hibernate.connection.url" 
value="jdbc:mysql://localhost/nomeDaBase" />
<property name="hibernate.connection.username" value="usuario" />
<property name="hibernate.connection.password" value="senha" />
</properties>
</persistence-unit>
</persistence>
Algumas considerações sobre a listagem anterior:
<class>Cliente</class> - Classe a ser gerenciada pelo JPA.
<persistence-unit name="ClienteJPA"> - Numa solicitação de serviços do JPA, uma 
conexão será criada utilizando um persistence-unit, identificado através de seu nome, onde as 
informações necessárias para a estabelecer uma conexão com o banco estão presentes.
As clausulas property informam os detalhes da conexão, identificando o tipo de banco de 
dados utilizado, endereço do servidor, senha, usuário dentre outras informações. 
Outro conceito que o JPA nos apresenta é o EntityManager, responsável pela execução dos 
serviços de persistência do framework. Ele gerencia as entidades, estabelece a conexão com o banco 
de dados, executa as operações de gravação, alteração, remoção e seleção das classes anotadas. O 
EntityManager é criado baseando-se em no persistence-unit definido no persistence.xml. O 
código que segue, demostra a criação do gerenciador.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("ClienteJPA");
EntityManager em = emf.createEntityManager();
Repare que o parametro de contruçao do gerenciador é o mesmo nome contido no valor 
name da unidade de persistencia. 
 <persistence-unit name="ClienteJPA">
Nos exemplos anteriores, tratamos apenas a filosofia de funcionamento do Hibernate, o 
exemplo a seguir mostra o código que realiza a gravação de um objeto cliente, no banco de dados, 
mas dessa vez utilizando a sintaxe completa do JPA.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("ClienteJPA");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(cliente);
em.getTransaction().commit();
em.close();
emf.close();
O exemplo cria um EntityManager, fazendo referência ao persistence-unit configurado no 
arquivo persistence.xml, em seguida uma transação é iniciada.
em.getTransaction().begin();
A instrução abaixo diz ao EntityManager para executar a gravação, no banco de dados, do 
objeto cliente passado por parâmetro. Persist significa persistir, armazenar, gravar.
em.persist(cliente);
Para que o objeto seja realmente gravado, deve-se dar a ordem de exucação de gravação, 
isso se faz através do código abaixo. Commit concretiza a solicitação do recurso de gravação.
em.getTransaction().commit();
Para finalizar, encerra-se a transação.
em.close();
emf.close();
Para realizar uma seleção, o mecanismo é similar, vamos a um exemplo de procura de um 
cliente a partir do seu código:
em.getTransaction().begin();
compra = em.find(Compra.class, codigo); 
em.getTransaction().commit();
No exemplo acima, uma transação é iniciada, e o método find localiza a partir do código o 
objeto, os dois parâmetros da procura são a classe do objeto, que serve de referencia para dizer 
aonde procurar, e o código, que diz oque procurar. 
O código abaixo mostra como alterar os objetos:
entityManager.merge(cliente);
O método merge atualiza o registro da tabela do banco que possui o mesmo código do 
objeto passado por parâmetro. As ilustrações 6 e 7 mostram o processo de atualização do objeto 
cliente.
Cliente cliente = new Cliente();
cliente.setNome("José Serra");
cliente.setRg("123");
cliente.setCpf("456");
cliente.setTelefone("999");
cliente.setCodigo(5);
em.getTransaction().begin();
em.merge(cliente);
em.getTransaction().commit();
O exemplo anterior altera os valores do cpf, rg e telefone do registro de código 5. Repare 
que a data de nascimento não foi definida no objeto cliente alterado, sendo assim, o atributo alterou 
o valor armazenado na tabela por valores nulos. Para que ocorra a alteração é necessário que o 
código do cliente esta definido no objeto passado por parâmetro.
Agora vamos remover o registro que foi alterado no exemplo anterior, seguindo o principio 
dos exemplos temos:
Cliente cliente = new Cliente();
cliente.setNome("José Serra");
cliente.setRg("123");
cliente.setCpf("456");
cliente.setTelefone("999");
cliente.setCodigo(5);
em.getTransaction().begin();
em.remove(cliente);
em.getTransaction().commit();
Recebemos o seguinte erro:
Exception in thread "main" java.lang.IllegalArgumentException: 
Removing a detached instance Cliente
Ilustração 6: Registro antes da alteração.
Ilustração 7: Registro depois da alteração.
Para explicar oque ocorreu errado na tentativa de remover o registro, tem-se que entender o
conceito de entidades gerenciadas pelo JPA. Ao criar objetos na aplicação, inicialmente esses não 
estão sendo gerenciados pelo JPA. 
Ao executar operações de persistência, como por exemplopersist, a entidade é gravada no 
banco de dados e passa a ser gerenciada pelo framework.
Na tentativa de remoção, que resultou no erro, tinha-se o seguinte cenário:
Ilustração 8 : Entidades não gerenciadas pelo JPA. 
Entidades Monitoradas pelo JPA
 Cliente titi = new Cliente();
 cliente.setNome("Carvo");
 cliente.setCpf("4445988-5");
 cliente.setRg("48053400");
 cliente.setTelefone("4833666");
 Cliente bi = new Cliente();
 cliente.setNome("bianchi");
 cliente.setCpf("5433535");
 cliente.setRg("34567454");
 cliente.setTelefone("483233");
Ilustração 9: Processo de gerenciamento de entidades JPA.
Entidades Monitoradas pelo JPA
 Cliente carvo = new Cliente();
 cliente.setNome("Carvo");
 cliente.setCpf("4445988-5");
 cliente.setRg("48053400");
 cliente.setTelefone("4833666"); Cliente bi = new Cliente();
 cliente.setNome("bianchi");
 cliente.setCpf("5433535");
 cliente.setRg("34567454");
 cliente.setTelefone("483233");
 em.getTransaction().begin();
 em.persist(cliente);
 em.getTransaction().commit();
Ilustração 10 : Tentativa de remoção de entidade não gerenciada. 
Cliente cliente = new Cliente();
cliente.setNome("José Serra");
cliente.setRg("123");
cliente.setCpf("456");
cliente.setTelefone("999");
cliente.setCodigo(5);
 em.getTransaction().begin();
 em.remove(cliente);
 em.getTransaction().commit();
Entidades Monitoradas pelo JPA
ERRO
Note que a remoção se aplicou a uma entidade que não estava sendo gerenciada pelo JPA, este é o 
motivo do erro. O JPA não pode remover uma entidade que não é gerenciada por ele. Sendo assim, a 
entidade que deseja-se remover deve estar sob o domínio do framework. Uma forma de fazer isso é 
solicitar que o Hibernate faça a pesquisa da entidade. Toda a entidade selecionada do banco de 
dados através do framework, está sob gerenciamento. O código que segue mostra a implementação 
da solução encontrada.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPAExemplo");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Cliente c = em.find(Cliente.class, 5);
em.getTransaction().commit();
em.getTransaction().begin();
em.remove(c);
em.getTransaction().commit();
em.close();
emf.close();
Resumo do Capítulo:
A forma tradicional de manipulação de informações em banco de dados, envolve um código 
muito extenso e propenso a erros e profundas modificações caso seja necessário qualquer 
modificação na configuração dos dados. A pratica de uso JDBC despende de grande esforço para o 
desenvolvimento e consequentemente na manutenção dos sistemas.
JPA vem com a proposta de facilitar o penoso trabalho de manipular informações que 
precisam ser gravadas em banco de dados, tornando a manipulação de banco de dados, que segue o 
paradigma relacional, em uma abordagem orientada a objeto.
O Hibernate é uma implementação da especificação padrão, e a configuração do framework 
se faz principalmente por meio de anotações nas classes que sofreram persistência. As 
configurações físicas do banco de dados ficam no arquivo persistence.xml, que contém todas as 
propriedades do sistema gerenciador de banco de dados a a ser utilizado.
As funções de manipulação de dados são realizadas por métodos do gerenciador de 
entidades, sendo essas persist, merge, find e remove. O JPA mantem sob seu gerenciamento as 
entidades que manipula. 
Este capitulo mostrou os conceitos básicos do JPA com Hibernate, seus principais 
componentes, conceitos e configurações.
Ilustração 11: Remoção de entidade gerenciada.
 em.getTransaction().begin();
 Cliente c = em.find(Cliente.class, 5);
 em.getTransaction().commit();
 em.getTransaction().begin();
 em.remove(c);
 em.getTransaction().commit();
Entidades Monitoradas pelo JPA
Nome = ("José Serra");
Rg = ("123");
Cpf = ("456");
Telefone = ("999");
Codigo = (5);
.....
Remoção 
Realizada
3. Implementando JPA no projeto JSF. 
Iniciamos anteriormente um projeto JSF de cadastro de clientes, que utiliza JDBC para 
manipular as operações com o banco de dados, vamos construir uma implementação JPA com 
Hibernate para realizar essa tarefa, e veremos as vantagens ao se desenvolver utilizando esta 
tecnologia. 
A ilustração 12 mostra o diagrama de classe do projeto e evidencia a nova classe que 
implementará a interface ClienteDAO utilizando JPA. A ilustração 13 representa o Diagrama ER, 
observe que não houve alteração nenhuma do banco de dados.
Ilustração 12: Diagrama de Classe Adaptado para JPA
Ilustração 13: Diagrama ER do Projeto Cadastro Clientes
Com a estrutura do projeto redefinida, vamos agora a implementação. Devemos acrescentar 
a classe JPAClienteDAO ao projeto, mas antes disso temos que adicionar ao projeto JSF, as funções 
JPA com Hibernate. Vá as propriedades do projeto e selecione a opção Project Facets. Selecione a 
opção Java Persistence e clique em OK.
Concluída esta etapa, o projeto passa a possuir características JSF e JPA, em outras palavras, 
o projeto agrega funcionalidades dos dois Frameworks. Observe que agora está presente o arquivo 
de configuração do Hibernate.
Ilustração 14: Adicionando Funcionalidades JPA ao Projeto.
Ilustração 15: Estrutura JPA ao Projeto JSF.

Continue navegando