Persistindo entidades contendo lista de enums utilizando JPA

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (3)  (0)

Veja veste artigo como gerar entidades utilizando JPA e salvar uma lista de Enums utilizando banco de dados PostgreSQL, criando assim tabelas relacionadas entre si sem a necessidade de código SQL.

É notório o crescimento da área de desenvolvimento de software nos últimos 20(vinte) anos. Para acompanhar o crescimento, novas metodologias foram surgindo com o intuito de facilitar o desenvolvimento. Por muito tempo um dos maiores problemas encontrados na codificação estava na necessidade de efetuar transações com banco de dados (a grande maioria das aplicações necessitam interagir com algum banco de dados). Um outro problema comum é a dificuldade de manter código muito acoplado, contendo códigos referentes ao domínio da aplicação misturados com códigos SQL. Na tentativa de resolver esses problemas surgiu o Hibernate, e logo após surgiu o JPA (Java Persistence API), permitindo trabalhar ORM (Modelo Objeto Relacional) de forma transparente, sem a necessidade direta de utilizar código SQL, por meio de anotações (annotations) e fazendo uso de recursos como o refflaction. Nas listagens abaixo serão mostrados exemplos e dicas para trabalhar com os frameworks de persistência.

Para representar o exemplo será desenvolvida uma pequena aplicação que persiste um objeto contendo uma lista de enumeradores utilizando anotações JPA para a persistência e relacionamentos.

CRIANDO O CÓDIGO

Listagem 1: Classe que contém a lista de Enum

package br.com.nooclix.domain;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.SequenceGenerator;

import org.hibernate.annotations.CollectionOfElements;

@Entity(name = "tb_person")
public class Person {
	@Id
	@SequenceGenerator(initialValue = 1, allocationSize = 1, sequenceName = "person_seq", name = "person_seq")
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "person_seq")
	@Column(nullable = false)
	private Integer code;
	private String firstName;
	private String lastName;

	@CollectionOfElements(targetElement = PersonType.class, fetch = FetchType.EAGER)
	@JoinTable(name = "tb_persontype", joinColumns = @JoinColumn(name = "persontypeid"))
	@Column(name = "persontype", nullable = false)
	@Enumerated(EnumType.STRING)
	private List<PersonType> listPersonType;

	//Getters() and Setters()
}

A anotação “@Entity” indica que a classe “Person” ao ser persistida formará uma entidade com o nome “tb_person”. Logo mais abaixo observa-se a anotação “@Id” que define a chave primária da entidade “tb_person”. Mais abaixo a anotação “@SequenceGenerator(...)” contém a sequência que a chave primária deve seguir, no exemplo acima, está indicando que a chave do primeiro valor da entidade “tb_person” será 1, cujo o nome da sequência será “person_seq”, essa “alias” para a sequência será utilizada na anotação seguinte “@GeneratedValue” que contém a estratégia a ser seguida para gerar as chaves primárias da entidade. No exemplo acima foi utilizado a estratégia “AUTO”, ou seja, a chave iniciará com o valor “1” e seguirá a sequência crescente. Os demais atributos da classe “Person” (firstName, lastName) serão acrescentadas à entidade na forma de colunas.

A LISTA DE ENUM'S

Listagem 2: Criando o Enum PersonType

package br.com.nooclix.domain;

public enum PersonType {
	ADMIN, MANAGER, SECRETARY
}

No exemplo de código acima foi determinado um enum com 3(três) enumeradores, os quais serão usados para definir o tipo de “Person” que será salvo. Para os exemplos desse artigo será salvo uma lista de Enumeradores, permitindo assim conter na aplicação mais de um “Person_Type” por pessoa.

Na Listagem 1 as linhas de código 30 a 35 definem como se dará a persistência da lista de Enums, dessa forma, uma nova tabela será gerada permitindo ter uma junção entre as duas classes definido pela anotação “@JoinColumn”.

CRIANDO A CONEXÃO COM O BANCO

Listagem 3: Fábrica de conexões

package br.com.nooclix.persistence;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
//Criando a fábrica de Conexões
public class ConnectionDB {
	private static EntityManagerFactory emf = Persistence
			.createEntityManagerFactory("JPA");
	private static EntityManager em;
	
	public static EntityManager getConnection(){
		return emf.createEntityManager();
	}
}

