Archive

Archive for the ‘JPA’ Category

 Powered by Max Banner Ads 

OneToMany com Hibernate JPA

May 1st, 2011 4 comments

Opa! Pessoal,

O post de hoje vou apresentar como criar o relacionamento oneToMany / ManyToOne de forma simples. Quem ai nunca passou por algum tipo de problema ao criar esse tipo de relacionamento? Algo como de não criar a FK e só persistir uma das tabelas etc. Estarei apenas focando em como definir os relacionamentos à nível de código e para isso teremos code apenas para o objetivo do post. Quero evitar posts grandes sem necessidade.

lets go…

Required

- Vou assumir que se você está lendo este post é pq já está brincando com o Hibernate e agora precisa fazer um relacionamento entre as suas tabelas, então parte de configuração do framework, ou explicação dos métodos serão omitidos, qualquer dúvida consulte outros posts no blog na categoria Hibernate, e veja como ter o ambiente funcionando.

- A classe DAO nos códigos é que possui o trabalho de persistência, ela não é requirida para o post, pois vc uma vez que podemos obter o begin(), save(), commit() etc do hibernate por diversas formas.

- Hibernate 3.x

- MySql 5

OneToMany

O relacionamento OneToMany é bem usado, e são poucas vezes que de fato não precisamos te-lo, então é aquele lance se não precisou até hoje, espere mais um pouco que essa necessidade vai nascer. Vamos tirar a vantagem dos annotations e veremos @OneToMany e @ManyToOne ao invés dos .hbm, Como exemplo há vários cenários para exemplificar este tipo de relacionamento, tais como: um time de futebol tem vários jogadores, uma infra-estrutura tem vários servidores, porém um jogador só pode jogar em um time(ou não depende da regra de negócio, aqui está o pulo do gato), e um servidor está em uma infra-estrutura.

Note: Há casos que um jogador joga mais de um time, daí temos o ManyToMany.

Para criar esse tipo de relacionamento temos que identificar o ponto chave do relacionamento entre as classes, como por exemplo, para um Time de futebol, temos que saber que há uma lista com os jogadores que pertencem ao clube, uma vez que um team não tem apenas 1 jogador este pode ter de 0..X(mesmo sem jogadores ele pode ser considerado um team de futebol, mas está sem grana e demitiu todos os jogadores). Eu costumo chamar de HAS-AN List something (tem uma lista de alguma coisa).

A seguir temos a class bean que representa o Team (por boas práticas elas não deveria extends DAO, porém fiz aqui para ser mais pratico e fazer sentindo com as invocações do Hibernate que temos no code).

@Entity

public class Team extends DAO{

@Id

@GeneratedValue

private long id;

@Column

private String nameTeam;

private List<Player> players;

Usando @OneToMany

Agora vamos usar o relacionamento apropriado para a classe,a seguir temos o code atualizado:

@Entity

public class Team {

private String nameTeam;

@OneToMany(mappedBy = “team”, targetEntity = Player.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)

private List<Player> players;

mappedBy = informamos o nome da variavel de instância que vai indicar a quem aquele One pertence, ou seja, um jogador ele deve dizer a qual time este está associado.

TargetEntity = informa qual a entidade estamos associando

FetchType.Lazy = foi escolhido por performace

cascade = ALL para permitir alterações em todos os relacionamentos.

Pronto, já dizemos que um TEAM tem muitos jogadores (uma lista )

Usando @ManyToOne

Na classe que representa o MANY(do manyToOne), que nesse caso é a Player, teremos uma anotação @ManyToOne na variavel de instancia que representa o TEAM.

@Entity

public class Player {

@Id

@GeneratedValue

private long id;

private String nickName;

@ManyToOne

@JoinColumn(name=“team_id”)

private Team team;

@JoinColumn = informamos o nome que terá o FK.

Ao rodar o código main na class Team:

public static void main(String args[]) {

Team team1 = new Team();

team1.setNameTeam(“São Paulo”);

Player jogador1 = new Player();

Player jogador2 = new Player();

jogador1.setNickName(“Rogerio Ceni”);

jogador2.setNickName(“Luiz Fabiano”);

// has-an associando o jogador ao team

jogador1.setTeam(team1);

jogador2.setTeam(team1);

begin();

getSession().save(team1);

getSession().save(player1);

getSession().save(player2);

commit();

}

Talvez você tenha pensado que apenas 1 (um) save() seria necessario, mas não é, pois precisamos colocar a instancia dos players com a session, para que este se torne um objeto persistente do contrario, o Hibernate não o poder de persistir no banco. O resultado:

O team do São Paulo tem dois jogadores, observe que o ID do team aparece na table do Player(team_id) assim sabemos a qual time este pertence.

Erros comuns durante a programação:

