out 24 2010

Spring MVC 3 na Prática com Bean Validation

Category: Spring,Spring MVC 3.0Edson Gonçalves @ 20:56

Olá Pessoal, tudo bom? Como vão vocês?

Este é o terceiro artigo da série Spring MVC 3.0. Se vocês não tiveram um contato inicial com o framework, recomendo ver este artigo primeiro.

Para acompanhar esta terceira parte, recomendo ter criado o projeto do segundo artigo.

Como sempre, dúvidas e críticas são bem vindas.

Alterando o CRUD criado com o Spring MVC

O projeto neste artigo é o mesmo do segundo artigo da série. Entretanto, faremos algumas alterações para que passe a utilizar validações do Bean Validation.

Adicionando as bibliotecas ao projeto utilizando o Maven

Mais uma vez, recorreremos ao Maven para adicionar as bibliotecas que necessitamos. Neste caso, teremos que baixar o Hibernate Validator. Para utilizar o Bean Validation, utilizaremos dois JARs: hibernate-validator-4.0.2.GA.jar e validation-api-1.0.0.GA.jar.

Abram o arquivo pom.xml , encontrado na view Package Explorer para que possamos adicionar as configurações que necessitamos.

Criando a propriedade

Na aba Overview, em Properties, cliquem no botão Create. Na caixa de diálogo Add property, preencham como na Figura 1.

Figura 1 – Criação da property da versão do hibernate validator

Criando a dependência

Com a propriedade definida para informar qual versão desejamos utilizar, no qual o Maven deverá baixar, resta configurar as dependências.

Na aba Dependencies, cliquem no botão Create e preencham conforme a Figura 2 ilustra.

Figura 2 – A dependência do Hibernate Validator

Alterando a entidade Contato

A entidade do artigo, chamada de Contato, será a primeira coisa que iremos modificar no projeto.

Graças a JSR 303, chamada de Bean Validation, podemos anotar as entidades com validações. Com as anotações de Bean Validation na entidade, concentramos a validação em um único local, de forma padronizada, tornando possível portar estas validações para as classes controladoras do Spring MVC.

A Listagem 1 exibe  a entidade Contato modificada. Note as anotações de validação onde colocamos as mensagens de erro embutidas. Mais adiante iremos capturá-las para exibir o problema ao usuário.

Listagem 1. A entidade Contato com anotações Bean Validation.

package br.com.integrator;

import javax.persistence.*;
import javax.validation.constraints.*;

@Entity
@Table(name = "contato")
public class Contato {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id")
	private Long id;
	@NotNull
	@Size(min=5, message="O nome não pode ter menos que 5 caracteres!")
	private String nome;
	@NotNull
	@Pattern(regexp = "^[\\w\\-]+(\\.[\\w\\-]+)*@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$", message="E-mail com formato incorreto.")
	private String email;
	@Pattern(regexp = "\\(?\\b([0-9]{2})\\)?[-. ]?([0-9]{4})[-. ]?([0-9]{4})\\b", message="Telefone em formato incorreto")
	private String telefone; 

     //getters e setters
 }

A infra-estrutura definida pela JSR 303 nos permite descrever as restrições, usando anotações no modelo de classes de persistência, como definir se um campo aceitará uma quantidade mínima de caracteres ou se não aceitará nulo, por exemplo.

Cada anotação é associada a uma validação, verificando se a instância da entidade anotada obedece à regra ou não.

A Tabela 1 apresenta todas as anotações possíveis de serem usadas e suas funcionalidades.

Annotation O que faz?
@AssertFalse Checa se a propriedade anotada é falsa.
@AssertTrue Checa se a propriedade anotada é verdadeira.
@DecimalMax(value=) A propriedade anotada precisa ser um número, cujo valor deve estar menor ou igual ao valor máximo previsto. O parâmetro value é a representação em string do valor máximo aceito de acordo com o formato representado em BigDecimal. Suporta tipos como BigDecimal, BigInteger, String, byte, short, int, long e os respectivos wrappers de tipos primitivos.
@DecimalMin(value=) A propriedade anotada precisa ser um número, cujo valor deve estar maior ou igual ao valor mínimo previsto. O parâmetro value é a representação em string do valor mínimo de acordo com a representação de sequência de BigDecimal. Suporta tipos como BigDecimal, BigInteger, String, byte, short, int, long e os respectivos wrappers de tipos primitivos.
@Digits(integer=, fraction=) Verifica se a propriedade possui a quantidade de dígitos antes e depois do separador de casa decimal. Por exemplo: @Digits(integer=9, fraction=2) significa que espera-se 9 dígitos inteiros e 2 dígitos fracionários. Suporta os tipos: BigDecimal, BigInteger, String, byte, short, int, long e os respectivos wrappers de tipos primitivos.
@Future Checa se a data está no futuro. Suporta os tipos java.util.Date e java.util.Calendar.
@Max(value=) Verifica se o valor é menor ou igual ao valor anotado. Suporta os tipos: BigDecimal, BigInteger, String, byte, short, int, long e os respectivos wrappers de tipos primitivos.
@Min(value=) Verifica se o valor é maior ou igual ao valor anotado. Suporta os tipos: BigDecimal, BigInteger, String, byte, short, int, long e os respectivos wrappers de tipos primitivos.
@NotNull Checa se o valor anotado não é nulo (null). Uma String cujo valor seja vazio (“”) vai passar.
@Null Checa se o valor anotado é nulo (null).
@Past Checa se uma data está no passado. Suporta os tipos java.util.Date e java.util.Calendar.
@Pattern(regex=, flag=) Checa se a propriedade obedece à expressão regular.
@Size(min=, max=) Confere se a quantidade de elementos está entre o mínimo e o máximo, suportando tipos como: Strings, Collections, Maps e arrays.
@Valid Impõe uma validação recursiva aos objetos associados. Digamos que, no bean Post, houvesse a anotação @Valid no atributo comments. Já na classe Comment, temos um atributo de validação anotado. Se um valor transmitido a comments, de Post, não estiver de acordo com a validação existente na classe Comment, de acordo com o atributo anotado, um erro será gerado em tempo de execução. A notação @Valid está sendo usada no PostController para validar os erros existentes em Post ou Comment.

Tabela 1. Anotações e regras para criar restrições (Constraints).

Alterando o controlador

Alteraremos a classe ContatoController, criada no pacote br.com.integrator.web, de acordo com o mostrado na Listagem 2.

Listagem 2. A classe ContatoController alterada.

package br.com.integrator.web;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import br.com.integrator.dao.ContatoDAO;
import br.com.integrator.Contato;

