JPA standalone (fora do servidor, container ou da IDE)

Neste post vou mostrar o exemplo mais básico de utilização de JPA, sem a utilização de qualquer servidor (de aplicação ou não) e sem os pulos do gato de uma IDE como o Eclipse.

Acredito que para qualquer iniciante no estudo de uma tecnologia é sempre bom ter contato com a tecnologia em seu formato mais cru, a fim de entender os cernes da questão e evitar as armadilhas da abstração no completo entendimento.

Para este post pegue apenas seu Java SE e vamos brincar.

A JPA

A Java Persistence API (JPA) é uma especificação Java (JSR 317 em sua versão 2.0) responsável por, nas próprias palavras da Sun/Oracle:

“Gerenciamento da persistência e mapeamento objeto/relacional com Java EE e Java SE.”

Construindo a aplicação de exemplo

Na JPA as entidades são apenas classes POJOS comuns gerenciadas por um serviço chamado EntityManager, responsável por controlar o sincronismo dos dados com o banco de dados.

A seguir a classe Pessoa.java:

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Pessoa {

	@Id
	private int id;

	private String nome;

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

	public int getId() {
		return this.id;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getNome() {
		return this.nome;
	}
}

Em uma aplicação com JPA devemos utilizar o arquivo persistence.xml para mapear grupos de entidades JPA (como Pessoa.java) a uma unidade de persistência. Uma unidade de persistência nada mais é que um agrupamento lógico de entidades mapeadas a um banco de dados.

A seguir nosso exemplo simples de um persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="Persistence1">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/meubd" />
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
        <property name="hibernate.connection.password" value="" />
        <property name="hibernate.connection.username" value="root" />
    </properties>
</persistence-unit>
</persistence>

No exemplo acima definimos algumas coisas interessantes:

1. Nossa unidade de persistência se chamará “Persistence1” (podemos ter mais de uma unidade de persistência numa mesma aplicação).

2. Definimos que a implementação da JPA utilizada será o Hibernate.

3. Definimos algumas propriedades necessárias ao Hibernate para a comunicação com o banco de dados, como o tipo de SGBD (Mysql, no exemplo), a url de conexão (que informa host, porta e nome do banco de dados), além de um usuário e senha de acesso.

Por último, nossa aplicação precisa de um classe para testarmos se este tal de JPA realmente funciona e se conseguimos realmente sincronizar os dados da entidade Pessoa com o banco de dados:

import javax.persistence.*;

public class StandAlone {

	public static void main(String[] args) {
		EntityManagerFactory emf = Persistence.createEntityManagerFactory("Persistence1");
		EntityManager em = emf.createEntityManager();

		Pessoa p = new Pessoa();
		p.setNome("Asdrúbal");

		EntityTransaction et = em.getTransaction();

		et.begin();

		em.persist(p);

		et.commit();
	}
}

Algumas considerações importantes sobre a classe simples de teste acima:

1. Para o gerenciamento da sincronização com o banco de dados precisamos do objetinho maroto “EntityManager”, o qual obtemos com uma fábrica de EntityManager conseguida através da classe Persistence.

2. Criamos uma instância de nossa entidade Pessoa normalmente, atribuindo um valor para o nome.

3. Todo o sincronismo com o banco de dados é feito através de contextos de persistência transacionais, para tal temos que iniciar uma transação através do EntityManager.

4. Para informar ao EntityManager que queremos adicionar os dados desta entidade ao banco de dados, devemos utilizar o método persist().

5. Por fim, para efetivar a operação, devemos comitar a transação.

OBS: Este exemplo prático apenas apresenta conceitos básicos da JPA, favor consultar um guia ou a especificação oficial para detalhes da API.

Agora que temos nossa aplicação criada, precisamos criar o banco de dados mapeado em nosso persistence.xml.

Criando o banco de dados

Para este exemplo utilizaremos o MySQL, por ser um banco de dados free e um dos padrões de mercado. Se você não possui um servidor MySQL instalado em sua máquina, faça o download.

Após o MySQL devidamente instalado e inicializado, vamos criar nosso banco de dados e a tabela correspondente à nossa entidade Pessoa, executando os seguintes comandos SQL:

CREATE DATABASE meubd;
USE meubd;
CREATE TABLE Pessoa (id int(10), nome varchar(50));

Agora que temos nossa aplicação construída e nossa infra-estrutura criada, só nos falta compilar e executar!

Compilando

Crie um diretório “bin” dentro da pasta onde você armazenou as classes Java e o persistence.xml. Este será o nosso diretório de execução.

Para início de conversa, para compilar nosso código, precisamos além de, obviamente, ter a JDK instalada em nosso computador, também das bibliotecas de implementação da JPA fornecidas pelo Hibernate. Basta fazer o download no site do Hibernate.

Também precisaremos do driver do MySQL, que funciona como um conector entre o JPA e o banco de dados específico. Este conector pode ser baixado no site do fabricante.

Após feito o download, crie uma pasta “lib” dentro do diretório “bin” recém-criado, onde armazenaremos todas as dependências. Copie todos os JARs presentes dentro das pastas lib/required e lib/jpa do Hibernate para esta pasta “lib” de nossa aplicação. Copie também o conector do MySQL.

Compilamos nossas classes com o seguinte comando:

javac -cp "bin/lib/hibernate-jpa-2.0-api-1.0.1.Final.jar" -d bin *.java

O comando acima informa ao compilador Java para compilar todos os arquivos com extensão java e inserir as classes compiladas no diretório “bin” (parâmetro “d”). Além disso, para que saiba como compilar os códigos relacionados à API da JPA, devemos adicionar ao classpath o JAR com as implementações da JPA baixadas do site do Hibernate (parâmetro “cp”). Atenção: substitua no comando a biblioteca do hibernate pela sua versão.

Após este passo, devemos ter as classes compiladas e, antes de executar a classe de teste, devemos finalizar copiando o arquivo persistence.xml para dentro da pasta bin/META-INF. *Este arquivo deve ficar dentro de uma pasta META-INF no classpath da aplicação.

Executando

Utilize o seguinte comando para executar a classe teste:

cd bin
[enter]
java -cp "lib/*;." StandAlone

Com o comando acima, informamos que queremos executar a classe StandAlone inserindo todos os JARs dentro da pasta lib e as classes do diretório bin no classpath da aplicação (onde ela consegue enxergá-las).

Após a execução, um novo registro de pessoa deve ter sido inserido no banco de dados e o log deve ser algo assim:

16/08/2012 01:23:54 org.hibernate.annotations.common.Version <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
16/08/2012 01:23:54 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.1.6.Final}
16/08/2012 01:23:54 org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
16/08/2012 01:23:54 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
16/08/2012 01:23:54 org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
16/08/2012 01:23:54 org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20
16/08/2012 01:23:54 org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000006: Autocommit mode: true
16/08/2012 01:23:54 org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/meubd]
16/08/2012 01:23:54 org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000046: Connection properties: {user=root, password=****, autocommit=true, release_mode=auto}
16/08/2012 01:23:55 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
16/08/2012 01:23:55 org.hibernate.engine.transaction.internal.TransactionFactory
Initiator initiateService
INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal
.jdbc.JdbcTransactionFactory
16/08/2012 01:23:55 org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory

Com isso encerramos nosso exemplo. Até a próxima.

Referências

Especificação “JPA 2.0 (JSR #317 – JavaTM Persistence 2.0)”
Livro “Enterprise JavaBeans 3.0” – Bill Burke & Richard Monson-Haefel
Apostila “Curso FJ-31 (Java EE Avançado e Web Services” – Caelum

 

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>