Problema com auto complete primefaces

Olá pessoal, estou tendo um problema com um autocomplete do Primefaces, que simplesmente traz o objeto inteiro e não apenas um atributo.
Quero que traga apenas o nome da empresa, e está trazendo tudo.

Podem me ajudar?

Código da consulta:

	@SuppressWarnings("unchecked")
	public List<Empresa> complete() {
		Query query = this.session.createQuery("Select e From Empresa as e");
		return query.list();

Managed Bean:

	public List<Empresa> autocompleteEmpresa(String query) {
		List<Empresa> results = new ArrayList<Empresa>();
		if (empresas.isEmpty()) {
			this.empresas = empresaRN.complete();
		}
		for (Empresa e : empresas) {
			if (e.getNome().startsWith(query)) {
				results.add(e);
			}
		}
		return results;
	}

Página:

					<p:autoComplete value="#{empresaBean.empresa.nome}" var="empresa"
						completeMethod="#{empresaBean.autocompleteEmpresa}"
						itemLabel="#{empresa.nome}" itemValue="#{empresa}"
						converter="Converter"
						onkeyup="this.value = this.value.toUpperCase();">
					</p:autoComplete>

Nunca fiz isso mas fica uma sugestão:

Não tem como fazer essa lista ser de String, e adicionar somente os nomes? ou você precisa do objeto todo?
Se for o caso, não resolveria sobreescrever o toString() para retornar o nome ?

Pode dar uma dica de como fazer isso?

public List<String> autoCompleteEmpresa(String query) { List<String> results = new ArrayList<String>(); if (empresas.isEmpty()) { this.empresas = empresaRN.complete(); } for (Empresa e : empresas) { if (e.getNome().startsWith(query)) { results.add(e.getNome()); } } return results; } isso ?

A hql mudaria?

Ah, você pode implementar um converter, e fazer da maneira que ja estava fazendo. Muito mais fácil.

http://www.primefaces.org/showcase/ui/autoCompletePojo.jsf

Digao, não sou experiente em jsf, o que de fato faz um converter?
e como implementar, nesse caso?

Desse modo como voce me disse anteriormente dá problema no getNome.

[quote=smnj]Digao, não sou experiente em jsf, o que de fato faz um converter?
e como implementar, nesse caso?[/quote]
Bom, um converter é o que vai converter (obviamente) um objeto do seu modelo, para uma String que você queira apresentar na sua View. Ficou confuso?

Usando o próprio exemplo do PrimeFaces [code]public class PlayerConverter implements Converter {

public static List&lt;Player&gt; playerDB;  

static {  
    playerDB = new ArrayList&lt;Player&gt;();  

    playerDB.add(new Player("Messi", 10));  
    playerDB.add(new Player("Bojan", 9));  
    playerDB.add(new Player("Henry", 14));  
    playerDB.add(new Player("Iniesta", 8));  
    playerDB.add(new Player("Villa", 7));  
    playerDB.add(new Player("Xavi", 6));  
    playerDB.add(new Player("Puyol", 5));  
    playerDB.add(new Player("Afellay", 20));  
    playerDB.add(new Player("Abidal", 22));  
    playerDB.add(new Player("Alves", 2));  
    playerDB.add(new Player("Pique", 3));  
    playerDB.add(new Player("Keita", 15));  
    playerDB.add(new Player("Busquets", 16));  
    playerDB.add(new Player("Adriano", 21));  
    playerDB.add(new Player("Valdes", 1));  
    playerDB.add(new Player("Thiago", 30));  
}  

public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {  
    if (submittedValue.trim().equals("")) {  
        return null;  
    } else {  
        try {  
            int number = Integer.parseInt(submittedValue);  

            for (Player p : playerDB) {  
                if (p.getNumber() == number) {  
                    return p;  
                }  
            }  

        } catch(NumberFormatException exception) {  
            throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid player"));  
        }  
    }  

    return null;  
}  

public String getAsString(FacesContext facesContext, UIComponent component, Object value) {  
    if (value == null || value.equals("")) {  
        return "";  
    } else {  
        return String.valueOf(((Player) value).getNumber());  
    }  
}  

}[/code]

No método getAsString, você recebe o objeto em si, no seu caso a Empresa, e retorna dela, uma representação textual (String) que a identifique da maneira que você quer, no caso, seria o nome.

No método getAsObject, você recebe a representação textual gerada anteriormente, e precisa a partir dela, obter o objeto para atualizar o seu modelo (ManagedBean), que no caso, ele itera a lista procurando pelo nome, quando encontra o objeto correto o retorna.

Deu pra entender?

Não é difícil entender, agora, implementar, é outra história…

Mas aí a gente te ajudar :slight_smile: Comece um conversor aí, implemente primeiro o getAsString porque é bem mais fácil,
depois tente o getAsObject, qualquer dúvida posta aqui.

Beleza então.

creio que isso não seria sufuciente:

package com.portal.view;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

import com.portal.empresa.Empresa;
import com.portal.empresa.EmpresaRN;

@FacesConverter(value = "Converter")
public class EntityConverter implements Converter {

	public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {

		if (arg2.trim().equals(""))
			return null;

		EmpresaRN empresaRN = new EmpresaRN();

		System.out.println("passando no converter getAsObject ");

		if (empresaRN != null) {
			System.out
					.println("passando no converter getAsObject dentro do método");
			return empresaRN;
		}

		return null;
	}

	@Override
	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
		System.out.println("passando no converter getAsString");
		if (arg2 != null && arg2 != "") {
			System.out
					.println("passando no converter getAsString dentro do método");
			Empresa e = (empresa) arg2;
			return b.getNome();

		}

		return "";
	}
}