@Controller
@RequestMapping("/contato/**")
public class ContatoController {
@Autowired
private ContatoDAO contatoDao;

@RequestMapping(value = "/contato/{id}", method = RequestMethod.GET)
public String show(@PathVariable("id") Long id, ModelMap modelMap) {
modelMap.addAttribute("contato", contatoDao.find(id));
return "contato/show";
}

@RequestMapping(value = "/contato", method = RequestMethod.GET)
public String list(ModelMap modelMap) {
modelMap.addAttribute("contatos", contatoDao.findAll());
return "contato/list";
}

@RequestMapping(value = "/contato/{id}", method = RequestMethod.DELETE)
public String delete(@PathVariable("id") Long id) {
contatoDao.remove(contatoDao.find(id));
return "redirect:/contato";
}

@RequestMapping(value = "/contato/form", method = RequestMethod.GET)
public String form(ModelMap modelMap) {
modelMap.addAttribute("contato", new Contato());
return "contato/create";
}

@RequestMapping(value = "/contato", method = RequestMethod.POST)
public String create(@Valid Contato contato, BindingResult result) {
if (result.hasErrors())
return "contato/create";

contatoDao.persist(contato);
return "redirect:/contato";
}

@RequestMapping(value = "/contato/{id}/form", method = RequestMethod.GET)
public String updateForm(@PathVariable("id") Long id, ModelMap modelMap) {
modelMap.addAttribute("contato", contatoDao.find(id));
return "contato/update";
}

@RequestMapping(method = RequestMethod.PUT)
public String update(@Valid Contato contato, BindingResult result) {
if (result.hasErrors())
return "contato/update";

contatoDao.merge(contato);
return "redirect:/contato";
}

}

Como visto na Listagem 1, as anotações @Size e @Pattern possuem o atributo message, que capturamos pelo Spring MVC na classe ContatoController (Listagem 2)  – através da classe javax.validation.Valid (anotação @Valid). Assim como a anotação @Controller, as anotações pertencentes a Bean Validation são obtidas graças a adição do elemento <mvc:annotation-driven />. Isto permite que as informações anotadas sejam injetadas onde a validação é necessária na sua aplicação.Caso haja um erro, o método hasErrors(), de org.springframework.validation.BindingResult, retorna true, nos possibilitando conduzir a navegação da página, com seus respectivos erros, inclusive paralisando a ação ao qual se encontra. A utilização de hasErrors() ocorre em ContatoController, nos métodos create() e update() com o seguinte if:

if (result.hasErrors())

//executa uma ação para conduzir a página com os erros ao usuário

As informações recebidas da validação pela classe Controller são transmitidas para o formulário e capturadas. Veja como isto ocorre na descrição da Listagem 3.

Alterando as views

Temos três páginas que representam nosso CRUD feitas. Estas páginas foram criadas dentro do diretório chamado WEB-INF/jsp/contato(fisicamente na ferramenta: src/main/webapp/WEB-INF/jsp/contato). Teremos que alterá-las para permitir que os erros sejam exibidos.

O formulário de cadastro

Abra o arquivo create.jsp e altere como na Listagem 3, adicionando as tags  <form:errors />.

Listagem 3. A página create.jsp.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 <style type="text/css" media="screen">
 @import url("<c:url value="/static/styles/style.css"/>");
 </style>
<title>Cadastrar</title>

</head>
<body>
 <div id="wrap">

 <div id="menu">
 <%@ include file="/menu.jsp" %>
 </div>
 <div id="main">
 <div id="body">
 <c:url var="url" value="/contato" />
 <form:form action="${url}" method="POST" modelAttribute="contato">
 <div>
 <label for="nome">Nome:</label>
 <form:errors path="nome" cssClass="errors"/><br />
 <form:input cssStyle="width:250px" maxlength="30" path="nome" size="30"/>

 </div>
 <br/>
 <div>
 <label for="email">Email:</label>
 <form:errors path="email" cssClass="errors"/><br />
 <form:input cssStyle="width:250px" maxlength="30" path="email" size="30"/>

 </div>
 <br/>
 <div>
 <label for="telefone">Telefone:</label>
 <form:errors path="telefone" cssClass="errors"/><br />
 <form:input cssStyle="width:250px" maxlength="30" path="telefone" size="20"/>
</div>
 <br/><div>
 <input id="criar" type="submit" value="Criar Contato"/>
 </div>
 </form:form>
 </div>
 </div>
 </div>
</body>
</html>
A tag  <form:errors /> foi utilizada na Listagem 3 com dois parâmetros: path e cssClass. No parâmetro path transmitimos o  atributo da classe Contato, validada pelas anotações de Bean Validation, onde receberá a mensagem.

Figura 3 – Processo de validação partindo da anotação no JavaBean Contato

Podemos ter uma idéia de como ficará a página create.jsp depois das alterações visualizando a Figura 4.

Figura 4 – Validação transmitida para a página de JSP

Figura 4 – Validação transmitida para a página de JSP

Alterando a página de atualização de dados

Como feito na página create.jsp, a página update.jsp também receberá as tags <form:errors />. A Listagem 4 exibe a página com as mudanças, na íntegra.

Listagem 4. A página update.jsp.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 <style type="text/css" media="screen">
 @import url("<c:url value="/static/styles/style.css"/>");
 </style>
<title>Atualizar</title>
</head>
<body>
 <div id="wrap">
 <div id="menu">
 <%@ include file="/menu.jsp" %>
 </div>
 <div id="main">
 <div id="body">
 <c:url var="url" value="/contato/${contato.id}" />
 <form:form action="${url}" method="PUT" modelAttribute="contato">
 <div>
 <label for="nome">Nome:</label>
 <form:errors path="nome" cssClass="errors"/><br />
 <form:input cssStyle="width:250px" maxlength="30" path="nome" size="30"/>
 </div>
 <br/>
 <div>
 <label for="email">Email:</label>
 <form:errors path="email" cssClass="errors"/><br />
 <form:input cssStyle="width:250px" maxlength="30" path="email" size="30"/>
 </div>
 <br/>
 <div>
 <label for="telefone">Telefone:</label>
 <form:errors path="telefone" cssClass="errors"/><br />
 <form:input cssStyle="width:250px" maxlength="30" path="telefone" size="20"/>
 </div>
 <br/>
 <div>
 <input id="atualizar" type="submit" value="Atualizar Contato"/>
 </div>
 <form:hidden path="id"/>
 </form:form>
 </div>
 </div>
 </div>
</body>
</html>

O projeto para download

Clique aqui para baixar o projeto e alterá-lo como desejar.

Considerações finais

Com as validações, boa parte dos problemas iniciais de um desenvolvimento usando o Spring MVC foram resolvidos. Mas vejam só: é o começo. Caso haja interesse do leitor em aprender um exemplo mais complexo, a revista JavaMagazine #78 publicou, um artigo meu com o Spring MVC 3 na criação de um blog, do começo ao fim. É um bom início para se desenvolver um projeto mais completo e complexo.
Para os que acompanham o blog, o assunto Spring MVC não para por aqui. Veremos em breve um site completo, feito com o framework, unindo várias características do Spring, de seu framework MVC e a parte de segurança com Spring Security.

Tags: , , , , , , , ,


jun 27 2010

Hibernate com Hibernate Tools

Category: HibernateEdson Gonçalves @ 1:30

Olá Pessoal, tudo bom? Como vão vocês?

O artigo que veremos fala sobre a utilização do Hibernate Tools, um excelente plugin para o Eclipse IDE, oficial da Red Hat, feito para trabalhar com o Hibernate.

Dúvidas e críticas são sempre bem vindas.

Obtendo e instalando o Eclipse IDE

Para desenvolver este exemplo, utilizei a versão do Eclipse IDE 3.6, em um ambiente voltado para o trabalho com Java EE. Para obter o Eclipse IDE, já configurado com o ambiente Web, vá ao endereço http://www.eclipse.org/downloads/ e clique em Eclipse IDE for Java EE Developers. Lembre-se de selecionar o seu sistema operacional.