  • esquecer de associar as instâncias envolvidas no relacionamento, se eu esquecer de dizer a qual team um jogador pertence, não teremos o resultado esperado e o resultado na sua tabela será NULL, caso seja permitido esse valor na coluna.

  • Não salvar as instâncias que serão persistidas é outro fato comum, quem está fazendo pela primeira acredita que dar um save apenas na classe que representar One (team), é o sufuciente e por alguma mágina o Hibernate vai saber quais outras instancias devem ser persistidas, ai vem a pergunta, como o Hibernate vai saber, se você não transformou o “objeto java” criando em um objeto-persistent?

Espero que tenham gostado do post, vou ficando por aqui.

Abracos see you next post!!! :)

JPA com Hibernate + JSF + MySQL

August 23rd, 2010 20 comments

olá Pessoal,

Neste post, vou mostrar como usar JPA para seus projetos JEE tendo como provider o nosso Hibernate e para o view usaremos JSF. Alguns adoram o TopLink da Oracle, eu tive serios problemas com ele na parte de config, e cansei de me stressar com coisas operacionais e mantenho meu querido Hibernate como provider.

Aplicação será bem simples, apenas cadastrar um cliente. Limitamos os dados do form, pois o objetivo é mostrar como criar um ambiente para development tendo JPA nos seus projetos. Já mostrei em outros posts, como criar um projeto JPA para Java Básico. Então, recebi alguns emails e para JEE?

Lets go…

Oportunidade Java:

Estamos disponibilizando uma vaga para desenvolvedor Senior Web
. Carga horária será de 8 horas diárias. Os requisitos técnicos para esta contratação são:

- Conhecimentos nas APIs: JSF, Hibernate;
- Conhecimentos nos patterns MVC, DAO, VO;
- Desejável conhecimento em RichFaces

Regime De trabalho é CLT. O salário será de 4.000 mais benefícios. 

Interessados enviar currículos para atendimento@leiria.com.br

Obrigado.

Posts relacionados

Requisitos

Iniciando

Na imagem a seguir você tem toda a estrutura do projeto, observe que já criei as bibliotecas para o projeto e estas foram adicionadas. Se não quiser adicioanr as bibliotecas ao projeto, copie os .jars para a pasta lib e pronto. Lembre-se que ao adicionar uma biblioteca ao projeto, o stupid Eclipse não copia os .jars para a pasta lib. (ao contrário do netbeans :) ).

Não esqueça também de criar um schema e uma table no MySQL, aqui chamaremos de sistemas e clientes respectivamente.

estrutura

1.monte uma estrutura conforme a imagem acima.

Para os arquivos em .jsp e .xml tive que colocar no formato imagem. Infelizmente o plugin para code no wordpress, esse é estressante quando envolve xml, html etc. preciso ficar dando um espaco para cada par de < > senão ele bagunça todo código ou até converte para qualquer outra coisa. Já gastei 1 hora somente para tentar configurar isso. Em função disso, coloquei no formato img o code bem organizado. O lado bom, é que você poderá praticar sem dar ctrl + c e ctrl + v. :)

E como sempre boa parte das explanações estão dentro do code no formato de comentário, lado-lado para facilar a compreensão.

Desenvolvimento

2.primeiro passo é criar o bean e fazer as devidas anotações, então veja abaixo o nosso cliente bean como está:

package br.com.bean;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="cliente")//caso o nome da tabela seja diferente informe aqui
public class Cliente {
	@Column(name="nome")
	private String nome;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	//anotação acima indica que o campo será gerado automaticamente pelo BD
	@Column(name="id")
	private int id;
	@Column(name="sobrenome")
	private String sobrenome;
	@Column(name="cidade")
	private String cidade; 

	public Cliente() {
		// TODO Auto-generated constructor stub
	}

