Problema com Hibernate

25 respostas
X

Eu quero fazer uma lista para imprimir usuários com nome parecidos tipo:
Eu quero o usuário Alexandre:
Então na lista deve Aparece todos os usuários que comece com Alexandre. Ex: Alexandre Lima, Alexandre Rabelo e etc

Mais ter 2 iguais no banco e eu for busca ele, o hibernate lança um erro:

javax.servlet.ServletException: #{alunoBean.pesquisaByNome}: org.hibernate.NonUniqueResultException: query did not return a unique result: 3 javax.faces.webapp.FacesServlet.service(FacesServlet.java:277) org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178) org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290) org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368) org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)

Como eu resolvo isso? Alguém sabe?
Obrigado

25 Respostas

romarcio

Coloca a consulta pra gente ver.

rafaelrodrigues1607

Posta o código aí irmão.

X
romarcio:
Coloca a consulta pra gente ver.
O Metodo da consulta:
public String pesquisaByNome(){
		AlunoFacadeImpl alunoService = new AlunoFacadeImpl();
		this.aluno = alunoService.procuraByNome(this.aluno.getNome());
		
		return "pesquisaByNomeSucesso";
	}

Foi malz esquecido de colocar... ;;

Diego_Adriano

Cara, vc não teria que carregar um Array com sua consulta ?

viniciuspadua

essa pesquisa esta retornando mais de um elemento e talvez esteja esperando apenas um!

Diego_Adriano

Poste esse método pra gente ver: procuraByNome

rafaelrodrigues1607

Coloca o código da classe “AlunoFacadeImpl”.

romarcio

Você não postou a consulta, mas se está usando na consulta .uniqueResult() tá errado, tem que retornar um lista.

X
Diego Adriano:
Poste esse método pra gente ver: procuraByNome
Aki:
public Aluno procuraByNome(String nome){
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);
		
		Aluno p = this.alunoDAO.pesquisaAlunoByNome(nome);
		
		tx.commit();
		session.close();
		
		return p; 
	}
romarcio

Posta o método da consulta, o que contém a consulta.

Diego_Adriano

Cara, agente precisa ver o método que faz a pesquisa no BD, onde esta o SQL …
Mas … a sua forma de retorno esta errada …

X
rafaelrodrigues1607:
Coloca o código da classe "AlunoFacadeImpl".
public class AlunoFacadeImpl implements AlunoFacade {

	private static final long serialVersionUID = 1818242808424001885L;
	
	private AlunoDAO alunoDAO;
	private SessionFactory sf; 
	private	Session session;
	private Transaction tx;
	
	public void salva(Aluno p) {
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);
		
		this.alunoDAO.save(p);
		
		tx.commit();
		session.close();
	}

	public void atualiza(Aluno p) {
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);
		
		this.alunoDAO.merge(p);
		
		tx.commit();
		session.close();
	}

	public Aluno procura(Long id) {
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);
				
		Aluno p = this.alunoDAO.load(id);
		
		tx.commit();
		session.close();
		
		return p;
	}

	public void remove(Aluno p) {
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);
		
		this.alunoDAO.delete(p);
		
		tx.commit();
		session.close();
	}

	public List<Aluno> lista() {
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);
				
		List<Aluno> lista = this.alunoDAO.list();
		
		tx.commit();
		session.close();
		
		return lista;
	}
	
	public List<Aluno> pesquisaAlunosByNome(String nome) {
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);
		
		List<Aluno> lista = this.alunoDAO.pesquisaAlunos(nome);
		tx.commit();
		session.close();
		
		return lista;
	}
	
	public Pessoa procuraById(Long id){
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);
				
		Aluno p = this.alunoDAO.pesquisaAlunoById(id);
		
		tx.commit();
		session.close();
		
		return p;
	}
	
	public Aluno procuraByNome(String nome){
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);
		
		Aluno p = this.alunoDAO.pesquisaAlunoByNome(nome);
		
		tx.commit();
		session.close();
		
		return p; 
	}
	
	public Aluno procuraByEmail(String email){
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);

		Aluno p = this.alunoDAO.pesquisaAlunoByEmail(email);
		
		tx.commit();
		session.close();
		
		return p; 
	}

	
}
rafaelrodrigues1607

Posta o método: “pesquisaAlunoByNome”.

Diego_Adriano

Ai cara … de uma olhada nisso … ela retorna mais de um resultado

