OneToMany com Hibernate JPA

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!!! 🙂

Os melhores posts de 2010 LpJava

ae! Pessoal,

Em preparativo dos posts para 2011 e das novidades para o próximo ano, resolvi listar os 12 posts mais visitados neste ano. Caso tenha perdido algum, confira quem são eles:

Os posts mais visitados 2010:

  1. Uma simples aplicação Hibernate + JSF + poolConexao

  2. Série NZ: Minha Experiência Intercâmbio – Auckland

  3. SimSCJP Premium

  4. Java Básico + Hibernate JPA + Mysql

  5. Quando ser contratado como PJ?

  6. selectOneMenu JSF com BD

  7. Como ser um Programador Senior Java

  8. JPA com Java Básico MySql

  9. Como melhorar seu estudo? English

  10. Praticando JSF Facelets no Eclipse

  11. Projetos com RedMine

  12. Open Session View – Hibernate Solução

Atingimos o número de 184 posts, desde os técnicos e não técnicos, nesses dois anos de trabalho, iniciado desde março/2008. Este ano foram 55 novos posts( técnicos, carreira, inglês). Espero escrever mais em 2011 😉

Vou ficando por aqui e semana que vem retorno com o ultimo post do ano, sobre metas/plano de carreira e retrospectiva.

Abracos, see ya!

JPA com Hibernate + JSF + MySQL

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.! 🙂

JPA com Java Básico MySql

olá pessoal, nesse post vou apresentar como fazer persistência de dados usando apenas JPA, mas com Java Básico o objetivo é ajudar aqueles que estão dando o primeiro passo com a tecnologia. Não confunda este post com este Java Básico + Hibernate JPA + Mysql são parecidos, mas aqui nos não vamos envolver nada de Hibernate, ou seja, será 100% JPA.

Recomendado: Você vai precisar configurar a JPA no seu projeto Java, portanto veja no post abaixo:

*Basta adicionar ao seu projeto o arquivo .jar referente a JPA do pacote hibernate annotations. Nada mais que isso, confira: Java Básico + Hibernate JPA + Mysql

Outros posts relacionados:

Preparando o ambiente desenvolvimento

  1. crie um Java project no eclipse

  2. E monte conforme a estrutura abaixo:

  3. A classe TesteJPA  deve conter o método main.

  4. Não esqueça de adicionar o .jar ao seu projeto. Se tem dúvida com fazer isso veja nos posts citados acima.

Preparando Banco de Dados

Vamos usar o MySql como BD e vou levar em conta que você já tem o mesmo instalado e configurado. Crie apensa um DataBase e uma table para este. Se quiser seguir o exemplo do post o nosso ficou assim:

DataBase: sistemas Table: Cliente

A tabela cliente possui os seguintes campos como VARCHAR(nome,cidade,sobrenome)e um Integer(id). O id é auto_increment e chave-primaria da tabela.

Desenvolvimento

Explicando as anotações
@Entity = é uma entidade que representa uma class bean;
@Table = mapeia com o nome da tabela. Aqui eu coloquei o table para explicar, mas poderia omitir levando em conta que eu teria uma table no meu BD com o mesmo nome da minha class Bean. Ou seja, se você não especificar qual será a tabela do BD, será considerada o nome do Bean. Tenha atenção se você tem tabelas com nomes diferentes em relação ao seu bean;
@Id = tem relação com a chave primaria da sua tabela;
@Column = mapeia com as colunas da sua tabela, segue a mesma regra de table, quando ter colunas com nomes diferentes este campo eh obrigatório, caso contrario non-required ;

Deixe sua classe Cliente.java conforme abaixo:

package br.com.bean;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="cliente")
public class Cliente {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	private String nome;
	private String cidade;
	private String sobrenome;

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public String getCidade() {
		return cidade;
	}
	public void setCidade(String cidade) {
		this.cidade = cidade;
	}
	public String getSobrenome() {
		return sobrenome;
	}
	public void setSobrenome(String sobrenome) {
		this.sobrenome = sobrenome;
	} }

A classe ClienteDAO é responsável por implementar o CRUD usando a JPA, vamos ver aqui o salvar, excluir e atualizar. Então atualize seu arquivo ClienteDAO.java conforme abaixo:

package br.com.dao;

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

import br.com.bean.Cliente;

public class ClienteDAO {

	EntityManagerFactory emf; 

	private EntityManager getEntityManager(){
		return emf.createEntityManager();
	}
	public ClienteDAO() {
	emf = Persistence.createEntityManagerFactory("sistemas");
	}