Ao baixar, descompacte em um local desejado de sua máquina.

O plugin JBoss Tools

Para a versão do Eclipse 3.6, o atual enquanto escrevo este artigo, temos uma versão em desenvolvimento compatível do plugin JBoss Tools. Para obtê-lo, basta baixar a versão de desenvolvimento atual, encontrada em um dos diretórios existentes dentro deste endereço:

http://download.jboss.org/jbosstools/builds/nightly/trunk/

Podemos baixar o Hibernate Tools separadamente ou, como fiz, baixando o JBoss Tools completo. O arquivo que obtive, no momento em que escrevo é o JBossTools-Update-3.2.0.v201006240331N-H369-M1.zip. Com o Eclipse IDE fechado, ao baixar o plugin, descompacte e mova seu conteúdo  sobre o diretório eclipse. Isto fará a instalação do  plugin JBoss Tools. Depois de adicionarmos o plugin, inicie o Eclipse.

Atenção: Por se tratar de uma versão em desenvolvimento, o endereço passado neste artigo poderá sofrer alterações. Portanto, sempre verifique a última versão no endereço http://download.jboss.org/jbosstools/builds/. As versões de desenvolvimento costumam causar instabilidade no Eclipse, portanto, façam seu uso em um ambiente de testes.

O banco de dados

Utilizaremos o banco de dados MySQL, que pode ser adquirido clicando aqui. O banco de dados que utilizaremos para executar o exemplo se chamará hibernatenapratica.

Criando o projeto

Iniciem alterando a perspectiva. No ícone Open Perspective,  cliquem em Other.

Figure 1 – Alterando a Perspectiva

Figura 1 – Alterando a Perspectiva

Selecionem em seguida a Perspectiva Hibernate.

Figure 2 – Seleção da perspectiva Hibernate

Figura 2 – Seleção da perspectiva Hibernate

Na view Package Explorer, cliquem com o direito do mouse e selecionem, no menu de contexto, o item Project.

Figure 3 – Criando um novo projeto pela view Package Explorer através do menu de contexto

Figura 3 – Criando um novo projeto pela view Package Explorer através do menu de contexto

Na caixa de dialogo New Project, selecionem Java>Java Project e cliquem no botão Next.

Figure 4 – Seleção da opção Java Project

Figura 4 – Seleção da opção Java Project

Em New Java Project, digitem o nome do seu projeto. Irei utilizar o nome ProjUtilizandoHibernateTools. Em seguida, cliquem no botão Finish.

Figure 5 – Criação de um projeto Java

Figura 5 – Criação de um projeto Java

Ao surgir a caixa de dialogo Open Associated Perspective, cliquem no botão No. Nós não precisaremos da perspectiva Java apenas para editar o projeto, uma vez que nossa intenção é trabalhar única e exclusivamente com o Hibernate.

Figure 6 – Pergunta automática de alteração de perspectiva feita dependendo do tipo de projeto criado

Figura 6 – Pergunta automática de alteração de perspectiva feita dependendo do tipo de projeto criado

As bibliotecas

Para trabalhar com o Hibernate 3.5, primeiramente será preciso configurar os arquivos no projeto. Para adicionar as bibliotecas que necessitamos ao projeto, cliquem com o direito do mouse sobre o mesmo, na view Package Explorer e, no menu de contexto, selecionem Properties.

Figure 7 – Bibliotecas do projeto

Figura 7 – Bibliotecas do projeto

Vocês podem baixar as bibliotecas do Hibernate clicando aqui. No site, em Download, no menu lateral esquerdo, encontramos as bibliotecas para serem baixadas. A versão, no momento em que escrevo, é a 3.5.1.

Os arquivos que utilizaremos no projeto serão os encontrados em:

  • Hibernate Core

Ao baixar os arquivos, descompacte-os.  Vocês precisarão das seguintes bibliotecas:

  • hibernate3.jar
  • antlr-2.7.6.jar
  • commons-collections-3.1.jar
  • dom4j-1.6.1.jar
  • javassist-3.9.0.GA.jar
  • jta-1.1.jar
  • slf4j-api-1.5.8.jar
  • hibernate-jpa-2.0-api-1.0.0-CR-1.jar

Além destes arquivos, será necessário utilizar as bibliotecas da Simple Logging Facade for Java, SLF4J. Baixem os arquivos com todas as bibliotecas da SLF4J aqui.

Ao descompactar o arquivo, vocês encontrarão a seguinte biblioteca:

  • slf4j-jdk14-1.5.11.jar

Por fim, também necessitaremos da biblioteca JDBC do MySQL, que pode ser obtida clicando aqui. A versão 5.1.10 era, no momento em que este artigo começa a ser escrito, a versão mais atual. Entretanto, é possível que, com o tempo, isto esteja alterado.

Para o projeto, precisaremos do seguinte JAR:

  • mysql-connector-java-5.1.10-bin.jar

Criando o JavaBean Categoria

Com o direito do mouse em seu projeto, vamos até o item New>Other. Na caixa de diálogo New, selecionem Java>Class. Na caixa de diálogo New Java Class, preencham o pacote (br.com.integrator) e o nome da classe, no caso Categoria, em Name. Confirmem a criação no botão Finish.

Figure 8 – Criando a classe Categoria

Figura 8 – Criando a classe Categoria

Alterem a classe Categoria conforme mostrado na Listagem 1.

Listagem 1 – O JavaBean Categoria

package br.com.integrator;

import java.io.Serializable;

import java.lang.Long;

import java.lang.String;

public class Categoria implements Serializable {

private Long id;

private String categoria;

private String descricao;

public Long getId() {

return id;

}

public void setId(Long id) {

this.id = id;

}

public String getCategoria() {

return categoria;

}

public void setCategoria(String categoria) {

this.categoria = categoria;

}

public String getDescricao() {

return descricao;

}

public void setDescricao(String descricao) {

this.descricao = descricao;

}

}

Mapeando a tabela no Hibernate utilizando a forma tradicional

Para mapear a tabela correspondente no banco de dados a classe Categoria, através do Hibernate, temos que criar um XML como forma tradicional de utilização do framework.

Selecionem o pacote e a classe na view Package Explorer e, com o direito do mouse, selecionem o item New>Hibernate XML Mapping file (hbm.xml).

Figure 9 – Seleção do item Hibernate XML Mapping file (hbm.xml) no menu de contexto

Figura 9 – Seleção do item Hibernate XML Mapping file (hbm.xml) no menu de contexto

Na caixa de diálogo New Hibernate XML Mapping Files (hbm.xml), teremos os dois itens selecionados: o pacote e a classe. Caso tenhamos esquecido de selecionar um ou ambos, podemos clicar nos botões que estão na lateral direita (Add Class e Add Package). Continuem no botão Next.

Figure 10 – Criação do arquivo XML de mapeamento do Hibernate

Figura 10 – Criação do arquivo XML de mapeamento do Hibernate

Na etapa seguinte o assistente exibirá o arquivo Categoria.hbm.xml que será criado.  Continuem no botão Next.

Figure 11 – Apresentação do arquivo XML de mapeamento do Hibernate que será criado

