Falando em JPA

35 respostas
paulofernandesjr

opa!

galera gostaria que algum me explicasse o seguinte.

onde devo colocar as anotações dos campos
assim esta correto, tem que ser antes do Get mesmo?

@Id
	@Column(name = "cod_cliente", unique = true, nullable = false, precision = 10, scale = 0)
	public Integer getCodCliente() {
		return this.codCliente;
	}

ou tem que ser diferente?

como posso fazer para selecionar o proximo valor de uma sequence?

obrigado

35 Respostas

paulofernandesjr

ou devo fazer assim

@Id
private Integer codUsuario;

qual é a forma correta?

Mero_Aprendiz

paulofernandesjr:
opa!

galera gostaria que algum me explicasse o seguinte.

onde devo colocar as anotações dos campos
assim esta correto, tem que ser antes do Get mesmo?

@Id
	@Column(name = "cod_cliente", unique = true, nullable = false, precision = 10, scale = 0)
	public Integer getCodCliente() {
		return this.codCliente;
	}

ou tem que ser diferente?

como posso fazer para selecionar o proximo valor de uma sequence?

Olá.
Bem, está correto sim. Deve ser no metódo GET.

Para informa o forma de preenchimento do id, informe o GeneratedValue, sendo os tipo AUTO, SEQUENCE, IDENTITY e TABLE.

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
@Column(name = "cod_cliente", unique = true, nullable = false, precision = 10, scale = 0)
public Integer getCodCliente() {
	return this.codCliente;
}

[]'s
JL

P

não há a necessida de ser no método. vc pode anotar no atributo. eu particulamente prefiro no atributo.

Filipe_Chagas

Anotações podem ser feitas nos atributos ou nos métodos, as duas formas estão corretas.
Mas contrariamente ao autor do post que linquei, eu prefiro fazer nos atributos por dois motivos simples:
[list]Legibilidade[/list]Prefiro que tudo que for relacionado a ORM fique o mais reunido possível. Fora que ter um monte de anotações espalhadas entre os métodos de minha classe fica bem feio.
[list]Encapsulamento![/list]Nem todos os meus atributos possuem métodos get e set! Simples assim!

:wink:

Mero_Aprendiz

Falha nossa!
Deveria ter escrito também pode ser ao invez de deve
Obviamente cada um tem seu metódo predileto de usar as anotações.
Eu pessoalmente utilizo em metódos GET apenas pelo costume que veio do XDoclet, nas versões anteriores ao uso de anotações.

[]'s
JL

A

Só exclarecendo:

Caso coloque a anotação no método Get, o JPA usará o metodo setter para atribuir o valor ao atributo.
Caso coloque a anotação no atributo, o JPA atribuirá o valor no atributo diretamente, via reflection.

Eu uso nos getters somente quando um dado precisa passar por algum tipo de tranformação antes de ser atribuido. É a minha forma de usar…

Mas lembre-se ou você usa todos nos atributos ou todos nos métodos, não pode misturar porque o JPA não gosta.

paulofernandesjr

bom como estou começando, você terãoq eu desculpar pelo tipo de pergunta… mas vamos lá

tenho a seguinte estrutura de tabelas

o código java fiz dessa forma

package br.com.ternet.cartao.bean;

import java.io.Serializable;

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

/**
 * Classe responsavel por representar um usuario no sistema 
 * @author Paulo Fernandes
 *
 */
@Entity
@Table(name="usuario", schema="public")
public class UsuarioBean implements Serializable {
	
	private static final long serialVersionUID = 7918140502550519009L;

	@Id
	@GeneratedValue(strategy=GenerationType.SEQUENCE)  
	@Column(name="cod_usuario")
	private Integer codigo;
	
	@Column(name="nome_usuario")
	private String nome;
	
	@Column(name="login")
	private String login;
	
	@Column(name="senha")
	private String senha;
	
	@Column(name="status")
	private Integer status;
	
	@Column(name="tipo_usuario")
	private Integer tipoUsuario;
	
	@ManyToOne(fetch=FetchType.LAZY)
	private EquipeBean equipe;
	
	// get and set removido para diminuir tamanho do post
	
}


----------------------------------------------------------------------------------

package br.com.ternet.cartao.bean;

import java.io.Serializable;

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

/**
 * classe responsavel por representar a equipe de vendas
 * @author Paulo Fernandes
 *
 */
@Entity
@Table(name="equipe", schema="public")
public class EquipeBean implements Serializable {
	
	private static final long serialVersionUID = 4157547012821652450L;

	@Id
	@GeneratedValue(strategy=GenerationType.SEQUENCE)
	@Column(name="cod_equipe")
	private Integer codEquipe;
	
	@Column(name="nome_equipe")
	private String nomeEquipe;
	