	public String getNome() {
		return nome;
	}

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

	public int getId() {
		return id;
	}

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

	public String getSobrenome() {
		return sobrenome;
	}

	public void setSobrenome(String sobrenome) {
		this.sobrenome = sobrenome;
	}

	public String getCidade() {
		return cidade;
	}

	public void setCidade(String cidade) {
		this.cidade = cidade;
	}

}

Agora vamos partir para criar o nosso DAO, que nele teremos a nossa fábrica de conexão. E poderiamos ter métodos genéricos como salvar, deletar, atualizar etc.Mas, não vamos implementar todos.

package br.com.dao;

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

public class DAO {

	private EntityManagerFactory emf; 

	/* se vc já está acostumado com Hibernate
	 * a ideia é a mesma do método de fabrica que
	 * criamos para os Session que vem do SessionFactory
	 * Aqui temos apenas nomeclatura diferente, pense assim.
	 */
	public EntityManager getEntityManager(){

		//responsavel pela persistencia
		return emf.createEntityManager();
	}
	public DAO() {
		//chamo ele de reprodutor da instância
		emf = Persistence.createEntityManagerFactory("sistemas");

		/* o nome passado vem do arquivo persistence.xml que contém as configs
		 * para conexão com o BD.
		 */
	}}

Agora vamos criar a classe que vai fazer a persistencia com os dados do cliente. É a ClienteDAO.java esta classe extends a classe DAO, para conseguirmos pegar um objeto objeto EntityManager que é responsável pelas inclusões, exclusões e atualizações.

package br.com.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import br.com.bean.Cliente;

public class ClienteDAO extends DAO {

	public void salvar(Cliente cliente){
		//obtendo o EntityManager
		EntityManager em = getEntityManager();
		try{
			//inicia o processo de transacao
			em.getTransaction().begin();
			//faz a persistencia
			em.persist(cliente);
			//manda bala para o BD
			em.getTransaction().commit();
		}catch (Exception e) {
			//se der algo de errado vem parar aqui, onde eh cancelado
			em.getTransaction().rollback();
		}
	}

	public List exibir(){
		EntityManager em = getEntityManager();
		try{
			Query q = em.createQuery("select object(c) from Cliente as c");

		return q.getResultList();}
		finally{
			em.close();
		}
	}
}

Agora criaremos a classe ClienteController quer terá a responsabilidade de direcionar a comunicação do JSF e pegar o foi digitado no form e persistir.

package br.com.controller;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import br.com.bean.Cliente;
import br.com.dao.ClienteDAO;
public class ClienteController {
	private Cliente cliente;
	private DataModel model;
	public ClienteController() {
		cliente = new Cliente();
	}

	public Cliente getCliente() {
		return cliente;
	}
	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}

	public String salvar(){
		ClienteDAO clientedao = new ClienteDAO();
			clientedao.salvar(cliente);
		return "salvar";
	}
	public DataModel getTodos(){
			ClienteDAO clientedao = new ClienteDAO();
			model = new ListDataModel(clientedao.exibir());
		return model;
	}
}

Vamos configurar o no velho e querido face-config.xml

faceconfigdesign

Criando arquivo persistence.xml

o arquivo que vamos precisar para conectar ao banco de dados, parecido como hibernate.cfg.xml, em respeito de ter a mesma função, conectar ao BD.

Observe o name da persistence-unit pois, eh ele que usamos no nosso DAO.java

persistence

Não esqueça que terá que criar um folder META-INF em JavaSource e colocar o persistence.xml neste folder e não coloca-lo dentro do META-INF de WebContent. Alguns programadores acabam confundido e dai recebe as velhas exceções e ficam stressado. Take care easy!

Criando as pages JSF

1.Agora criamos três páginas .jsp com JSF, uma será index que redireciona para cadastro.jsf e a outra é somente uma mensagem dizendo que foi cadastrado com sucesso.

Index.jsp

Coloque o código abaixo na página index.jsp

cadastrojsf

Testando

Mande executar seu projeto. Clique nele e vá em Run ==> Run as ==> Run on Server

  • Cadastre um cliente

E depois verifique se ele está realmente no BD. Veja abaixo meus prints:

testecad

testesucessocad

testemysqlcad

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

Abracos, see you later.! :)

Related Posts with Thumbnails