Figura 11 – Apresentação do arquivo XML de mapeamento do Hibernate que será criado

A última etapa apresentará o XML do mapeamento criado para o Hibernate, onde a base foi a classe Categoria. Confirmem a criação no botão Finish.

Figure 12 – Arquivo XML do mapeamento que será criado

Figura 12 – Arquivo XML do mapeamento que será criado

Com a finalização do assistente, temos o XML gerado aberto pelo editor do Hibernate Tools. Neste editor podemos mudar as características que desejamos no XML gerado, colocando mais informações em cada propriedade.

Figure 13 – Editor do XML gerado para Hibernate

Figura 13 – Editor do XML gerado para Hibernate

O resultado final será como o mostrado na Listagem 2 a seguir:

Listagem 2 – O arquivo Categoria.hbm.xml

O resultado final será como o mostrado na Listagem 2 a seguir:

Listagem 2 – O arquivo Categoria.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!-- Generated 24/06/2010 05:07:14 by Hibernate Tools 3.3.0.GA -->

<hibernate-mapping>

<class name="br.com.integrator.Categoria" table="categoria">

<id name="id" type="java.lang.Long">

<column name="id"/>

<generator class="increment"/>

</id>

<property generated="never" lazy="false" name="categoria" type="java.lang.String">

<column name="categoria" length="50"/>

</property>

<property generated="never" lazy="false" name="descricao" type="java.lang.String">

<column name="descricao"/>

</property>

</class>

</hibernate-mapping>

Configurando o Hibernate

Com o direito do mouse sobre src, na view Package Explorer, selecionem Hibernate Configuration File (cfg.xml).

Figure 14 – Criação do arquivo hibernate.cfg.xml

Figura 14 – Criação do arquivo hibernate.cfg.xml

Ao surgir o assistente, deixem o nome do arquivo como hibernate.cfg.xml e prossigam no botão Next.

Figure 15 – Assistente de criação do arquivo de configuração do Hibernate

Figura 15 – Assistente de criação do arquivo de configuração do Hibernate

Como vamos utilizar o banco de dados MySQL, preencham os campos como mostrado na Figura 16, alterando de acordo com as configurações que possuem em seu banco de dados.

Por fim, marquem a opção Create a console configuration.  Cliquem no botão Next.

Figure 16 – Configuração do banco de dados no hibernate.cfg.xml

Figura 16 – Configuração do banco de dados no hibernate.cfg.xml

Na última etapa, temos as configurações do console do Hibernate. Este console, quando configurado e funcional, nos permite  executar queries HQL ou trabalhar com Criteria.

Figure 17 – Configuração do console Hibernate

Figura 17 – Configuração do console Hibernate

Cliquem na aba Mappings e removam o caminho configurado automaticamente para o arquivo Categoria.hbm.xml. Este caminho não será preciso porque iremos configurá-lo diretamente no arquivo hibernate.cfg.xml, ao qual o console fará uso também. Confirmem o assistente clicando no botão Finish.

Figure 18 – A abra Mappings da configuração do console

Figura 18 – A abra Mappings da configuração do console

Na finalização do assistente, abrirá o editor do arquivo de configuração do Hibernate.

Figure 19 – O editor do arquivo de configuração do Hibernate

Figura 19 – O editor do arquivo de configuração do Hibernate

Como muitas das informações que desejávamos, foram colocadas no assistente, resta apenas adicionar o caminho para Categoria.hbm.xml. Para fazermos isso, basta ir no botão Add e digitar o caminho em Resource.

Figura 20 – Detalhe de Mappings com o arquivo Categoria.hbm.xml adicionado

Figura 20 – Detalhe de Mappings com o arquivo Categoria.hbm.xml adicionado

Para executarmos o exemplo, tornando possível a criação da tabela no banco de dados pelo Hibernate, assim como sua recriação a cada nova execução, expandindo Session Factory>Properties>Hibernate, em Hibernate Configuration 3.0 XML Editor, alterem Hbm2ddl Auto para create-drop.

Neste mesmo local, onde temos as propriedades, podemos alterar para true em Show SQL, Use SQL Comments e Format SQL.

Figura 21 – Adicionando novas propriedades ao arquivo hibernate.cfg.xml

Figura 21 – Adicionando novas propriedades ao arquivo hibernate.cfg.xml

O resultado final das configurações, no arquivo hibernate.cfg.xml, são mostrados na Listagem 3 a seguir:

Listagem 3 – O arquivo hibernate.cfg.xml

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

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>

<property name="hibernate.connection.password">integrator</property>

<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernatenapratica</property>

<property name="hibernate.connection.username">edson</property>

<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

<property name="hibernate.show_sql">true</property>

<property name="hibernate.use_sql_comments">true</property>

<property name="hibernate.format_sql">true</property>

<property name="hibernate.hbm2ddl.auto">create-drop</property>

<mapping resource="br/com/integrator/Categoria.hbm.xml"/>

</session-factory>

</hibernate-configuration>

Algumas características do Hibernate Tools

Como Hibernate está devidamente configurado, podemos já utilizar algumas de suas características.

Figura 22 – A view Hibernate Configurations após as configurações do arquivo hibernate.cfg.xml

Figura 22 – A view Hibernate Configurations após as configurações do arquivo hibernate.cfg.xml

Na view Hibernate Configurations, cliquem com o direito do mouse e selecionem Mapping Diagram.

Figura 23 – Acessando Mapping Diagram no menu de contexto

Figura 23 – Acessando Mapping Diagram no menu de contexto

O Hibernate Tools possui uma ferramenta visual que nos permite visualizar as classes mapeadas em suas tabelas correspondentes encontradas no banco de dados.  Isto não significa que a tabela já exista no banco de dados. Trata-se da forma como a configuração “enxerga” a tabela em que irá trabalhar no banco de dados.

Figura 24 – Visualizando a classe Categoria mapeada para a tabela correspondente no banco de dados

Figura 24 – Visualizando a classe Categoria mapeada para a tabela correspondente no banco de dados

Colocando o Hibernate para trabalhar

Iremos criar duas pequenas classes que juntas irão gerar a tabela e seus  dados dela no banco de dados.

Com o direito do mouse sobre src, na view Package Explorer, selecionem o item New>Other.  Na caixa de dialogo New, selecionem Java>Class.

Coloquem o pacote br.com.integrator.util e deem o nome da classe de HIbernateUtil, confirmando o assistente, em seguida, no botão Finish.

Figura 25 – Criação da classe HibernateUtil

Figura 25 – Criação da classe HibernateUtil

O conteúdo da classe HibernateUtil será similar ao mostrado na Listagem 4 a seguir:

Listagem 4 – A classe HibernateUtil

package br.com.integrator.util;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

public class HibernateUtil {

private  static final SessionFactory sessionFactory;

static {

try {

sessionFactory = new Configuration().configure()

.buildSessionFactory();

} catch (Throwable ex) {

System.err.println("Initial SessionFactory creation failed." + ex);

throw new ExceptionInInitializerError(ex);

}

}

public static SessionFactory getSessionFactory() {

return sessionFactory;

}

}

A segunda classe que criaremos irá se chamar Main e será colocada no pacote br.com.integrator.

Figura 26 – Criação da classe Main

Figura 26 – Criação da classe Main

