[RESOLVIDO] Erro de validação selectonemenu

Antes de me crucificarem por postar isso novamente eu digo: sim eu usei a busca. Mas tentei de todos os jeitos e não consegui…
Vi que precisava de implementar um converter e fiz isso, mas agora está dando:

java.lang.NullPointerException
party.utils.CityConverter.getAsObject(CityConverter.java:21)

<h:outputLabel value="#{msg.city}*:" for="city" /> <h:selectOneMenu id="city" value="#{userMB.city}" required="true" requiredMessage="#{msg.city_empty}" converter="cityConverter"> <f:selectItem itemLabel="#{msg.select_city}" itemValue="" /> <f:selectItems value="#{userMB.listCities}" var="b" itemValue="#{b}" itemLabel="#{b.city}" /> </h:selectOneMenu>

[code]@FacesConverter(value = “cityConverter”)
public class CityConverter implements Converter {

@EJB
private CityRepository cityRepository;

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
	if (value != null && !value.equals("")) {
		return this.cityRepository.findById(Long.valueOf(value));
	}
	return null;
}

@Override
public String getAsString(FacesContext context, UIComponent component,	Object value) {
	if(value instanceof City){
		City city = (City) value;
		return String.valueOf(city.getCityId());
	}
	return "";
}

}[/code]

Já tentei de tudo e sempre da um erro diferente, variando de null converter para erro de validação e agora nullpointer
Alguma luz? :shock:

Posta esse #{userMB.listCities} para eu dar uma olhada.

Ta ai:
:slight_smile:

[code] public List getListStates() {
if (this.listStates == null) {
this.listStates = this.stateRepository.findAll();
}
return this.listStates;
}

public List<City> getListCities() {
	return this.listCities;
}

public void listCitiesByState() {
	this.listCities = this.cityRepository.findByState(this.state);
}[/code]

Tente o carregamento pelo collection

public Collection&lt;SelectItem&gt; getCarregarSelect() {  
    ArrayList list = new ArrayList();  
    Collection&lt;SelectItem&gt; lst = new ArrayList&lt;SelectItem&gt;();  
    List&lt;City&gt; lista = carregarLista; //carregue sua lista de cidades aqui
    for (int i = 0; i &lt; lista.size(); i++) {  
        lst.add(new SelectItem(lista.get(i).getId(), lista.get(i).getNomeCidade()));  
    }  
    return lst;  
} 

no select

&lt;h:selectOneMenu value="#{meuBeanNomeado.valorVinculado}"&gt;  
       &lt;f:selectItems value="#{meuBeanNomeado.carregaSelect}"/&gt;                   
&lt;/h:selectOneMenu&gt; 

Fiz do jeito que tu falou, mas como campo ta como required=“true”.
Agora ta dando como se o campo estivesse vazio e mostrando mensagem configurada por mim de campo vazio.

Coloquei da seguinte forma:

No MB:

public Collection<SelectItem> getCarregarSelect() { Collection<SelectItem> lst = new ArrayList<SelectItem>(); List<City> lista = this.cityRepository.findByState(this.state); for (int i = 0; i < lista.size(); i++) { lst.add(new SelectItem(lista.get(i).getCityId(), lista.get(i).getCity())); } return lst; }
Na página:

<h:outputLabel value="#{msg.city}*:" for="city" /> <h:selectOneMenu id="city" value="#{userMB.city}" required="true" requiredMessage="#{msg.city_empty}" converter="cityConverter"> <f:selectItem itemLabel="#{msg.select_city}" itemValue="" /> <f:selectItems value="#{userMB.carregarSelect}" /> </h:selectOneMenu>

Ao enviar o formulário recebo:

Por favor selecione sua cidade

tenta assim

<h:outputLabel value="#{msg.city}*:" for="city" />  
<h:selectOneMenu id="city" value="#{userMB.city}" required="true" requiredMessage="#{msg.city_empty}" >  
    <f:selectItem itemLabel="#{msg.select_city}" itemValue="" />  
    <f:selectItems value="#{userMB.listCities}" var="b" itemValue="#{b}" itemLabel="#{b.city}" />
   <f:converter converterId="cityConverter" />
</h:selectOneMenu>

Deu:

[code]exception

javax.servlet.ServletException
javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)
root cause

java.lang.NullPointerException
party.utils.CityConverter.getAsObject(CityConverter.java:21)
com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:171)
com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectOneValue(MenuRenderer.java:202)
com.sun.faces.renderkit.html_basic.MenuRenderer.getConvertedValue(MenuRenderer.java:319)
javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030)
javax.faces.component.UIInput.validate(UIInput.java:960)
javax.faces.component.UIInput.executeValidate(UIInput.java:1233)
javax.faces.component.UIInput.processValidators(UIInput.java:698)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
javax.faces.component.UIForm.processValidators(UIForm.java:253)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1172)
com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)
[/code]

Parece que meu converter está retornando null, mas não vejo erro nenhum com ele.

Cara eu tive o mesmo problema e não entendi o pq, mas tenta assim só pra ver se o erro para :