	public void salvar(Cliente cliente){
		EntityManager em = getEntityManager();
		try{
			em.getTransaction().begin(); //inicia o processo de transacao
			em.persist(cliente);//permite fazer insercoes e atualizacoes no bd
			em.getTransaction().commit();//realizo as alteracoes no banco
		}catch (Exception e) {
			em.getTransaction().rollback();// se rolar uma excecao cancelo acao
			e.printStackTrace();//mostro o percurso de onde veio as excecoes
		}finally{
			em.close();
		}
	}
	public void excluir(Cliente cliente){
		EntityManager em = getEntityManager();

		try{
			em.getTransaction().begin();
			cliente = em.merge(cliente);
			em.remove(cliente);
			em.getTransaction().commit();
		}catch (Exception e) {
			em.getTransaction().rollback();
		}
	}
	public void atualizar(Cliente cliente){
		EntityManager em = getEntityManager();
		try{
			em.getTransaction().begin();
			em.merge(cliente);
			em.getTransaction().commit();
		}catch (Exception e) {
			em.getTransaction().rollback();
		}}
	}
  1. Fazendo a persistência de dados no arquivo persistence.xml. Precisamos passar as informações do BD, user, password etc para o arquivo persistence.xml, assim conseguimos a conexao com o nosso BD. Então atualize o arquivo .xml conforme o code abaixo(tive que dar um espaco entre os <  >  pois o plugin para code não estava reconhecendo com XML):

    org.hibernate.ejb.HibernatePersistence
    < persistence-unit name="sistemas" transaction-type="RESOURCE_LOCAL">
    org.hibernate.ejb.HibernatePersistence
            
    		br.com.bean.Cliente
    
                
                < property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
                < property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
                < property name="hibernate.connection.url" value="jdbc:mysql://localhost/sistemas" />
                < property name="hibernate.connection.username" value="camilo" />
                < property name="hibernate.connection.password" value="integrator" />
     
                < property name="hibernate.show_sql" value="true" />
                < property name="hibernate.format_sql" value="true" />
                < property name="use_sql_comments" value="true" />
    
            < /properties>
    
        < /persistence-unit>
  2. Atualizando a classe TesteCliente.java. Precisamos ter uma classe para testar o nosso CRUD com JPA. Para isso teremos uma classe java tradicional com o método main. Eu comentei algumas linhas apenas para poder testar outros recursos. Mas, levando em conta que sua table não há nenhuma informação, vamos executar primeiramente a opção salvar.

    package br.com.teste;
    
    import br.com.bean.Cliente;
    import br.com.dao.ClienteDAO;
    
    public class TesteCliente {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		ClienteDAO clidao = new ClienteDAO();
    		Cliente cliente = new Cliente();
    	//	cliente.setCidade("salvador");
    		cliente.setNome("recife");
    		cliente.setSobrenome("neto");
    		//cliente.setId(12);
    		clidao.salvar(cliente);
    		//clidao.excluir(cliente);
    	//cliente.setCidade("Sao Paulo");
    		//cliente.setId(15);
    		//clidao.atualizar(cliente);
    	}
    }

Não Esqueça:

  • Esteja certo que você deu um start no seu BD.

  • não esqueça dos .jars no seu projeto.

Verificando dados no BD

  1. Acesse seu banco de dados e veja se a informação inserida realmente consta na tabela. Aqui usei uma ferramenta chamada Mysql Query Browser para facilitar o trabalho com o BD. No meu caso eu fiz varias alterações.

Vou ficado por aqui e espero que tenham gostado do post. Para quem está em primeiro contato com a tecnologia pode parecer difícil, estranho ou complicado essa estrutura da JPA, mas pode ter certeza que é mais produtivo no ciclo de desenvolvimento.

Abraços e até o próximo post.

JPA com Jboss

womanjava

olá pessoal, nesse post vou mostrar como criar um JPA Project e seus beneficios através da ferramenta Jboss Tools. Em um dos meus posts eu expliquei como instalar e configurar o Jboss tools no eclipse.

Montar uma estrutura JPA na “mão-grande” é um pouco cansativo e não tão produtivo quando se tem auxilio de uma ferramenta como Jboss tools. Nao estou dizendo que a ferramenta vai programar por você, ela apenas vai fazer a parte operacional não relacionada a programação, e você como bom desenvolvedor vai estar focado na parte lógica do negócio.

Lets go…

Outros posts:

  1. Abra o Eclipse e o seu workspace (uma vez que tenha instalado o plugin Jboss tools)

  2. Clique em New ==> Project

  3. Na lista que aparece vá até o diretório JPA.

  4. Escolha JPA Project, conforme a imagem abaixo:

    japproject

  5. Clique em next e na próxima pagina vamos dar o nome ao projeto e configurar o servidor. Aqui estamos usando o TomCat. Veja na imagem a seguir:

    namejpa

  6. Clique em next duas vezes. Até encontrar a tela a seguir. Agora precisamos configurar JPA e a plataforma. Depois clique em Finish

    jpaeclipse

  7. Pronto! Agora vc ja tem um projeto apto a usar JPA com os .jars adicionados estrutura ja montada pelo Jboss tools. Confira na imagem abaixo:

    jpaestrutura

Se você não conhecia o Jboss tools fica ai um pouquinho como a ferramenta pode ajudar no dia-dia.. 😉

Abraços! See you later…


Follow me: http://twitter.com/camilolope