O conteúdo da classe Main é mostrado na Listagem 5 a seguir:

Listagem 5 – A classe Main

package br.com.integrator;

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.Transaction;

import br.com.integrator.util.HibernateUtil;

public class Main {

public static void main(String[] args) {

Session session = HibernateUtil.getSessionFactory().openSession();

Transaction transaction = null;

try {

transaction = session.beginTransaction();

Categoria categoria1 = new Categoria();

categoria1.setCategoria("Informática");

categoria1.setDescricao("Produtos de Informática");

session.save(categoria1);

Categoria categoria2 = new Categoria();

categoria2.setCategoria("Eletrodomésticos");

categoria2.setDescricao("Eletrodomésticos em Geral");

session.save(categoria2);

Categoria categoria3 = new Categoria();

categoria3.setCategoria("Livraria");

categoria3.setDescricao("Livros para todos os gostos");

session.save(categoria3);

transaction.commit();

} catch (HibernateException e) {

transaction.rollback();

e.printStackTrace();

} finally {

session.close();

}

}

}

Executem a classe Main para que o Hibernate crie a tabela categoria e adicionem o conteúdo. Graças as configurações criadas no arquivo hibernate.cfg.xml, temos a saída na view Console como mostra a Figura 27.

Figura 27 – A saída no console criada na execução do exemplo

Figura 27 – A saída no console criada na execução do exemplo

O Editor HQL e Criteria

Para acessar o editor HQL do Hibernate Tools, cliquem com o direito do mouse em qualquer parte da view Hibernate Configurations e selecionem, no menu de contexto, o item HQL Editor.

Figura 28 – Chamando o editor HQL pelo menu de contexto na view Hibernate Configurations

Figura 28 – Chamando o editor HQL pelo menu de contexto na view Hibernate Configurations

No editor HQL, se digitarmos uma query HQL, veremos também na view Hibernate Dynamic SQL Preview a instrução SQL gerada automaticamente pelo Hibernate.

Figura 29 – Editor HQL em ação e a view Hibernate Dynamic SQL Preview exibindo a SQL gerada

Figura 29 – Editor HQL em ação e a view Hibernate Dynamic SQL Preview exibindo a SQL gerada

Ao mandarmos executar a query HQL, em Run HQL, vemos o resultado surgir na view Hibernate Query Result. Quando selecionamos este resultado, vemos os dados na view  Properties.

Figura 30 – Resultados encontrados na query HQL executada nas views Hibernate Query Result e Properties

Figura 30 – Resultados encontrados na query HQL executada nas views Hibernate Query Result e Properties

A parte de Criteria também é bem fácil de se criar. Cliquem com o direito do mouse sobre Session Factory>br.com.integrator.Categoria e selecionem, no menu de contexto, o item Hibernate Criteria Editor.

Figura 31 – Abrindo o editor de criteria

Figura 31 – Abrindo o editor de criteria

Ao surgir o editor de Criteria, basta completarmos a instrução que desejamos executar. Em seguida,  clicamos no botão Run criteria (o mesmo botão que no editor HQL se chama Run HQL).

Figura 32 – Criação do Hibernate Criteria no editor e seu resultado apos clicar em Run criteria

Figura 32 – Criação do Hibernate Criteria no editor e seu resultado apos clicar em Run criteria

Engenharia Reversa

A engenharia reversa no Hibernate Tools também é de fácil utilização.

Para trabalhar com a engenharia reversa, é necessário termos o arquivo de configuração do Hibernate, configurado para conectar-se ao banco de dados pré-existente.

A engenharia reversa está preparada para gerar as classes, os arquivos .hbm.xml ou então anotações. Também é possível termos anotações JPA, relacionamentos e outros.

Para criar a engenharia reversa em nosso exemplo, cliquem com o direito do mouse na view Package Explorer. No menu de contexto selecionem New>Hibernate Reverse Engineering File (reveng.xml).

Figura 33 – Opção Hibernate Reverse Engineering File (reveng.xml) do menu de contexto

Figura 33 – Opção Hibernate Reverse Engineering File (reveng.xml) do menu de contexto

Na caixa de diálogo, selecionem o diretório src e mantenham o nome do arquivo padrão solicitado. Cliquem no botão Next.

Figura 34 – Iniciando a criação do arquivo de configuração de engenharia reversa

Figura 34 – Iniciando a criação do arquivo de configuração de engenharia reversa

Na etapa seguinte, selecionem a configuração do console previamente criada em Console configuration. Cliquem no botão Refresh e selecionem no banco de dados a(s) tabela(s) que desejam trabalhar na engenharia reversa para utilizar com o Hibernate e confirmem no botão Include. Concluam o assistente no botão Finish.

Figura 35 – Seleção da tabela categoria para a engenharia reversa

Figura 35 – Seleção da tabela categoria para a engenharia reversa

O assistente irá gerar o arquivo de engenharia reversa. Agora iremos configurá-lo para que, na geração dos arquivos baseados na(s) tabela(s) do banco de dados, a conversão seja exatamente como desejamos.

Comecem indo na aba Type Mappings e cliquem no botão Refresh.

Figura 36 – Exibindo o banco de dados através do botão Refresh

Figura 36 – Exibindo o banco de dados através do botão Refresh

Na caixa de diálogo Select a console configuration, selecionem o console criado e confirmem no  botão OK.

Figura 37 – Seleção da configuração de console

Figura 37 – Seleção da configuração de console

Retornando para o editor, temos o banco de dados, tabela(s) e campo(s). Para que ocorra a engenharia reversa de forma correta, devemos Add cada um deles, editando o Hibernate Type, Length e também Not-Null.

Vejam  como é  mostrado na Figura 38.

Figura 38 – Configurando os tipos JDBC e  Hibernate da tabela para executar a engenharia reversa

Figura 38 – Configurando os tipos JDBC e Hibernate da tabela para executar a engenharia reversa

O resultado do arquivo configurado, visto na aba Source, em formato XML, é como o mostrado na Listagem 6.

Listagem 6 – O arquivo hibernate.revenge.xml

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

<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >

<hibernate-reverse-engineering>

<type-mapping>

<sql-type jdbc-type="BIGINT" hibernate-type="long"

not-null="true">

</sql-type>

<sql-type jdbc-type="VARCHAR" hibernate-type="string" length="50"

not-null="false">

</sql-type>

<sql-type jdbc-type="VARCHAR" hibernate-type="string"

not-null="false">

</sql-type>

</type-mapping>

<table-filter match-catalog="hibernatenapratica" match-name="categoria"/>

</hibernate-reverse-engineering>

Retornando a view Package Explorer, vamos configurar um console Hibernate para executar o arquivo de engenharia reversa criado. Cliquem com o direito do mouse sobre o arquivo hibernate.revenge.xml e selecionem, no menu de contexto, o item Hibernate Console Configuration.

Atenção: Esta etapa não é realmente necessária quando já existe um console configurado. Entretanto, na primeira vez que configuramos um, o acesso não havia sido feito desta maneira.
Figura 39 – Seleção do item Hibernate Console Configuration no menu de contexto

Figura 39 – Seleção do item Hibernate Console Configuration no menu de contexto