bom, o getAsString está correto até, mas ficaria muito mais legível se ficasse igual ao do exemplo do PrimeFaces, só que ao invés de fazer o cast para Player, você faz para Empresa, e ao invés de invocar o getNumber você invoca o getNome.

Quanto ao getAsObject, ele não está correto, você precisaria de uma lista, pra retornar o objeto que você ja tem, se o seu converter for usado somente nessa tela, você pode buscar a lista diretamente do managed bean, fazendo algo como ELContext elContext = arg0.getELContext(); List<Empresa> list = ((MeuMB) elContext.getELResolver().getValue(elContext, null, "meuMB")).getListEmpresas(); Ja vi casos onde buscam diretamente do banco a lista, tornando o conversor mais genérico, e também garantindo que os dados são atuais. não sei o que é melhor para o seu caso.

Cara, vê se é isso:

package com.portal.view;

import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;

import com.portal.empresa.Empresa;

public class EntityConverter implements Converter {

	public static List&lt;Empresa&gt; empresas;

	static {
		empresas = new ArrayList&lt;Empresa&gt;();
	}

	public Object getAsObject(FacesContext facesContext, UIComponent component,
			String submittedValue) {
		if (submittedValue.trim().equals("")) {
			return null;
		} else {
			try {
				String nome = submittedValue;

				for (Empresa e : empresas) {
					if (e.getNome() == nome) {
						return e;
					}
				}

			} catch (NumberFormatException exception) {
				throw new ConverterException(new FacesMessage(
						FacesMessage.SEVERITY_ERROR, "Conversion Error",
						"Not a valid value"));
			}
		}

		return null;
	}

	public String getAsString(FacesContext facesContext, UIComponent component,
			Object value) {
		if (value == null || value.equals("")) {
			return "";
		} else {
			return String.valueOf(((Empresa) value).getNome());
		}
	}
}

o problemas esta nesse codigo seu :


&lt;p:autoComplete value="#{empresaBean.empresa.nome}" var="empresa"  
    completeMethod="#{empresaBean.autocompleteEmpresa}"  
    itemLabel="#{empresa.nome}" itemValue="#{empresa}"  
    converter="Converter"  
    onkeyup="this.value = this.value.toUpperCase();"&gt;  
