Problema com campo de chave composta no JPA

3 respostas
fredabcdef

Ola a todos,

Meu primeiro post aqui no fórum.

Tenho que recuperar um usuario a partir do seu login, mas a tabela de usuario tem uma chave composta por 2 campos :

  • cedente_usuario e login_usuario
    o campo cedente_usuario tem o codigo do usuario.
    e o campo login_usuario tem o login do usuario.

Para resolver isso, eu criei 3 classes. A UsuarioCedente ( Bean ) , ChaveUsuario (que tem os campos da chave composta) e UsuarioCedenteDAO( que é onde eu faço as operaçoes de banco de dados)

segue o codigo das classes:

UsuarioCedente:

@Entity
@Table(name="usuario_cedente")
public class UsuarioCedente {
	
	@EmbeddedId
	private	ChaveUsuarioCedente	chaveCompostaUsuarioCedente;
	
	@Column(name="senha_usuario")
	private	String	senhaUsuario;
	
	@Column(name="nome_usuario")
	private	String	nomeUsuario;
	
	@Column(name="atualiza_usuario")
	private	String atualizaUsuario;
	
	@Column(name="bloqueio_usuario")
	private	String bloqueioUsuario;
	
	@Column(name="frase_usuario")
	private	String	fraseUsuario;
	
	@Column(name="resposta_usuario")
	private	String	respostaUsuario;
	
	@Column(name="email_usuario")
	private	String	emailUsuario;
	


	public ChaveUsuarioCedente getChaveCompostaUsuarioCedente() {
		return chaveCompostaUsuarioCedente;
	}

	public void setChaveCompostaUsuarioCedente(
			ChaveUsuarioCedente chaveCompostaUsuarioCedente) {
		this.chaveCompostaUsuarioCedente = chaveCompostaUsuarioCedente;
	}

	public String getSenhaUsuario() {
		return senhaUsuario;
	}

	public void setSenhaUsuario(String senhaUsuario) {
		this.senhaUsuario = senhaUsuario;
	}

	public String getNomeUsuario() {
		return nomeUsuario;
	}

	public void setNomeUsuario(String nomeUsuario) {
		this.nomeUsuario = nomeUsuario;
	}

	public String getAtualizaUsuario() {
		return atualizaUsuario;
	}

	public void setAtualizaUsuario(String atualizaUsuario) {
		this.atualizaUsuario = atualizaUsuario;
	}

	public String getBloqueioUsuario() {
		return bloqueioUsuario;
	}

	public void setBloqueioUsuario(String bloqueioUsuario) {
		this.bloqueioUsuario = bloqueioUsuario;
	}

	public String getFraseUsuario() {
		return fraseUsuario;
	}

	public void setFraseUsuario(String fraseUsuario) {
		this.fraseUsuario = fraseUsuario;
	}

	public String getRespostaUsuario() {
		return respostaUsuario;
	}

	public void setRespostaUsuario(String respostaUsuario) {
		this.respostaUsuario = respostaUsuario;
	}

	public String getEmailUsuario() {
		return emailUsuario;
	}

	public void setEmailUsuario(String emailUsuario) {
		this.emailUsuario = emailUsuario;
	}

}

ChaveUsuarioCedente :

@Embeddable
public class ChaveUsuarioCedente implements Serializable{

	
	@Column(name="cedente_usuario")
	private	String cedenteUsuario;	// codigo do usuario Cedente
	
	@Column(name="login_usuario")
	private	String loginUsuario;

	
	public	ChaveUsuarioCedente	(){
		
	}
	
	public	ChaveUsuarioCedente(String cedenteUsuario, String loginUsuario){
		super();
		this.cedenteUsuario	=	cedenteUsuario;
		this.loginUsuario	=	loginUsuario;
	}

	public String getCedenteUsuario() {
		return cedenteUsuario;
	}

	public void setCedenteUsuario(String cedenteUsuario) {
		this.cedenteUsuario = cedenteUsuario;
	}

	public String getLoginUsuario() {
		return loginUsuario;
	}

	public void setLoginUsuario(String loginUsuario) {
		this.loginUsuario = loginUsuario;
	}

}

e por ultimo a classe DAO