Na caixa de dialogo, alterem o campo Name para ProjUtilizandoHibernateToolsAnnotations. Verifiquem se Configuration file está corretamente apresentando o arquivo hibernate.cfg.xml.

Figura 40 – Diálogo de criação da configuração do console Hibernate para a engenharia reversa

Figura 40 – Diálogo de criação da configuração do console Hibernate para a engenharia reversa

Através do botão Run As , clicando no pequeno triângulo que aponta para baixo,  encontramos um menu onde temos o item Hibernate Code Generation Configurations.

Figura 41 – Menu Run As com a opção Hibernate Code Generation Configurations

Figura 41 – Menu Run As com a opção Hibernate Code Generation Configurations

Na caixa de diálogo Hibernate Code Generation Configurations, em Hibernate Code Generation, cliquem com o direito do mouse e selecionem, no menu de contexto, o item New.

Figura 42 – Acionando o menu de contexto em Hibernate Code Generation

Figura 42 – Acionando o menu de contexto em Hibernate Code Generation

Na lateral direita, tenham ProjUtilizandoHibernateToolsAnnotations em Console configuration selecionado. Em Output directory, cliquem em Browse e selecionem o local onde será(ão) gerada(s) a(s) classe(s), neste caso.

Digitem o pacote em Package e, em reveng.xml, cliquem em Setup.

Figura 43 – Configuração inicial da aba Main em Hibernate Code Generation Configurations

Figura 43 – Configuração inicial da aba Main em Hibernate Code Generation Configurations

Ao surgir o diálogo Setup reverse engineering, cliquem em Use existing.

Figura 44 – Selecionando o botão Use existing

Figura 44 – Selecionando o botão Use existing

Selecionem o item hibernate.reveng.xml e confirmem no botão OK.

Figura 45 – Seleção do arquivo hibernate.reveng.xml

Figura 45 – Seleção do arquivo hibernate.reveng.xml

Retornando ao diálogo Hibernate Code Generation Configurations, ainda na aba Main, temos todas as informações que desejamos preenchidas, como na Figura 46.

Figura 46 – Aba Main do diálogo Hibernate Code Generation Configurations preenchido

Figura 46 – Aba Main do diálogo Hibernate Code Generation Configurations preenchido

Agora iremos na aba Exporters, ao qual iremos marcar Generate EJB 3 annotations e Domain code (.java).

Figura 47 – Opções de exportação da caixa de diálogo Hibernate Code Generation Configurations

Figura 47 – Opções de exportação da caixa de diálogo Hibernate Code Generation Configurations

Por fim, vamos clicar no botão Run para executar a engenharia reversa.

Figura 48 – Executando a engenharia reversa através do botão Run

Figura 48 – Executando a engenharia reversa através do botão Run

Neste último exemplo, o resultado é a classe Categoria sendo criada com anotações.

Considerações finais

Como vocês puderam ver, o Hibernate Tools é uma ferramenta bem interessante para aqueles que trabalham com o framework Hibernate. Seja para criar suas configurações através dos assistentes, para executar as queries HQL ou Criteria em seus editores, vale a pena  instalar e conhecer este plugin do Eclipse IDE.

Até o próximo artigo pessoALL.

Tags: , , , ,


mar 09 2010

JPA 2.0 na Prática com Hibernate 3.5

Category: JPA 2.0Edson Gonçalves @ 21:07

Olá, tudo bom? Como vão vocês?
Embora meus artigos sobre JPA 2.0 tenham uma sequencia, este em especial está sendo postado para sanar as dúvidas de vários leitores que me pediram para ensiná-los a usar o Hibernate 3.5, como ORM provider, para trabalhar com JPA 2.0.
Dúvidas e críticas são bem vindas.

Preparação do ambiente de trabalho

Se você olhou o artigo JPA na Prática – Parte 1, será similar no banco de dados e  na ferramenta porém, haverá uma modificação na biblioteca JPA.

A  biblioteca JPA

O Hibernate é um ORM como o EclipseLink, muito utilizado no desenvolvimento Web com Java,  cujo a versão 3.5 possui suporte a Java Persistence API 2.0.  Você pode baixá-la clicando aqui. Clique em Download, no menu lateral esquerdo.

A versão, no momento em que escrevo, é a 3.5.0-CR-2 (ainda em desenvolvimento).

Os arquivos que terá de baixar serão:

  • Hibernate Core
  • Hibernate JPAModelGen

Ao baixar os arquivos, descompacte-os.  Você precisará das seguintes bibliotecas:

  • hibernate3.jar
  • antlr-2.7.6.jar
  • commons-collections-3.1.jar
  • dom4j-1.6.1.jar
  • javassist-3.9.0.GA.jar
  • jta-1.1.jar
  • slf4j-api-1.5.8.jar
  • hibernate-jpa-2.0-api-1.0.0-CR-1.jar

Além destes arquivos, será necessário utilizar as bibliotecas da Simple Logging Facade for Java, SLF4J. Baixe o arquivo com todas as bibliotecas da SLF4J aqui.

Descompacte o arquivo após baixá-lo.  Você precisará das seguintes bibliotecas:

  • slf4j-jdk14-1.5.11.jar
  • slf4j-log4j12-1.5.11.jar

O Projeto

O projeto para este pequeno tutorial é o mesmo do criado no artigo JPA na Prática – Parte 1, portanto não será explicado novamente como fazê-lo.

As bibliotecas no projeto

Podemos tanto criar uma biblioteca de usuário, contendo todas elas ou, simplesmente, adicionar todas ao seu projeto.

Figura 1 – Bibliotecas do Hibernate 3.5 e SLF4J adicionadas ao projeto

Figura 1 – Bibliotecas do Hibernate 3.5 e SLF4J adicionadas ao projeto

Configurando o arquivo persistence.xml

Similar ao mostrado na JPA 2.0 na Prática – Parte 2, no arquivo persistence.xml, altere-o conforme a Listagem 1 abaixo:
Listagem 1 – O arquivo persistence.xml

<?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="JpaNaPratica" transaction-type="RESOURCE_LOCAL">

<class>br.com.integrator.Categoria</class>

<properties>

<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpapratica"></property>

<property name="javax.persistence.jdbc.user" value="edson"></property>

<property name="javax.persistence.jdbc.password" value="integrator"></property>

<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"></property>

<property name="hibernate.show_sql" value="true" />

<property name="hibernate.format_sql" value="true" />

<property name="hibernate.hbm2ddl.auto" value="create"/>

</properties>

</persistence-unit>

</persistence>

Infelizmente, nem todas as propriedades de persistence.xml são padronizadas, conforme já dito no artigo JPA na Prática – Parte 2. Para exibir a saída das instruções SQL geradas, assim como outras informações, as seguintes propriedades foram  adicionadas ao arquivo persistence.xml:

<property name="hibernate.show_sql" value="true" />

<property name="hibernate.format_sql" value="true" />

Para criar a tabela, utilizamos a seguinte adição:

<property name=”hibernate.hbm2ddl.auto” value=”create”/>

Testando o Projeto

Similar ao mostrado na JPA 2.0 na Prática – Parte 2, execute a classe com o método main() e veja os resultados refletidos no banco de dados.

Hibernate ou EclipseLink?