&lt;/p:autoComplete&gt; 

o certo para o que voce quer fazer é:


&lt;p:autoComplete value="#{empresaBean.empresa.nome}" var="empresa"  
    completeMethod="#{empresaBean.autocompleteEmpresa}"  
    itemLabel="#{empresa.nome}" itemValue="#{empresa.nome}"  
    converter="Converter"  
    onkeyup="this.value = this.value.toUpperCase();"&gt;  
&lt;/p:autoComplete&gt; 

a propriedade itemValue é o valor que ira para o value do componente, conseguentemente para o seu managedbean, como voce que so o nome no item value voce tem quer por o object.property dele, fazendo isso ira funcionar

o problemas esta nesse codigo seu :


&lt;p:autoComplete value="#{empresaBean.empresa.nome}" var="empresa"  
    completeMethod="#{empresaBean.autocompleteEmpresa}"  
    itemLabel="#{empresa.nome}" itemValue="#{empresa}"  
    converter="Converter"  
    onkeyup="this.value = this.value.toUpperCase();"&gt;  
&lt;/p:autoComplete&gt; 

o certo para o que voce quer fazer é:


&lt;p:autoComplete value="#{empresaBean.empresa.nome}" var="empresa"  
    completeMethod="#{empresaBean.autocompleteEmpresa}"  
    itemLabel="#{empresa.nome}" itemValue="#{empresa.nome}"  
    converter="Converter"  
    onkeyup="this.value = this.value.toUpperCase();"&gt;  
&lt;/p:autoComplete&gt; 

a propriedade itemValue é o valor que ira para o value do componente, conseguentemente para o seu managedbean, como voce que so o nome no item value voce tem quer por o object.property dele, fazendo isso ira funcionar

o problemas esta nesse codigo seu :


&lt;p:autoComplete value="#{empresaBean.empresa.nome}" var="empresa"  
    completeMethod="#{empresaBean.autocompleteEmpresa}"  
    itemLabel="#{empresa.nome}" itemValue="#{empresa}"  
    converter="Converter"  
    onkeyup="this.value = this.value.toUpperCase();"&gt;  
&lt;/p:autoComplete&gt; 

o certo para o que voce quer fazer é:


&lt;p:autoComplete value="#{empresaBean.empresa.nome}" var="empresa"  
    completeMethod="#{empresaBean.autocompleteEmpresa}"  
    itemLabel="#{empresa.nome}" itemValue="#{empresa.nome}"  
    converter="Converter"  
    onkeyup="this.value = this.value.toUpperCase();"&gt;  
&lt;/p:autoComplete&gt; 

a propriedade itemValue é o valor que ira para o value do componente, conseguentemente para o seu managedbean, como voce que so o nome no item value voce tem quer por o object.property dele, fazendo isso ira funcionar

o problemas esta nesse codigo seu :


&lt;p:autoComplete value="#{empresaBean.empresa.nome}" var="empresa"  
    completeMethod="#{empresaBean.autocompleteEmpresa}"  
    itemLabel="#{empresa.nome}" itemValue="#{empresa}"  
    converter="Converter"  
    onkeyup="this.value = this.value.toUpperCase();"&gt;  
&lt;/p:autoComplete&gt; 

o certo para o que voce quer fazer é:


&lt;p:autoComplete value="#{empresaBean.empresa.nome}" var="empresa"  
    completeMethod="#{empresaBean.autocompleteEmpresa}"  
    itemLabel="#{empresa.nome}" itemValue="#{empresa.nome}"  
    converter="Converter"  
    onkeyup="this.value = this.value.toUpperCase();"&gt;  
&lt;/p:autoComplete&gt; 

a propriedade itemValue é o valor que ira para o value do componente, conseguentemente para o seu managedbean, como voce que so o nome no item value voce tem quer por o object.property dele, fazendo isso ira funcionar

Va LE U MANOLO Acabaram com todos os meus problemas.!@!!!