JPA com Hibernate + JSF + MySQL
![]()
olá Pessoal,
Neste post, vou mostrar como usar JPA para seus projetos JEE tendo como provider o nosso Hibernate e para o view usaremos JSF. Alguns adoram o TopLink da Oracle, eu tive serios problemas com ele na parte de config, e cansei de me stressar com coisas operacionais e mantenho meu querido Hibernate como provider.
Aplicação será bem simples, apenas cadastrar um cliente. Limitamos os dados do form, pois o objetivo é mostrar como criar um ambiente para development tendo JPA nos seus projetos. Já mostrei em outros posts, como criar um projeto JPA para Java Básico. Então, recebi alguns emails e para JEE?
Lets go…
Oportunidade Java:
Estamos disponibilizando uma vaga para desenvolvedor Senior Web
. Carga horária será de 8 horas diárias. Os requisitos técnicos para esta contratação são:
- Conhecimentos nas APIs: JSF, Hibernate;
- Conhecimentos nos patterns MVC, DAO, VO;
- Desejável conhecimento em RichFaces
Regime De trabalho é CLT. O salário será de 4.000 mais benefícios.
Interessados enviar currículos para atendimento@leiria.com.br
Obrigado.
Posts relacionados
Requisitos
-
MySQL 5.0.x
-
Hibernate – Download .jars
-
JSF 1.2 – Download .jars
Iniciando
Na imagem a seguir você tem toda a estrutura do projeto, observe que já criei as bibliotecas para o projeto e estas foram adicionadas. Se não quiser adicioanr as bibliotecas ao projeto, copie os .jars para a pasta lib e pronto. Lembre-se que ao adicionar uma biblioteca ao projeto, o stupid Eclipse não copia os .jars para a pasta lib. (ao contrário do netbeans
).
Não esqueça também de criar um schema e uma table no MySQL, aqui chamaremos de sistemas e clientes respectivamente.