<h:outputLabel value="#{msg.city}*:" for="city" />  
    <h:selectOneMenu id="city" value="#{userMB.city}" required="true" requiredMessage="#{msg.city_empty}" converter="cityConverter">  
        <f:selectItems value="#{userMB.listCities}" var="b" itemValue="#{b}" itemLabel="#{b.city}" />  
    </h:selectOneMenu>  

remove to seu select:

&lt;f:selectItem itemLabel="#{msg.select_city}" itemValue="" /&gt;  

e no código, adicione isso:

public Collection&lt;SelectItem&gt; getCarregarSelect() {      
        Collection&lt;SelectItem&gt; lst = new ArrayList&lt;SelectItem&gt;();    
        lst.add(new SelectItem("valor", "O que vai aparecer escrito no select"));      //aqui
        List&lt;City&gt; lista = this.cityRepository.findByState(this.state);  
        for (int i = 0; i &lt; lista.size(); i++) {      
            lst.add(new SelectItem(lista.get(i).getCityId(), lista.get(i).getCity()));      
        }      
        return lst;      
    } 

[quote=andre.froes]remove to seu select:

&lt;f:selectItem itemLabel="#{msg.select_city}" itemValue="" /&gt;  

e no código, adicione isso:

public Collection&lt;SelectItem&gt; getCarregarSelect() {      
        Collection&lt;SelectItem&gt; lst = new ArrayList&lt;SelectItem&gt;();    
        lst.add(new SelectItem("valor", "O que vai aparecer escrito no select"));      //aqui
        List&lt;City&gt; lista = this.cityRepository.findByState(this.state);  
        for (int i = 0; i &lt; lista.size(); i++) {      
            lst.add(new SelectItem(lista.get(i).getCityId(), lista.get(i).getCity()));      
        }      
        return lst;      
    } 
[/code] [/quote]

Fiz do jeito que tu falou, porém ainda está dando que o valor selecionado está vazio.
Acho que tem algo de errado com o converter, mas não consegui indentificar:

[code]	@Override
	public String getAsString(FacesContext context, UIComponent component,	Object value) {
		if(value instanceof City){
			City city = (City) value;
			return String.valueOf(city.getCityId());
		}
		return "";
	}

Cara, na boa. Volte seu código ao que estava no começo do tópico.
Seu erro era:[quote]java.lang.NullPointerException
party.utils.CityConverter.getAsObject(CityConverter.java:21) [/quote]
Não será pq o @EJB não foi injetado não? Você verificou isso?
Pq vc não tenta por lookup ao invés de Injection?
Converters ainda não estão dendo do contexto de JSF (Será uma nova feature do JSF 2.2).

[quote=jakefrog]Cara, na boa. Volte seu código ao que estava no começo do tópico.
Seu erro era:[quote]java.lang.NullPointerException
party.utils.CityConverter.getAsObject(CityConverter.java:21) [/quote]
Não será pq o @EJB não foi injetado não? Você verificou isso?
Pq vc não tenta por lookup ao invés de Injection?
Converters ainda não estão dendo do contexto de JSF (Será uma nova feature do JSF 2.2).
[/quote]

Fiz por lookup e agora está dando o erro do ínicio antes de implementar o converter:

j_idt7:city: Erro de validação: o valor não é válido

EJB:

public City findById(Long id) {
		TypedQuery<City> query = (TypedQuery<City>) this.entityManager
				.createQuery("FROM City where city_id = :city");
		query.setParameter("city", id);
		return query.getSingleResult();
	}

Tentei usar o EJB assim:

public City findById(Long id) { javax.persistence.Query query = (Query) this.entityManager.find(City.class, id); return (City) query.getSingleResult(); }

Mas quando coloco assim da o seguinte erro:

[code]exception

javax.servlet.ServletException: java.lang.ClassCastException: party.entities.City cannot be cast to javax.persistence.Query
javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)
[/code]

Meu converter está assim agora:

@Override public Object getAsObject(FacesContext context, UIComponent component, String value) { if (value != null && !value.equals("")) { try { InitialContext ini = new InitialContext(); CityRepository repo = (CityRepository) ini.lookup("java:module/CityRepository"); return repo.findById(Long.valueOf(value)); } catch (NamingException e) { e.printStackTrace(); } } return null; }

Não é assim que se faz, cara ^^ public City findById(Long id) { javax.persistence.Query query = (Query) this.entityManager.find(City.class, id); return (City) query.getSingleResult(); } Você está tentando jogar o resultado de uma busca, que ja é o objeto que você quer, em uma Query, não tem pra que. Mude pra isso:public City findById(Long id) { City city = this.entityManager.find(City.class, id); return city; } ou simplesmente: public City findById(Long id) { return this.entityManager.find(City.class, id); }

[quote=digaoneves]Não é assim que se faz, cara ^^ public City findById(Long id) { javax.persistence.Query query = (Query) this.entityManager.find(City.class, id); return (City) query.getSingleResult(); } Você está tentando jogar o resultado de uma busca, que ja é o objeto que você quer, em uma Query, não tem pra que. Mude pra isso:public City findById(Long id) { City city = this.entityManager.find(City.class, id); return city; } ou simplesmente: public City findById(Long id) { return this.entityManager.find(City.class, id); } [/quote]