Muitos me perguntam isso, querendo saber qual é o melhor. O ideal, como sempre, é conhecer ambos e tirar as suas próprias conclusões. Em JPA 2.0, ao menos por enquanto, no que foi mostrado, não há diferença.

Abraço a todos e até o próximo artigo.

Tags: , , , , ,


fev 03 2010

JPA 2.0 na Prática – Parte 2

Category: JPA 2.0Edson Gonçalves @ 14:13

Olá, tudo bom? Como vão vocês?

Este artigo é o segundo de uma série ao qual vou ensiná-los a trabalhar com a Java Persistence API 2.0 (JPA 2.0).  Dúvidas e críticas são bem vindas.

Os primeiros passos na JPA

Com o ambiente configurado, agora podemos  configurar a JPA e dar nossos primeiros passos em sua execução, entendendo como funciona e o que podemos fazer.

Esta parte do artigo está baseada na configuração, criação da entidade e manipulação básica do banco de dados.

Caso você tenha chegado agora, a Parte 1 do artigo ensina como configurar o seu ambiente de desenvolvimento e testes.

Configurando o arquivo persistence.xml

Ao criar o projeto, também foram criados um diretório e arquivo. Note o arquivo chamado persistence.xml,  encontrado no diretório META-INF, dentro de src.

Abra o arquivo persistence.xml e verá que o Eclipse IDE possui um editor do arquivo.

Sua estrutura básica é como mostrada na Listagem 1 abaixo:
Listagem 1 – O arquivo persistence.xml

<?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>

</persistence-unit>

</persistence>

Ela pode ser visualizada no Editor do Eclipse, em Source.

Configurando a conexão com o banco de dados

No editor do Eclipse, vá na aba Connection, em persistence.xml.

Adicionando as configurações de conexão ao persistence.xml

Adicionando as configurações de conexão ao persistence.xml

Comece alterando para Resource Local em Transaction type.

Esta pequena alteração adiciona o atributo transaction-type com o valor “RESOURCE_LOCAL” em <persistence-unit/> no arquivo persistence.xml.  O atributo transaction-type está definindo que a unidade de persistência terá sua integridade gerida  através da API local (RESOURCE_LOCAL), que é o nosso caso, onde não haverá um servidor de aplicativos Java EE por enquanto envolvido para transações JTA (Java Transaction API).

Mais abaixo, em EclipseLink Connection Pool, clique em Populate from Connection.

Adicionando os parâmetros de conexão no arquivo persistence.xml

Adicionando os parâmetros de conexão no arquivo persistence.xml

Ao abrir a caixa de diálogo Connection Selection, selecione a conexão do MySQL que fez na criação do projeto e confirme.

Conexão do MySQL feita na criação do Projeto

Conexão do MySQL feita na criação do Projeto

Ao retornar ao arquivo persistence.xml, os dados pertencentes ao banco de dados estarão preenchidos.

Configurações para a conexão ao banco de dados

Configurações para a conexão ao banco de dados

Esta mudança da conexão alterou o arquivo persistence.xml da seguinte forma:

<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpapratica"/>
<property name="javax.persistence.jdbc.user" value="edson"/>
<property name="javax.persistence.jdbc.password" value="integrator"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
</properties>

Na JPA 2.0, algumas propriedades foram padronizadas. As propriedades que foram adicionadas ao arquivo persistence.xml são padrões para se conectar ao banco de dados. Veja o que significa cada uma delas:

  • javax.persistence.jdbc.driver — o nome do driver da classe totalmente qualificado
  • javax.persistence.jdbc.url — URL específico do driver
  • javax.persistence.jdbc.user — usuário do banco de dados para a conexão
  • javax.persistence.jdbc.password — senha do banco de dados para a conexão

Vá agora até a aba Logging e, em Logging level, altere para All. Isso tornará visível todas as operações que fizemos, utilizando a JPA, no Console do Eclipse.

Alterando o nível de logging para ALL

Alterando o nível de logging para ALL

Infelizmente, nem todas as propriedades de persistence.xml foram padronizadas. A seguinte propriedade foi adicionada ao arquivo:

<property name=“eclipselink.logging.level” value=“ALL”/>

Ainda em persistence.xml, vá até a aba Schema Generation.  Nesta aba temos DDL generation type. Como não fizemos nenhuma tabela no banco de dados, teremos que criá-la ao executar nossa primeira entidade.

Temos três opções:

  • None – não ocorre nada;
  • Create Tables – cria as tabelas baseando-se nas informações contidas nas entidades;
  • Drop and Create Tables – exclui e cria as tabelas através das informações contidas nas entidades;

Para o nosso trabalho inicial, vamos manter um ciclo de criação e exclusão,  selecionando Drop and Create Tables.

Gerando tabelas através da configuração de persistence.xml

Gerando tabelas através da configuração de persistence.xml

As últimas alterações incluíram a seguinte propriedade:

<property name=“eclipselink.ddl-generation” value=“drop-and-create-tables”/>

Com estas mudanças, temos tudo pronto para trabalhar com a JPA.

Criando sua primeira entidade

Clique com o direito do mouse sobre src, do seu projeto JPA. Selecione no menu de contexto New>Entity.

Criando uma entidade JPA no Eclipse IDE

Criando uma entidade JPA no Eclipse IDE

Na caixa de diálogo New JPA Entity, preencha Java package e Class name, no caso: br.com.integrator e Categoria, respectivamente. Mantenha Entity em Inheritance e clique no botão Next.

Criando a classe/entidade Categoria

Criando a classe/entidade Categoria

Na segunda etapa, definimos o nome da tabela que será utilizada pela entidade Categoria e seus respectivos campos/colunas.

Segunda etapa da criação da Entidade JPA

Segunda etapa da criação da Entidade JPA

O Eclipse IDE, através do seu assistente, irá manter o nome da tabela como padrão existente ao nome da entidade. Desmarque Use default e altere para categorias em Table name.

Esta pequena alteração informa que a entidade Categoria está ligada a tabela categorias do banco de dados.

Alteração do nome da tabela para o banco de dados

Alteração do nome da tabela para o banco de dados

Abaixo você vai encontrar Entity fields. Clique em Add para adicionar as os atributos que existirão na entidade Categoria e seus respectivos tipos.

Detalhe da adição de atributos na entidade Categoria

O diálogo Entity Fields possui Type para colocar o tipo ( que também é acessível com Ctrl+Space) e o nome.

Adicionando um atributo

Adicionando um atributo

Os atributos da entidade são mostrados na Figura abaixo:

Atributos da entidade Categoria

Atributos da entidade Categoria

Veja que foi marcado id como key. Isso fará com que este atributo/campo seja a chave primária.

Diálogo completamente preenchido

Diálogo completamente preenchido

Com tudo preenchido, clique no botão Finish para gerar a classe Categoria com as devidas anotações que a fará uma Entidade da JPA.

A classe/entidade Categoria possui a estrutura como mostrado na Listagem 2 após sua geração:

Listagem 2 – A entidade Categoria

package br.com.integrator;
import java.io.Serializable;
import java.lang.Long;
import java.lang.String;
import javax.persistence.*;
@Entity
@Table(name="categorias")
public class Categoria implements Serializable {
@Id
private Long id;
private String categoria;
private String descricao;
//getters e setters omitidos
}