	@OneToMany(mappedBy="equipe", fetch=FetchType.LAZY)
	private UsuarioBean usuario;
	
	// get e set removido para diminuir tamanho do post
}

isso que eu fiz está correto?

como posso fazer essa query??

/** * metodo responsavel por retornar um usuario a partir do seu login * @param login * @return */ public UsuarioBean getUsuario(String login) { UsuarioBean usuario = (UsuarioBean) entity.createQuery(????).getSingleResult(); // quero pegar o usuario a partir do login... como fazer??? return usuario; }

PS:

esse é boa, ela tem vida própria…

hahah

A

Quase tem vida própria. :smiley:

Só mais uma coisa:
Quando o nome do campo na tabela é igual ao nome do atributo na classe, você não precisa especificar usando a anotação @Column
Como aqui:

@Column(name="login") private String login;

paulofernandesjr

beleza, valeu pela dica!

do resto esta tudo ok?

A

paulofernandesjr:
beleza, valeu pela dica!

do resto esta tudo ok?

Só rodando para saber… roda ai… grava coisas no banco, consulta… pelo que vi ta tudo OK!
Outra dica importante é esquecer de abrir a transaction, comitar e fechar a transaction… muita gente fica desesperado porque não grava na tabela quando só esqueceu de comitar a transação!

paulofernandesjr

como poderia fazer essa query aqui

/** * metodo responsavel por retornar um usuario a partir do seu login * @param login * @return */ public UsuarioBean getUsuario(String login) { UsuarioBean usuario = (UsuarioBean) entity.createQuery(????).getSingleResult(); // quero pegar o usuario a partir do login... como fazer??? return usuario; }

num faço nem idéia de como fazer o select, tem algum tutorial?

bsl.lacerda
public UsuarioBean read(String login) {
		return this.getEntityManager().find(UsuarioBean.class, login);
	}

Tenta aê!

paulofernandesjr

deu esse erro aqui…

errei em algum momento no mapeamento

bsl.lacerda
@OneToMany(mappedBy="equipe", fetch=FetchType.LAZY, cascade=CascadeType.ALL)  
    private List<UsuarioBean> usuarios;

e

@ManyToOne(fetch=FetchType.LAZY)  
@JoinColumn(name="cod equipe")
    private EquipeBean equipe;
paulofernandesjr

agora ferrou de vez…

bsl.lacerda

O jar do cglib está no classpath?

paulofernandesjr

sim estão

a 2.1 e coloquei a 2.2

bsl.lacerda

Eu uso aqui a 2.1_3.
Será que é por que vc tem duas versões da CGLIB no classpath?
Tenta tirar uma e vê qual é…

paulofernandesjr

tirei e deu esse erro aqui

ai quando dou F5 dá aquele erro do cglib

fiz isso aqui no meu controller

/**
	 * efetua o login na aplicacao
	 * @return
	 * @throws SystemException 
	 * @throws HeuristicRollbackException 
	 * @throws HeuristicMixedException 
	 * @throws RollbackException 
	 * @throws IllegalStateException 
	 * @throws SecurityException 
	 */
	public String acessar() throws SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException {
		FacesContext context = FacesContext.getCurrentInstance();
		SessionFactory factory = new Configuration().configure().buildSessionFactory();
		Session sessionBD = factory.openSession();          
		Transaction transaction = (Transaction) sessionBD.beginTransaction(); 
		String retorno = "sucesso";
		LoginBiz biz = new LoginBiz();
		if ( biz.isUsuarioValido(usuario) ) {
			HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
			session.setAttribute("usuario", usuario);
			subMenusList = biz.getSubMenusList(usuario);
		} else {
			retorno = "falha";
			String msg = "Login ou Senha incorretos.";
			FacesMessage message = new FacesMessage(msg);
			context.addMessage("login", message);
		}
		transaction.commit();
		sessionBD.close();
		return retorno;
	}

esta correto???

agora deu esse erro aqui

paulofernandesjr

o printStackTrace

bsl.lacerda

Bom dia!
NoSuchMethodError quer dizer que um método esperado não foi encontrado na classe ClassWrite do jar da asm.
Troca a versão deste jar pra ver qual é.
Eu uso
Hibernate 3.2.1
cglib-2.1_3
asm-1.5.3
e asm-attrs-2.2

Good luck!

paulofernandesjr

Bruno Lacerda teria como você me mandar estes jar para que não tenha problema?

[email removido]

abraço

bsl.lacerda

Já foi!

paulofernandesjr

valeu bruno....

agora deu quase certo

public UsuarioBean read(String login) { 
		entity.getTransaction().begin();
		UsuarioBean usuario = entity.find(UsuarioBean.class, login);
		entity.close();
		return usuario;
}

se eu faço desse jeito acima, dá esse erro aqui

javax.servlet.ServletException: Provided id of the wrong type. Expected: class java.lang.Integer, got class java.lang.String javax.faces.webapp.FacesServlet.service(FacesServlet.java:256)

ai se eu coloco assim

[code]
public UsuarioBean read(String login) { 
		entity.getTransaction().begin();
		UsuarioBean usuario = entity.find(UsuarioBean.class, 1);
		entity.close();
		return usuario;
}

dá esse erro aqui

javax.servlet.ServletException: ERROR: syntax error at or near "equipe" javax.faces.webapp.FacesServlet.service(FacesServlet.java:256)

esse erro aqui é mais aceitavel pois a coluna que representa a equipe é null, que eu já resolvi

o problema agora é como fazer para buscar pelo campo login?

bsl.lacerda

Tem que montar uma query.
no método que eu havia te passado faz o seguinte:

public UsuarioBean read(String login) {
Query query = entity.createQuery("from usuarioBean ub where ub.login = ?");
		query.setParameter(1, login);
		return (UsuarioBean) query.getResultList().get(0);
}

Não testei aqui, mas vou ver se consigo tb.
Testa aí…

paulofernandesjr

Bruno, deu quase certo, tive que apenas colocar o nome da classe me maiusculo

public UsuarioBean read(String login) {  
 Query query = entity.createQuery("from UsuarioBean ub where ub.login = ?");  
         query.setParameter(1, login);  
        return (UsuarioBean) query.getResultList().get(0);  
}

aproveitando o tópico, como posso fazer para selecionar um determinado campo da tabela???

bsl.lacerda

Funcionou?
Retornou um usuário pelo Login?

Bom, os campos das tabelas são as variáveis de instância dos seus beans (objetos do modelo).
Se você quiser selecionar um campo da tabela é a mesma coisa que fez antes. No caso você selecionou um UsuarioBean pelo campo Login da tabela.
Com o objeto retornado você agora tem acesso a todos os campos daquele registro (UsuarioBean) que o hibernate retornou para você.

paulofernandesjr

funcionou, deu certinho…

mas o que perguntei é o seguinte…

vamos supor que eu queira selecionar o nome da equipe que o usuario faz parta, você concorda que não precisarei do objeto usuario completo…

teria como retornar só o nome da equipe?

bsl.lacerda

Somente a String?
Não tem como, além do usuário, você vai ter que navegar até o objeto equipe e pegar este nome, ou seja, o nome da equipe ao qual o usuário encontrado pelo login faz parte.
Ex:

usuarioBean.getEquipe().getNome();

[]

paulofernandesjr

ah então beleza…

pensei que desse para fazer

select nome_equipe from usuario login = ?

mas beleza…

vou fazer mais alguns pontos do sistema

abraço e obrigado pelas dicas

paulofernandesjr

agora veio outra dúvida!

como o Hibernate sabe a sequencia que ele tem que pegar…

@Entity
@Table(name="equipe", schema="public")
public class EquipeBean implements Serializable {
	
	private static final long serialVersionUID = 4157547012821652450L;

	@Id
	@GeneratedValue(strategy=GenerationType.SEQUENCE)
	@Column(name="cod_equipe")
	private Integer codEquipe;
	
	@Column(name="nome_equipe")
	private String nomeEquipe;
	
	@OneToMany(mappedBy="equipe", fetch=FetchType.LAZY, cascade=CascadeType.ALL)    
	private List<UsuarioBean> usuarios;

ele esta atribuindo o valor de zero para o código

porque isso ocorre!?

bsl.lacerda

Cara, não tenho certeza mas eu acho que se você não especificar a sequência que ele terá que utilizar no banco, no caso uma sequência criada por você no banco de dados direto, ele vai gerar a sequência para poder gerar os ids da forma dele, o que não garante que a ordem de criação da sequência será gerada de 1 em 1. Entendeu?
Eu acho que é isso mas vamos aguardar outras opiniões do pessoal mais por dentro do assunto.

paulofernandesjr

consegui fazer!

@Entity
@Table(name="equipe", schema="public")
@SequenceGenerator(name="seq_equipe", sequenceName="seq_equipe")
public class EquipeBean implements Serializable {
	
	private static final long serialVersionUID = 4157547012821652450L;

	@Id
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_equipe")
	@Column(name="cod_equipe")
	private Integer codEquipe;
paulofernandesjr

deu certo, mais nem tanto

ele não esta pegando o nextval do banco ele esta gerando uns numeros diferentes!

o que pode estar errado?

paulofernandesjr

alguem poderia me ajudar?

Criado 16 de março de 2009
Ultima resposta 19 de mar. de 2009
Respostas 35
Participantes 6