2013-08-24 2 views
3

Я делаю проект в JSF с PrimeFaces, и у меня есть проблема с <p:SelectOneMenu>, в частности с преобразованием выбранного значения из объекта в String. Я написал необходимый класс конвертера, реализованный toString() и equals() методов, как я думаю, совершенно правильно. Однако, в <h:messages /> компоненте он бесконечно дает мне:
Конвертер в JSF (PrimeFaces) с SelectOneMenu: Ошибка проверки

j_idt7:j_idt92: Validation Error: Value is not valid
j_idt7:j_idt98: Validation Error: Value is not valid

я должен выбрать значения, которые являются частью одной крупной формы. Затем, основываясь на выбранном владельце (właściciel) и компании (firma), я добавляю их в базу данных.

Это мой <p:SelectOneMenu> (дважды - два меню):

<p:selectOneMenu value="#{wniosek.selectedWl}" var="w"> 
<f:selectItem itemLabel="Wybierz" itemValue=""/> 
    <f:selectItems value="#{wniosek.listaWl}" var="wlasciciel" 
     itemLabel="#{wlasciciel.nazwisko}" itemValue="#{wlasciciel}" /> 

     <p:column> 
      #{w.nazwisko} 
     </p:column> 
     <f:converter converterId="WlascicielConverter" /> 
</p:selectOneMenu>      
<h:outputText value="Nazwa firmy: "/> 

<p:selectOneMenu value="#{wniosek.selectedFi}" var="f"> 
     <f:selectItem itemLabel="Wybierz" itemValue=""/> 
     <f:selectItems value="#{wniosek.listaFi}" var="firma" 
      itemLabel="#{firma.nazwa}" itemValue="#{firma}" /> 
     <f:converter converterId="FirmaConverter" /> 
     <p:column> 
      #{f.nazwa} 
     </p:column> 
</p:selectOneMenu> 

Это мой конвертер класс для владельца <p:SelectOneMenu> (аналогично я сделал с компанией один):

public class WlascicielConverter implements Converter { 

int i = 0; 
@Override 
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) { 
    try {   
     if (arg2 == null || arg2.isEmpty()) { 
      return null; 
     } 
     String owner = arg2; 
     return WlascicielBean.findAnOwner(owner); 

    } catch (SQLException e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

@Override 
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) { 

    if(arg2 == null) return null; 

    Wlasciciel owner = new Wlasciciel(); 

    if(arg2 instanceof Wlasciciel) { 
     owner = (Wlasciciel)arg2; 
     System.out.println(owner.getNazwisko()); 
     String surname = owner.getNazwisko(); 
     return (surname != null) ? String.valueOf(surname) : null; 
    } else throw new ConverterException("Something wrong!" + arg2.hashCode() + arg2.toString()); 

} 

}

equals() метод:

@Override 
public boolean equals(Object obj) { 
    if (obj == this) return true; 
    if (!(obj instanceof Wlasciciel)) return false; 

    Wlasciciel wl = (Wlasciciel)obj; 
    if (this.id_w != wl.getId_w()) return false; 
    if (!this.nazwisko.equals(wl.getNazwisko())) return false; 
    if (!this.imie.equals(wl.getImie())) return false;  
    if (!this.ulica.equals(wl.getUlica())) return false; 
    if (this.nr != wl.getNr()) return false; 
    if (this.lokal != wl.getLokal()) return false; 
    if (this.id_n != wl.getId_n()) return false; 

    return true; 
} 

Не могли бы вы дать мне несколько советов по решению этой проблемы? Я прочитал много руководств о конвертерах в JSF, попробовал много способов улучшить его, но он по-прежнему не работает. Я не знаю ... может быть, проблема в другом месте моего кода? Из-за его длины я бы не вставлял его здесь (конечно, если это необходимо, я сделаю это).

ответ

7

В общей сложности я думаю, что вы на правильном пути, даже если не-английский код делает его очень трудно понять, что вы на самом деле там делают ...

Что происходит: Вы Коллекцию что нибудь. Ваш конвертер проходит через эту коллекцию и вызывает getAsString() для каждого объекта. После того, как вы выбрали что-то в браузере, value (возвращаемое значение getAsString()) будет передаваться в преобразователь и будет вызываться getAsObject(). Это полностью НОВЫЙ объект, и не обязательно один из них, прежде чем (если ваш конвертер не получит доступ к этой коллекции и не возьмет ее оттуда). После этого JSF возьмет коллекцию, которую он использовал для генерации selectOneMenu, и сравните каждый элемент с тем, который возвратил конвертер.

Это может произойти в equals() или hashCode(), в зависимости от того, какая коллекция была использована. Таким образом, вам необходимо переопределить оба параметра одновременно (что вы действительно ВСЕГДА должны делать).

Если JSF не смог найти какой-либо объект из коллекции, который соответствует возврату конвертера (равно true или hashCode - то же самое), вы получаете Validation Error: Value is not valid.

Надеюсь, что этот процесс немного очистился. Я предполагаю, что вам либо нужно реализовать hashCode(), либо ваш неправильный метод equals(). Настройка в целом правильная. Вам нужно отлаживать и проверять, почему именно JSF не находит объект в вашем списке.

+0

Другая возможная причина заключается в том, что во время отправки формы был изменен ''. См. Также http: // stackoverflow.com/questions/9069379/validation-error-value-is-not-valid/9069660 # 9069660 Претензии для расшифровки польского кода в любом случае :) – BalusC

+0

Я по-прежнему борюсь с этой проблемой. Я попытался выяснить, почему конвертер работает inproperly, и я обнаружил, что объект 'arg2' в методе' getAsString' является 'String', а не' Wlascicel' (но это должно быть, не так ли?). Поэтому я получаю «ClassCastException» - он не может преобразовать 'String' в' Wlasciciel'. Я удалил предыдущий список и ввел обновленный конвертер. Я действительно не знаю, что случилось. –

+0

нашел решение? –

Смежные вопросы