Falando em JPA

35 respostas
P

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

P

ou devo fazer assim

@Id
private Integer codUsuario;

qual é a forma correta?

M

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.

F

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:

M

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.

P

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;

P

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!

P

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?

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

Tenta aê!

P

deu esse erro aqui…

errei em algum momento no mapeamento

B
@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;
P

agora ferrou de vez…

B

O jar do cglib está no classpath?

P

sim estão

a 2.1 e coloquei a 2.2

B

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 é…

P

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

P

o printStackTrace

B

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!

P

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

[email removido]

abraço

B

Já foi!

P

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?

B

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í…

P

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???

B

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ê.

P

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?

B

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();

[]

P

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

P

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

B

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.

P

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;
P

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?

P

alguem poderia me ajudar?

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