Tutorial Hibernate 3 com JPA 2

Olá pessoal, tudo bem?

Hoje vamos falar sobre um importante framework para tratar os dados do seu modelo: “Hibernate”.
Para fazer o Hibernate mais poderoso nesse “HelloWord” faremos com que ele trabalhe em conjunto com a API do JPA.
Trabalhando junto com o JPA não precisaremos mapear cada classe que for criada, mas deixaremos que o “EntityManager” tome conta do assunto.

Para começar precisamos fazer alguns downloads.

O primeiro será do MySQL.
O link para download é: http://dev.mysql.com/downloads/mysql/.

Imagem do Site MySQL

Basta instalar com padrão Microsoft: “Next, Next, Finish”. Apenas fique atento para a senha que você irá colocar no banco de dados. Ela será utilizada em nosso arquivo XML de configuração.

Precisamos criar um schema e para isso vamos abrir o “MySQL Command Line Client” que vai aparecer no seu menu do MySQL instalado.

Hibernate JPA

Digite o usuário e a senha colocados na hora da instalação. Digite o comando abaixo:

create database hello;

Aperte “Enter” e pronto.

Hibernate JPA

O próximo download será das bibliotecas do Hibernate 3 (aqui você poderá encontrar outras versões).

Vamos fazer o download do conector do MySQL (aqui você poderá escolher outro servidor para download).

O conector é o responsável por “ligar/intermediar” o Hibernate ao banco de dados. Estaremos utilizando o MySQL, mas caso queira fazer o teste com outro banco de dados basta fazer o download o conector do banco desejado.

API do Hibernate: Dentro do arquivo baixado encontraremos as bibliotecas do Hibernate 3, JPA 2 e algumas outras que são obrigatórias para o funcionamento do framework.
Após criar um projeto java do tipo “Java Project”, vamos criar criar um folder chamado “lib” para colocar as bibliotecas necessárias para funcionamento de nossa aplicação.