Burrice minha, rsrs…
Coloquei do jeito que tu falou:

public City findById(Long id) { return this.entityManager.find(City.class, id); }

Mas ainda continua dando:

j_idt7:city: Erro de validação: o valor não é válido

Ta foda isso… :frowning:

Para quê exatamente você está utilizando o converter? Pelo visto, aqui, ele só te está apresentando problemas em algo que não têm problema algum. Se você, daquela forma do collection, adicionar valor vazio:

lst.add(new SelectItem("", "O que vai aparecer escrito no select"));

que seria o value dele, ele já vai cair na validação, porque o valor é null e é necessário, caso não seja null, você já sabe que o valor é válido, e se precisar converter algo, você pode fazer a conversão do elemento dentro do #{userMB.city}
por exemplo, o valor que você passou, ao invés de ser String é um Integer, então:

private Integer city;

public void setCity(String valor){
     this.city = Integer.parseInt(valor);   
}

public Integer getCity(){
     return city;
}

[quote=andre.froes]Para quê exatamente você está utilizando o converter? Pelo visto, aqui, ele só te está apresentando problemas em algo que não têm problema algum. Se você, daquela forma do collection, adicionar valor vazio:

lst.add(new SelectItem("", "O que vai aparecer escrito no select"));

que seria o value dele, ele já vai cair na validação, porque o valor é null e é necessário, caso não seja null, você já sabe que o valor é válido, e se precisar converter algo, você pode fazer a conversão do elemento dentro do #{userMB.city}
por exemplo, o valor que você passou, ao invés de ser String é um Integer, então:

[code]
private Integer city;

public void setCity(String valor){
this.city = Integer.parseInt(valor);
}

public Integer getCity(){
return city;
}
[/code][/quote]

Ae galera, consegui…
Fiz do jeito que o Andre falou:

	public Collection&lt;SelectItem&gt; getCarregarSelect() {    
	    Collection&lt;SelectItem&gt; lst = new ArrayList&lt;SelectItem&gt;();    
	    lst.add(new SelectItem("", "Selecione"));
	    List&lt;City&gt; lista = this.cityRepository.findByState(this.state);
	    for (int i = 0; i &lt; lista.size(); i++) {    
	        lst.add(new SelectItem(lista.get(i).getCityId(), lista.get(i).getCity()));    
	    }    
	    return lst;    
	}
			&lt;h:outputLabel value="#{msg.city}*:" for="city" /&gt;
			&lt;h:selectOneMenu id="city" value="#{userMB.city}" required="true" requiredMessage="#{msg.city_empty}"&gt;
				&lt;f:selectItems value="#{userMB.carregarSelect}" /&gt;
			&lt;/h:selectOneMenu&gt;
private Long city;

	public Long getCity() {
		return city;
	}

	public void setCity(Long city) {
		this.city = city;
	}

Valeu todo mundo que ajudou ! :slight_smile:

Vi que seu projeto é EJB, no convert esta tendando fazer a injeção com anotação @EJB,
isso nao funciona no convert da uma olhada na net sobre EJB IOC.

seu getAsObject do convert o metodo “this.cityRepository.findById(Long.valueOf(value));” retorna sempre nulo.

Tem se ser feito um lookup para a injeção do ejb, muito manual.

Cria a inteface remota (CityRepositoryRemote) com @Remote e no convert coloca o lookup na mão, o selectmenu esta correto e o bean tamém ficou faltando somente isso.

Assim:

private CityRepositoryRemote getSession() {
try {
return (CityRepositoryRemote) new InitialContext().lookup(“java:app/CIREJB/CityRepository!com.cir.facade.CityRepositoryRemote”);
} catch (Exception ex) {
throw new IllegalArgumentException(ex);
}
}

@Override
public String getAsString…

@Override
public String getAsString…

[quote=drubervany]Vi que seu projeto é EJB, no convert esta tendando fazer a injeção com anotação @EJB,
isso nao funciona no convert da uma olhada na net sobre EJB IOC.

seu getAsObject do convert o metodo “this.cityRepository.findById(Long.valueOf(value));” retorna sempre nulo.

Tem se ser feito um lookup para a injeção do ejb, muito manual.

Cria a inteface remota (CityRepositoryRemote) com @Remote e no convert coloca o lookup na mão, o selectmenu esta correto e o bean tamém ficou faltando somente isso.

Assim:

private CityRepositoryRemote getSession() {
try {
return (CityRepositoryRemote) new InitialContext().lookup(“java:app/CIREJB/CityRepository!com.cir.facade.CityRepositoryRemote”);
} catch (Exception ex) {
throw new IllegalArgumentException(ex);
}
}

@Override
public String getAsString…

@Override
public String getAsString…[/quote]

Bom dia drubervany!

Cara acho que estou com o mesmo problema que voce passou ai em cima, só que estou tentando fazer o lookup manual e não estou conseguindo, tem como me ajudar? Posso postar o fonte?

Adriano poderia me ajugar aqui.