public List<Cliente> getAlunos(){
	Query query = this.entityManager.createQuery("Select new modelo.Cliente(c.id, c.nome, c.sobrenome, c.cpf) from Cliente as c where "+	"c.situacao =:situacao");
	query.setParameter("situacao", "A");
		
	return query.getResultList();
}
X
Diego Adriano:
Cara, agente precisa ver o método que faz a pesquisa no BD, onde esta o SQL .. Mas .. a sua forma de retorno esta errada ..
É esse:
public Aluno pesquisaAlunoByNome(String nome) {
		logger.info("pesquisaAlunoByNome : " + nome);
		Criteria c = session.createCriteria(Aluno.class);
		c.add(Restrictions.ilike("nome", "%" + nome + "%"));

		return (Aluno)c.uniqueResult();
	}

Não sei como fazer uma busca com lista usando Criteria... Eu pensei que podia dá certo assim...

X
rafaelrodrigues1607:
Posta o método: "pesquisaAlunoByNome".
public Aluno pesquisaAlunoByNome(String nome) {
		logger.info("pesquisaAlunoByNome : " + nome);
		Criteria c = session.createCriteria(Aluno.class);
		c.add(Restrictions.ilike("nome", "%" + nome + "%"));

		return (Aluno)c.uniqueResult();
	}
Diego_Adriano

Cara, se vc quer devolver vário tera que devolver um List “getResultList()” uniqResult é um resultato só .

romarcio
xandi_m5:
rafaelrodrigues1607:
Posta o método: "pesquisaAlunoByNome".
public Aluno pesquisaAlunoByNome(String nome) {
		logger.info("pesquisaAlunoByNome : " + nome);
		Criteria c = session.createCriteria(Aluno.class);
		c.add(Restrictions.ilike("nome", "%" + nome + "%"));

		return (Aluno)c.uniqueResult();
	}

Foi como eu disse, você está retornando um único resultado enquanto a pesquisa possui N resultados. Assim o Hibernate não aceita, porque ele não saberá qual dos N deve retornar para você.
Então troque .uniqueResult() por .list()
E o retorno do método também deve ser uma lista.

Diego_Adriano

Mano, tenta assim:

Criteria consulta = sess.createCriteria(Pessoa.class);

consulta.add( Expression.like("nome", "Maria%") );

List resultado = consulta.list();

De uma olhada nesse site, vai lhe ajudar
http://www.dsc.ufcg.edu.br/~jacques/cursos/daca/html/hibernate/hibernate.htm

X
Diego Adriano:
Cara, se vc quer devolver vário tera que devolver um List "getResultList()" uniqResult é um resultato só .

Foi eu chamei aquele método por engano. O mal do Ctrl + Espaço... Mais olha ai os métodos correto pq ainda está dando erro aki

Então o correto é assim: Da Classe Dao:
@SuppressWarnings("unchecked")
	public List<Aluno> pesquisaAlunos(String nome){
		Criteria c = session.createCriteria(Aluno.class);
		c.add(Restrictions.ilike("nome", "%" + nome + "%"));
		c.addOrder(Order.asc("nome"));
		
		return c.list();
	}
Da classe AlunoFacadeImpl:
public List<Aluno> pesquisaAlunosByNome(String nome) {
		sf = new AnnotationConfiguration().configure().buildSessionFactory(); 
		session = sf.openSession();
		tx = session.beginTransaction();
		alunoDAO = new AlunoDAO(session, Aluno.class);
		
		List<Aluno> lista = this.alunoDAO.pesquisaAlunos(nome);
		tx.commit();
		session.close();
		
		return lista;
	}
Do Bean:
public List<Aluno> getAlunosByNome(){ 
		AlunoFacadeImpl alunoService = new AlunoFacadeImpl();

		List<Aluno> lista = alunoService.pesquisaAlunosByNome(this.aluno.getNome());
	
		return lista;
	}
Agora chamado o método AlunosByNome() no commandButton o eclipse reclama isso:
Method must have "String method()" but has signature "List method()"
rafaelrodrigues1607

Da forma que o Diego Adriano falou é uma boa alternativa.

romarcio

ou

consulta.add( Restrictions.like("nome", "Maria", MatchMode.START) ); Vai retornar todos os nomes que iniciam por Maria.

romarcio

O problema agora parece não ser mais na consulta e sim no seu Servlet que não deve estar esperando uma lista.

X
rafaelrodrigues1607:
Da forma que o Diego Adriano falou é uma boa alternativa.
public List<Aluno> pesquisaAlunos(String nome){
		Criteria c = session.createCriteria(Aluno.class);
		c.add(Restrictions.ilike("nome", "%" + nome + "%"));
		c.addOrder(Order.asc("nome"));
		
		return c.list();
	}
X

Tb acho que é isso… Eu já fiz de varias maneiras e não deu certo?
Pode mi ajuda a fazer o Bean(Servlet)??
Alguem?

vlw!

Criado 20 de janeiro de 2012
Ultima resposta 20 de jan. de 2012
Respostas 25
Participantes 5