1.monte uma estrutura conforme a imagem acima.
Para os arquivos em .jsp e .xml tive que colocar no formato imagem. Infelizmente o plugin para code no wordpress, esse é estressante quando envolve xml, html etc. preciso ficar dando um espaco para cada par de < > senão ele bagunça todo código ou até converte para qualquer outra coisa. Já gastei 1 hora somente para tentar configurar isso. Em função disso, coloquei no formato img o code bem organizado. O lado bom, é que você poderá praticar sem dar ctrl + c e ctrl + v.
E como sempre boa parte das explanações estão dentro do code no formato de comentário, lado-lado para facilar a compreensão.
Desenvolvimento
2.primeiro passo é criar o bean e fazer as devidas anotações, então veja abaixo o nosso cliente bean como está:
package br.com.bean;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="cliente")//caso o nome da tabela seja diferente informe aqui
public class Cliente {
@Column(name="nome")
private String nome;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
//anotação acima indica que o campo será gerado automaticamente pelo BD
@Column(name="id")
private int id;
@Column(name="sobrenome")
private String sobrenome;
@Column(name="cidade")
private String cidade;
public Cliente() {
// TODO Auto-generated constructor stub
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSobrenome() {
return sobrenome;
}
public void setSobrenome(String sobrenome) {
this.sobrenome = sobrenome;
}
public String getCidade() {
return cidade;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
}
Agora vamos partir para criar o nosso DAO, que nele teremos a nossa fábrica de conexão. E poderiamos ter métodos genéricos como salvar, deletar, atualizar etc.Mas, não vamos implementar todos.
package br.com.dao;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class DAO {
private EntityManagerFactory emf;
/* se vc já está acostumado com Hibernate
* a ideia é a mesma do método de fabrica que
* criamos para os Session que vem do SessionFactory
* Aqui temos apenas nomeclatura diferente, pense assim.
*/
public EntityManager getEntityManager(){
//responsavel pela persistencia
return emf.createEntityManager();
}
public DAO() {
//chamo ele de reprodutor da instância
emf = Persistence.createEntityManagerFactory("sistemas");
/* o nome passado vem do arquivo persistence.xml que contém as configs
* para conexão com o BD.
*/
}}
Agora vamos criar a classe que vai fazer a persistencia com os dados do cliente. É a ClienteDAO.java esta classe extends a classe DAO, para conseguirmos pegar um objeto objeto EntityManager que é responsável pelas inclusões, exclusões e atualizações.
package br.com.dao;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import br.com.bean.Cliente;
public class ClienteDAO extends DAO {
public void salvar(Cliente cliente){
//obtendo o EntityManager
EntityManager em = getEntityManager();
try{
//inicia o processo de transacao
em.getTransaction().begin();
//faz a persistencia
em.persist(cliente);
//manda bala para o BD
em.getTransaction().commit();
}catch (Exception e) {
//se der algo de errado vem parar aqui, onde eh cancelado
em.getTransaction().rollback();
}
}
public List exibir(){
EntityManager em = getEntityManager();
try{
Query q = em.createQuery("select object(c) from Cliente as c");
return q.getResultList();}
finally{
em.close();
}
}
}
Agora criaremos a classe ClienteController quer terá a responsabilidade de direcionar a comunicação do JSF e pegar o foi digitado no form e persistir.
package br.com.controller;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import br.com.bean.Cliente;
import br.com.dao.ClienteDAO;
public class ClienteController {
private Cliente cliente;
private DataModel model;
public ClienteController() {
cliente = new Cliente();
}
public Cliente getCliente() {
return cliente;
}
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
public String salvar(){
ClienteDAO clientedao = new ClienteDAO();
clientedao.salvar(cliente);
return "salvar";
}
public DataModel getTodos(){
ClienteDAO clientedao = new ClienteDAO();
model = new ListDataModel(clientedao.exibir());
return model;
}
}
Vamos configurar o no velho e querido face-config.xml

Criando arquivo persistence.xml
o arquivo que vamos precisar para conectar ao banco de dados, parecido como hibernate.cfg.xml, em respeito de ter a mesma função, conectar ao BD.
Observe o name da persistence-unit pois, eh ele que usamos no nosso DAO.java
Não esqueça que terá que criar um folder META-INF em JavaSource e colocar o persistence.xml neste folder e não coloca-lo dentro do META-INF de WebContent. Alguns programadores acabam confundido e dai recebe as velhas exceções e ficam stressado. Take care easy!
Criando as pages JSF
1.Agora criamos três páginas .jsp com JSF, uma será index que redireciona para cadastro.jsf e a outra é somente uma mensagem dizendo que foi cadastrado com sucesso.
Index.jsp
Coloque o código abaixo na página index.jsp
Testando
Mande executar seu projeto. Clique nele e vá em Run ==> Run as ==> Run on Server
- Cadastre um cliente
E depois verifique se ele está realmente no BD. Veja abaixo meus prints:


Pessoal, vou ficando por aqui, espero que tenham gostado do post, o objetivo era dar o “ABC Prático” de JPA com JEE usando o framework JSF.
Abracos, see you later.!



Lembro-me que você me deu um incentivo enorme quando eu estava estudando JAVA. Hoje sou desenvolvedor, e isso já faz quase dois anos.
Como sempre, respostas esclarecedoras para caminhos sinuosos.
Sucesso!
By the way, ótimo artigo!
opa! odair.
bom saber que ta na aerea e que meu incentivo ti ajudou.
abracos,
Tô muito interessado em aprender Hibernate. Até hoje só utilizei JPA. Vendo essda aplicação, não parece ser tão difícil.
Camilo, vc poderia postar o download novamente dos jars do Hibernate? Baixei 2 vezes e quando tento abrir a pasta aparece como inválida e corrompida. Baixei tbm o arquivo do JSF e tbm tá com o mesmo problema.
É isso aí cara, valeu!
olá anderson,
que estranho, deletei os arquivos e subir novamente, dar uma olhada ai se está ok, aqui ta normal, nao ta corrompido nao.
Um detalhe que reparei antes é que com o winzip dar merda, porem com o winrar nao.
abracos,
Agora sim está tudo certo. Baixei os 2 arquivos e consegui extrair os jars.
Obrigado Camilo!
Camilo, pra rodar esse exemplo no jBoss ou glassfish tem alguma coisa que eu preciso acrescentar?
Estou com o projeto rodando normal no GlassFish
Porem quando eu chamo o servlet que executa um cadastro no banco da o seguinte erro
javax.persistence.PersistenceException: No Persistence provider for EntityManager named cadastro
no caso o meu persistence-unit chama cadastro
Estou a 2 dias tentando rodar um JPA no JBoss e nao consigo, agora passei pro netbeans+glassfish e esta dando o mesmo problema
To ficando loco já iuahiuah
Se puder ajudar ficarei grato
Valeww
opa, bruno
pela leitura do erro, é questao de configuracao do persistence, eu tb ja apanhei com isso no tomcat, mas eu nunca usei os servidores mencionados por vc para testar o exemplo acima. dar uma olhada na documentacao se nao tem algo.
flw. abracos,
Gostaria de saber se não tem nenhuma anotação no ClienteConntroller, tais como, @ManagedBean e o seu scope
Camilo,
ao executar na minha maquina, seguindo o seu tuto deu o seguinte erro:
/index.xhtml @16,150 value=”#{loginController.login.nome}”: Target Unreachable, identifier ‘loginController’ resolved to null.
Será que vc poderia me ajudar?
Obrigado!
Desculpe-me! estou utilizando o netbeans
CamiloLopes muito obrigado pelo post. Ele foi de grande ajuda.
Consegui resolver meu problema, pois o erro estava no local onde é colocado o arquivo de configuração (persistence.xml). No seu tutorial ele é colocado na pasta META-INF, porém acho que isso só vale pro eclipse, pois no netbeans é colocado direto no projeto e o netbeans encaminha para o local correto. Fica ai a dica..
olá, sei que o tutorial é antigo mas se alguem puder me ajudar, nem consigo testar a pagina pois meu jboss 5 não carrega, dá a seguinte mensagem:
Error installing to Start: name=persistence.unit:unitName=#sistemas state=Create
java.lang.RuntimeException: Specification violation [EJB3 JPA 6.2.1.2] – You have not defined a non-jta-data-source for a RESOURCE_LOCAL enabled persistence context named: sistemas
ele nao encontrou o context sistemas, veja as configs do context se estão ok.
Na parte Criando as pages JSF, você fala de 3 páginas, mas só vi uma, como ele redireciona do indes.jsp para cadastro.jsf??? O que tem na index e na cadsrto e a outro, qual é?
opa! emir, obrigado pelo feedback, acabei escrevendo errado, na verdade no inicio eu tinha pensando em tres, mas depois reduzir e nao mudei no texto. Observe que são apenas duas paginas, a index.jsp é que tem o formulario e a segunda, é da mensagem que nao precisa ser apresentada, pq é uma pagina jsp qualquer com uma mensagem de sucesso. E pela image do face-config.xml temos as duas paginas conversando.
abracos,
Camilo sei que o post é antigo mas resolveu o meu problema a única dúvida é porque existe a necessidade de instanciar um Objeto, na classe DAO, EntityManager e passar para ele o getEntityManager da super classe ao invés de se usar diretamente o getEntityManager da super classe !?
Obrigado Abraço
olá Fernando,
Instanciamos o DAO na classe DAO? olhando o post, a há uma instancia no controller para o xxxDAO. Não entendi muito bem a pergunta.
flw.
@camilolopes
Oi Camilo vou exemplificar com código! Porque fazer isso:
public void salvar(Cliente cliente){
EntityManager em = getEntityManager();
try{
em.getTransaction().begin();
em.persist(cliente);
em.getTransaction().commit();
}catch (Exception e) {
em.getTransaction().rollback();
}
Em vez Disso:
public void salvar(Cliente cliente){
try{
getEntityManager().getTransaction().begin();
getEntityManager().persist(cliente);
getEntityManager().getTransaction().commit();
}catch (Exception e) {
getEntityManager().getTransaction().rollback();
}
Era assim que estava a minha implementação e não dava certo de jeito nenhum depois que olhando no seu exemplo você instancia um EntityManager em e passa como valor o getEntityManager() da super . é essa a minha dúvida porque não funciona diretamente!
Abraços
Fernando,
fernando realmente não vai funcionar, para cada getEntityManager() que tu chama, tu tem um objeto novo concorda? então no teu catch e outras invocações tu nao tem o mesmo objeto diretamente, estamos lidando com variaveis de instância e não static, percebeu o pulo do gato? e pq temos que ter o objeto antes ?
abracos,
Entendi sim Camilo!!! ta na minha kra e eu não imaginei isso! Obrigado pela reposta! um abraço e sucesso pra ti!