As entidades, na especificação da JPA, são POJOS (Plain Old Java Objects ), onde podemos alocar com o operador new, assim como faríamos com qualquer outro objeto Java simples. As instâncias de uma classe do tipo entidade não se tornam persistentes até estarem associadas a um EntityManager.

No arquivo persistence.xml, verá a classe adicionada em General>Managed Classes.

Detalhe de Managed Classes em persistence.xml

Detalhe de Managed Classes em persistence.xml

No XML de persistence.xml, haverá a seguinte linha adicionada:

<class>br.com.integrator.Categoria</class>

O elemento <class/> lista explicitamente as classes que são consideradas entidades no persistence.xml.

Para finalizar, vá até a classe Categoria. Na view JPA Structure, clique em id. Marque Primary key generation na view JPA Details e selecione Identity em Strategy. Isso informa a entidade que o campo da chave primária é auto-incrementado e, portanto, gerado pela tabela do banco de dados.

Definindo a estratégia de auto-incremento no campo id da entidade

Definindo a estratégia de auto-incremento no campo id da entidade

Na classe veremos a seguinte anotação: @GeneratedValue(strategy = IDENTITY), onde IDENTITY é de javax.persistence.GenerationType.

Testando a JPA

Antes de explicar qualquer coisa, vamos fazer um teste para saber se está tudo corretamente funcionando, simplesmente chamando a persistence-unit através de uma simples classe Java com um método main().

Crie uma classe no próprio projeto JPA , chamando-a de TesteDaJPA. Coloque em um pacote diferente do qual vem usando e marque public static void main(String[] args). Confirme a criação da classe no botão Finish.

Criação da classe de testes

Criação da classe de testes

Altere a classe TesteDaJPA conforme a Listagem 3:

Listagem 3 – A classe TesteDaJPA

package br.com.integrator.teste;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class TesteDaJPA {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("JpaNaPratica");
EntityManager em = emf.createEntityManager();
em.close();
emf.close();
 }
}

Execute a classe através do menu Run>Run As>Java Application.

Graças à configuração que fizemos de logging no arquivo persistence.xml (em <property name=“eclipselink.logging.level” value=“ALL”/>) , possuímos uma saída bem detalhada do que ocorreu ao gerar este simples teste.

Assim que iniciada a classe, veremos a saída contendo a conexão ao banco de dados:

[EL Finest]: 2010-02-03 04:33:36.007--Thread(Thread[main,5,main])--DBPlatform: org.eclipse.persistence.platform.database.MySQLPlatform, RegularExpression: (?i)mysql.*.
[EL Fine]: 2010-02-03 04:33:36.007--Thread(Thread[main,5,main])--Detected Vendor platform: org.eclipse.persistence.platform.database.MySQLPlatform
[EL Config]: 2010-02-03 04:33:36.022--ServerSession(11025290)--Connection(29232906)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
 platform=>MySQLPlatform
 user name=> "edson"
 datasource URL=> "jdbc:mysql://localhost:3306/jpapratica"
))
[EL Config]: 2010-02-03 04:33:36.022--ServerSession(11025290)--Connection(9616314)--Thread(Thread[main,5,main])--Connected: jdbc:mysql://localhost:3306/jpapratica
 User: edson@localhost
 Database: MySQL Version: 5.1.43-community
 Driver: MySQL-AB JDBC Driver Version: mysql-connector-java-5.1.10 ( Revision: ${svn.Revision} )
[EL Config]: 2010-02-03 04:33:36.022--ServerSession(11025290)--Connection(23255990)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
 platform=>MySQLPlatform
 user name=> "edson"
 datasource URL=> "jdbc:mysql://localhost:3306/jpapratica"
))
[EL Config]: 2010-02-03 04:33:36.038--ServerSession(11025290)--Connection(16496587)--Thread(Thread[main,5,main])--Connected: jdbc:mysql://localhost:3306/jpapratica
 User: edson@localhost
 Database: MySQL Version: 5.1.43-community
 Driver: MySQL-AB JDBC Driver Version: mysql-connector-java-5.1.10 ( Revision: ${svn.Revision} )
[EL Finest]: 2010-02-03 04:33:36.069--ServerSession(11025290)--Thread(Thread[main,5,main])--sequencing connected, state is NoPreallocation_State

Entre a saída, veremos que, devido a configuração no persistence.xml (em <property name=“eclipselink.ddl-generation” value=“drop-and-create-tables”/>) , primeiro houve uma tentativa de fazer um drop table na tabela categorias. Como não existia tal tabela, veremos este erro:

Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown table 'categorias'
Error Code: 1051
Call: DROP TABLE categorias
Query: DataModifyQuery(sql="DROP TABLE categorias")
Em seguida veremos a criação da tabela na seguinte linha:
[EL Finest]: 2010-02-03 04:33:36.163--ServerSession(11025290)--Thread(Thread[main,5,main])--Execute query DataModifyQuery(sql="CREATE TABLE categorias (ID BIGINT AUTO_INCREMENT NOT NULL, CATEGORIA VARCHAR(255), DESCRICAO VARCHAR(255), PRIMARY KEY (ID))")

Por fim, será possível ver que ocorre a desconexão ao banco de dados.

A tabela gerada no banco de dados

Ao entrar no banco de dados, veremos que a simples classe anotada se transformou em uma tabela. Evidentemente que o POJO, sem a devida configuração no arquivo persistence.xml, antes da sua chamada pela classe executora que fizemos de teste, não teria esse poder.

A tabela gerada no MySQL

A tabela gerada no MySQL

Graças a anotação @Table, pudemos dar o nome da tabela que seria gerada, através do atributo name.

Atributos convertidos em colunas

Observe que cada atributo da classe se transformou em uma coluna na tabela. A coluna chave, tida por ID, foi gerada graças à anotação @Id. Além disso, o MySQL considerou esta coluna como auto-incrementada, ou seja, ela possui um modificador que incrementa em um toda vez que uma informação é inserida na tabela. Isso é automático e gerenciado pelo banco de dados. A anotação @GeneratedValue foi a responsável pela geração do auto-increment do MySQL.

Os tipos de cada coluna são gerados pelo similar em Java. Logo, Long se transformou em bigint e String em varchar. Cada tipo de coluna, na tabela do banco de dados, possui também um tamanho definido na sua criação. Como não especificamos isso na classe Categoria, através de anotações, a tabela foi gerada utilizando o tamanho máximo obtido pelo tipo, isso no banco de dados em questão. Logo, Long se transformou em bigint(20) e String em varchar(255).

Na próxima parte

Na Parte 2 da série JPA 2.0 na Prática finalmente fizemos a configuração da JPA, possibilitando a conexão ao banco de dados. Também foi possível gerar uma tabela baseada em uma entidade da JPA através de um pequeno teste de utilização.

Em JPA 2.0 na Prática – Parte 3, começaremos a compreender a Entidade em questão, suas várias anotações e implicações no banco de dados.

As entidades, na especificação da JPA, são POJOS (Plain Old Java Objects ), onde podemos alocar com o operador new, assim como faríamos com qualquer outro objeto Java simples. As instâncias de uma classe do tipo entidade não se tornam persistentes até estarem associadas a um EntityManager.

No arquivo persistence.xml, verá a classe adicionada em General>Managed Classes.

Tags: , , , , ,


Próxima página »