O código acima é um exemplo de fábrica de conexões, dessa forma não será preciso criar a conexão com o *“persistence.xml” toda vez que for preciso iniciar uma transação com o banco, bastando somente chamar o método “getConnection()” para receber a conexão com o XML.

Listagem 4: Criando o 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="JPA">
      
    <class>br.com.nooclix.domain.Person</class>
    
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
      <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/devdb"/>
      <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
      <property name="hibernate.connection.password" value="123456"/>
      <property name="hibernate.connection.username" value="postgres"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
    </properties>
  </persistence-unit>
</persistence>

O JPA trabalha com o arquivo Persistence.xml para efetuar a conexão com o banco de dados, no exemplo acima têm-se a definição das tags “<class> .. </class>” contendo o caminho das classes que serão persistidas como entidades no banco de dados. Mais abaixo estão definidas as propriedades de conexão que no caso do exemplo desse artigo será utilizado o banco de dados PostgreSQL, contendo a url, nome, usuário e senha do banco. Por meio da tag “<persistence-unit name="JPA">” é possível acessar o arquivo “persistence.xml” na fábrica de conexões (Listagem 3). O arquivo persistence.xml deverá estar obrigatoriamente dentro da pasta META-INF dentro do SRC do projeto.

Estrutura do projeto

Figura 1: Estrutura do projeto

CRIANDO A CLASSE DE PERSISTÊNCIA

Listagem 5: Classe de Persistência

package br.com.nooclix.persistence;

import javax.persistence.EntityManager;
import br.com.nooclix.domain.Person;

public class PersonDB {

	private EntityManager em;

	public PersonDB() {
		em = ConnectionDB.getConnection();
	}

	public void save(Person person) {
		em.getTransaction().begin();
		em.persist(person);
		em.getTransaction().commit();
		em.close();
	}
}

No exemplo de código acima, a classe “PersonDB” recebe por meio do construtor a conexão como banco de dados, mais abaixo o método “save( )” inicia a transação com o banco de dados e persiste o objeto “person” passado por parâmetro pela para o método. Ao final do “commit()” o entityMangager chama o método close(), ou seja, a conexão com o banco de dados precisa ser fechada, dessa forma basta apenas ter uma única instância da classe “PersonDB” para que possa salvar o objeto de Person.

PERSISTINDO O OBJETO

Listagem 6: Executando o código

package br.com.nooclix.execution;

import java.util.ArrayList;
import java.util.List;
import br.com.nooclix.domain.Person;
import br.com.nooclix.domain.PersonType;
import br.com.nooclix.persistence.PersonDB;

public class Execution {

	private Person person;
	private List<PersonType> listPersonType;
	private PersonDB personDB;

	public Execution() {
		person = new Person();
		listPersonType = new ArrayList<PersonType>();
		personDB = new PersonDB();
	}
	
	public void createPerson(){
		person.setFirstName("Yrineu");
		person.setLastName("Rodrigues");
		
		listPersonType.add(PersonType.ADMIN);
		listPersonType.add(PersonType.MANAGER);
		
		person.setListPersonType(listPersonType);
		
		personDB.save(person);
		System.out.println("Salvo com sucesso!");
	}
	
	public static void main(String[] args) {
		Execution ex = new Execution();
		ex.createPerson();
	}
}

No exemplo de código acima a o método createPerson() define os valores do objeto Person, assim como a lista de UserType adicionado ao objeto Person como uma instância de ArrayList. Aao final o código “personDB.save(person);” envia o objeto person para o método save() através do objeto personDB, que por sua vez possui a sequência de chamadas para efetuar a persistência do objeto.

Desta forma serão criadas duas tabelas distintas, porém interligadas.

Tabelas criadas

Figura 2: Tabelas criadas

Valores das tabelas

Figura 3: Valores das tabelas

CONCLUSÃO

Com o uso de frameworks ORM como o JPA/Hibernate é possível inserir, por meio de anotações, criação de tabelas e administrar os valores das mesmas sem a necessidade direta de envolver código SQL, tornando o código mais limpo e menos acoplado. Com o auxílio dos frameworks ORM é possível ainda trabalhar com linguagens Orientada a Objetos como o exemplo do Java, permitindo utilizar todos os seus recursos, como por exemplo o uso de Enumeradores.


 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?