Iremos utilizar:

  • hibernate-distribution-3.6.0.Final/hibernate3.jar
  • hibernate-distribution-3.6.0.Final/lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar
  • hibernate-distribution-3.6.0.Final/lib/required/* ” (Todos os arquivos)

Atenção: Os arquivos da pasta “required” são obrigatórios. Copie todos os arquivos (inclusive os arquivos da pasta "required") listados acima para a pasta lib.

Conector MySQL: Assim como fizemos com o as bibliotecas do Hibernate faremos com o conector. Dentro do arquivo ZIP, que você baixou, existe uma biblioteca chamada “mysql-connector-java-5.1.14-bin.jar” basta copiá-la para dentro da pasta lib.

Ao final teremos os seguintes arquivos dentro da pasta lib:

Hibernate JPA

Precisamos criar um arquivo de configuração chamado “persistence.xml”. Esse arquivo é padrão do Hibernate e a pasta onde o arquivo deve estar obrigatoriamente é “src/META-INF”. Veja como nosso arquivo ficará (se você está lendo este tutorial mas já procurou em outras fontes e seu código não funciona, pode ser a declaração do “persistence.xml”. Alguns tutoriais apresentam um “header” inválido para ele):

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.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_2_0.xsd">
    
    <persistence-unit name="Hello" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        
        <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/Hello"/>
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

Vou explicar qual a utilidade de cada linha do arquivo descrito acima:

  • <persistence-unit name=”Hello” transaction-type=”RESOURCE_LOCAL”>” Duas configurações importantes são definidas aqui. “unit name” define para a aplicação a configuração que será utilizada. No mesmo arquivo podemos ter vários tipos diferentes. “transaction-type” define como será nosso tipo de transação, em nosso caso “local”. Caso fosse uma aplicação web não iríamos precisar controlar a transação, o containner (JBoss, GlassFish, …) faria esse trabalho.
  • <provider>org.hibernate.ejb.HibernatePersistence</provider>” indica qual será o provider de nossa aplicação. Em nosso caso, o Hibernate.
  • hibernate.show_sql” habilita a exibição do SQL gerado no console.
  • javax.persistence.jdbc.driver” qual será o agente de conexão com o banco de dados que estaremos utilizando, vamos utilizar o MySQL.
  • javax.persistence.jdbc.url” a URL de nosso banco de dados juntamente com o schema de nosso banco de dados.
  • javax.persistence.jdbc.user” e “javax.persistence.jdbc.password” usuário e senha do banco de dados. Esses atributos foram definidos na instalação do MySQL. Utilizei os valores “root” e “root”.
  • hibernate.dialect” o dialeto que o Hibernate irá utilizar. Vamos discutir mais sobre essa opção em posts futuros, por exemplo, como gerar script do banco de dados de modo automático.
  • hibernate.hbm2ddl.auto” com essa opção ativada, o Hibernate atualizará suas tabelas quando necessário. Por exemplo, se a tabela não existir ela irá criar (“CREATE TABLE…”), se você adicionou uma coluna (“ALTER TABLE…”). Para testes vou deixar ativo, mas não aconselho a deixar essa opção ativada quando se trata de uma aplicação real. Não é uma boa escolha deixar essa alteração acontecer de modo automático em uma aplicação real. Deixe-a ativa apenas para teste local ou estudo.

Falta um último passo antes de começar a codificar. Adicionar as bibliotecas que baixamos ao build path do projeto. Precisamos fazer isso para que nossa aplicação as reconheça.

Botão direito do mouse em cima do projeto > “Properties > Java Build Path”.

Clique na aba Libraries e depois em “Add JARs”.

E por último, selecione os arquivos que estão dentro da pasta lib e click em Ok.

Finalmente vamos criar nossa classe “User” no package “com”. Com essa classe iremos realizar um CRUD (Create, Read, Update, Delete) básico.

package com;

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="user")
public class User {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    
    @Column
    private String name;
    
    @Column
    private String password;
    
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof User){
            User user = (User) obj;
            return user.getId() == this.getId();
        }
        
        return false;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Alguns detalhes sobre o código acima:

  • “@Entity” indica para nosso Provider que essa classe deve ser persistida em nosso banco de dados.
  • “@Table” define o nome da tabela a ser utilizada no banco de dados. Caso não tenha definida nenhum nome utilizando a chave “name”, o padrão será o nome exato da classe.
  • “@Id” mostra qual o nome do id de nossa classe.
  • “GeneratedValue” é a chave utilizada para que o valor do nosso id seja gerada por algum tipo de padrão. Em nosso exemplo estamos utilizando o tipo “AUTO”.
  • “@Column” define o atributo como uma coluna. Poderíamos também definir um nome pelo atributo “name”, como foi feito com a chave da tabela (“@Table”).

Por último precisamos de uma classe que irá criar a conexão com o banco de dados e gerenciar nossa classe de modelo User. Vamos criar uma classe chamada Main no package “com”.

package com;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Hello");
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            
            User user = new User();
            user.setName("abc123");
            user.setPassword("abc123");
            
            em.persist(user);
            
            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        finally{
            emf.close();
        }
        
        System.out.println("It is over");
    }
}

Alguns detalhes sobre o código acima:

  • Como estamos utilizando uma aplicação local precisamos controlar a conexão de modo manual. Por isso utilizamos o comando para abrir transação (“begin”), realizar commit e fechar a conexão (“close”).
  • Para informar que nosso objeto precisa ser salvo, utilizamos o comando “em.persist(user);”.

Basta executar nosso código e ver que a mensagem de execução com sucesso. Para confirmar, basta executar uma consulta em nosso banco de dados conforme imagens abaixo:

Hibernate JPA

Hibernate JPA

Note que, na imagem do console acima, o próprio Hibernate gerou o comando insert.

A grande vantagem do Hibernate é que ele traz um registro do banco de dados já como uma classe. E para fazer isso basta executar o código abaixo. Utilizamos o método “find” para localizar um registro do banco de dados pelo seu Id:

package com;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Hello");
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            
            User user = em.find(User.class, 1);
            
            System.out.println(user.getName());
            
            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        finally{
            emf.close();
        }
        
        System.out.println("It is over");
    }
}

E para realizar uma alteração? Vamos alterar o nome do nosso usuário, veja como é simples.

package com;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Hello");
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            
            User user = em.find(User.class, 1);
            
            user.setName("123abc");            
            
            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        finally{
            emf.close();
        }
        
        System.out.println("It is over");
    }
}

Hibernate JPA

E para remover basta utilizar o comando remove implementado pela classe EntityManager. Basta realizar novamente o comando find e depois “em.remove(user)“.

Bem pessoal, o post foi longo, mas espero que possa ser útil.

Em um próximo post poderemos ver questões de relacionamentos e como fazer com que o Hibernate + Ant gere o script do banco de dados.

Qualquer dúvida ou comentário basta postar.
Até mais! o_

Review: João Luiz Silva Silvestre

16 thoughts on “Tutorial Hibernate 3 com JPA 2

  1. Olá amigo, tudo bem?!
    Será que pode me ajudar?

    Estou tentando de todas as formas fazer esse seu exemplo.. e nao consigo… acontece o seguinte erro.

    org.hibernate.cfg.Configuration.reset(Configuration.java:299)
    at org.hibernate.cfg.Configuration.(Configuration.java:265)
    at org.hibernate.cfg.Configuration.(Configuration.java:269)
    at org.hibernate.ejb.Ejb3Configuration.(Ejb3Configuration.java:151)
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:63)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47)
    at model.Main.main(Main.java:13)
    Caused by: java.lang.NullPointerException
    at org.hibernate.internal.util.ConfigHelper.getResourceAsStream(ConfigHelper.java:170)
    at org.hibernate.cfg.Environment.(Environment.java:221)

    Sabe o que pode ser?
    Ele fala sobre esse org.hibernate.cfg.Configuration. porem, nao encontro em lugar algum como configurar isso.

    Pelo que sei, JPA + HIBERNATE só precisa do arquivo persistence.xml
    Veja como esta o meu arquivo.

    model.Pessoa

    Ja tentei usar o arquivo persistence.xml igual ao seu, mas nao funciona.
    Varios outros exemplo na internet sobre JPA + HIbernate acontecem esse mesmo erro. Talvez seja algum atualizacao que ocorreu. Ja tentei usar as suas libs e outras mais atualizadas, e mesma coisa.

    Se poder ajudar agradeço

    • Maicon, boa tarde.

      Olhando assim não sei te falar, desculpe.

      Siga o passo a passo desse tutorial, baixe as mesmas bibliotecas que eu ei que irá funcionar.

      Até mais.

  2. No eclipse existem muitas opções de novo projeto, eu instalei o Jboss Tools e apareceram ainda mais opções, minha duvida é, posso criar um simples, Java Project (pelo visto ele usa a JRE SE e não EE) e depois incluir os arquivos e recursos para EJB, e Web, JSF essas coisas no mesmo projeto? Quando eu crio um projeto especifico no Eclipse ele apenas facilita o trabalho criando a estrutura de diretório e copiando as principais libs certo? posso mudar isso a qualquer momento?

    • Rodolfo, bom dia.

      Eu geralmente crio o projeto JSF como Web e o EJB como Java Project. Nunca tive problemas com isso não. [=

      Obrigado pela visita.

  3. esta acontecendo o seguinte erro:

    SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”.
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
    Exception in thread “main” java.lang.IllegalStateException: Transaction not active
    at org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:104)
    at com.Main.main(Main.java:27)

    • Paulo, boa tarde.

      Verifique se a transação foi iniciada.

      Se não, veja se aparece algum outro erro.

      Até mais.

  4. Existe algum modo de fazer meu container controlar o EM, para eu não ter que me preocupar com poll, criar e fechar em

    • Cristiano, boa tarde.

      Existe sim. Você poderia utilizar JBoss, Glassfish como servidores, ou então, frameworks como o Spring.

      Obrigado pela visita.

  5. Oi Hebert,

    muito bacana o post, vi que vc criou uma classe main para executar o
    EntityManagerFactory emf = Persistence.createEntityManagerFactory(“Hello”);
    EntityManager em = emf.createEntityManager();

    Se eu fizesse uma classe JPAUtils, colocasse esse código acima para ler a unidade de persistencia, quem deveria chamar esse JPAUtils para gerar as tabelas no banco, considerando que trabalho com JPA (Hibernate) + JSF + Tomcat 7 ?

    Obrigado.

    • Thiago, boa noite.

      Você poderia fazer um interceptor ou listener, algum tipo de component baseado na tecnologia que você está utilizando que pode ser chamado quando o servidor fosse iniciado.

      Obrigado pela visita.

    • Joaquim, boa noite.

      Na hora de excluir você deve primeiro buscar a entidade do banco de dados e depois remover.

      Faça algo como:
      Carro carro = entityManager.getReference(Carro.class, 1);
      entityManager.remove(carro);
      entityManager.getTransaction().commit();

      Obrigado pela visita

  6. Cara pelo menos tenta fazer primeiro testes desses posts que está gerando, pois se for seguir a risca quase nenhum funciona conforme descrito.

    • Felipe, bom dia.

      Você é o primeiro a falar isso de qualquer post meu.

      Qual foi o seu problema?

      Obrigado pela visita.

  7. Hebert utilizei a propriedade abaixo para gerar as tabelas automaticamente de um estudo que estou fazendo, mas não esta funcionando.

    Pode me dar uma dica !!!

    Abaixo arquivo persistence.xml.

    org.eclipse.persistence.jpa.PersistenceProvider
    br.com.mycompletejpawebapp.entity.Log
    br.com.mycompletejpawebapp.entity.Product
    br.com.mycompletejpawebapp.entity.Sell
    br.com.mycompletejpawebapp.entity.User
    false

Leave a Comment