public class UsuarioCedenteDAO {

private EntityManagerFactory emf = Persistence.createEntityManagerFactory(Constantes.CONEXAO_JPA_DESKTOP);
	
	public String carregaSenhaUsuario(String loginUsuario){
		
		EntityManager em = emf.createEntityManager();
		
		StringBuffer sb = new StringBuffer();
		
		sb.append("select usuario.senhaUsuario from UsuarioCedente usuario");
		sb.append(" where usuario.chaveCompostaUsuarioCedente.loginUsuario = " + loginUsuario);
		
		Query query = em.createQuery(sb.toString());
		
		String resposta = (String)query.getSingleResult();
		return resposta;		
	}

   
     
public UsuarioCedente teste (String cedenteUsuario){
		
		EntityManager em = emf.createEntityManager();
		UsuarioCedente usuario	= null;
		
		StringBuffer sb = new StringBuffer();
		sb.append("select usuario from UsuarioCedente usuario");
		sb.append(" where usuario.chaveCompostaUsuarioCedente.cedenteUsuario = " + cedenteUsuario);
		
		Query query = em.createQuery(sb.toString());
		usuario	= (UsuarioCedente)query.getSingleResult();		
		return usuario;
	}


}

Estou com um problema bastante esquisito, quando tento carregar um dado do banco, a partir do campo loginUsuario , aparece o seguinte erro:

SEVERE: ERRO: coluna “itabira” não existe

Exception in thread main javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute query

at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:630)

at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:108)

at br.com.virtualtechnology.dao.UsuarioCedenteDAO.carregaUsuario(UsuarioCedenteDAO.java:46)

at br.com.virtualtechnology.teste.Teste.main(Teste.java:109)

Caused by: org.hibernate.exception.GenericJDBCException: could not execute query

at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)

at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)

at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)

at org.hibernate.loader.Loader.doList(Loader.java:2216)

at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)

at org.hibernate.loader.Loader.list(Loader.java:2099)

at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)

at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)

at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)

at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)

at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)

at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:82)

 2 more

Caused by: java.sql.SQLException: ERRO:  coluna itabira £o existe
at org.postgresql.core.QueryExecutor.execute(QueryExecutor.java:94)
at org.postgresql.Connection.ExecSQL(Connection.java:398)
at org.postgresql.jdbc2.Statement.execute(Statement.java:130)
at org.postgresql.jdbc2.Statement.executeQuery(Statement.java:54)
at org.postgresql.jdbc2.PreparedStatement.executeQuery(PreparedStatement.java:99)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
at org.hibernate.loader.Loader.doQuery(Loader.java:674)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2213)
... 10 more

onde “itabira” é o parametro passado para o metodo carregarUsuario(loginUsuario).

E quando eu tento recuperar o dado usando o outro campo da chave composta , o campo “cedenteUsuario” usando o metodo teste() , eu consigo retornar o usuario.

Alguma idéia do que está acontecendo ?

Att,
Fred Monteiro.

3 Respostas

aeugenio

Opa o problema e seu select altere para algo abaixo (repare na ')

sb.append("select usuario.senhaUsuario from UsuarioCedente usuario");  
    sb.append(" where usuario.chaveCompostaUsuarioCedente.loginUsuario = '" + loginUsuario+ "'");

Mas eu particularmente recomento vc fazer assim

sb.append("select usuario.senhaUsuario from UsuarioCedente usuario");  
    sb.append(" where usuario.chaveCompostaUsuarioCedente.loginUsuario = :login"); 
    Query query = em.createQuery(sb.toString()).setParameter("login", loginUsuario);

/peace

fredabcdef

Deu certo !
Valeu cara … mas é padrão colocar aspas simples em todos os valores que serão comparados ? pois sempre fiz sem colocar as aspas e nunca ocorreu problema.

e outra, pq vc recomenda fazer deste jeito ?

Valeu pela ajuda.

Att,
Fred Monteiro

aeugenio

Vc vai evitar problemas como SQL Injection alem de alguem digitar ’ no campo texto e pode dar problemas no seu select.
Eu recomento vc sempre usar parametros ate pra campos numericos.

/peace

Criado 6 de novembro de 2008
Ultima resposta 6 de nov. de 2008
Respostas 3
Participantes 2