2011-08-20 13 views
10

Sto usando il managedBean UserHome in requestScope, in cui l'entità 'utente' sarà persistono. L'utente ha la colonna capo che viene mappata in ManyToOne Codice relation.My assomiglia a questoJSF convertitore Errore di convalida: il valore non è valido per SelectOneMenu UIComponent

@ManagedBean 
@RequestScoped 
public class UserHome { 
    private User user = new User(); 
     // Getters and Setters 

    private List<SelectItem> selectItems = new ArrayList<SelectItem>(); 

    public UserHome() { 
     for(User user: availableLeaders) { 
      selectItems.add(new SelectItem(user.getName(), user)); 
     } 
    } 

    public void persis(); 
} 

User.java

public class User { 
    @Id 
    @Column 
    private Integer id; 

    @Column 
    privat String name; 

    @ManyToOne 
    private User leader; 
} 

Sto cercando di ottenere il valore di questo leader attraverso h:selectOneMenu come questo

<h:selectOneMenu value="#{userHome.user.leader}" converter="userConverter"> 
    <f:selectItems value="#{userHome.selectItems}"/> 
</h:selectOneMenu> 

mio convertitore si presenta così

@FacesConverter(forClass = User.class, value="userConverter") 
public class UserConverter implements Converter { 

    private Map<String, User> userValues = new HashMap<String, User>(); 

    public UserConverter() { 
     init(); 
    } 

    @Override 
    public Object getAsObject(FacesContext context, UIComponent component, 
      String value) { 
     return userValues.get(value); 
    } 

    @Override 
    public String getAsString(FacesContext context, UIComponent component, Object value) { 
     System.out.println("RAJASEKARAN "+value); 
     return ((User)value).getName(); 
    } 

    public void init() { 
     UserHome userHome = new UserHome(); 
     for(User user:userHome.availableLeaders()) { 
      userValues.put(user.getName(), user); 
     } 
    } 
} 

Mentre cercare di salvare l'utente Sto ottenendo l'USEREDIT errore: j_idt18: convalida errore: Valore non è valido

risposta

14

Aggiunta alla risposta di BalusC: dopo il postback, è necessario assicurarsi che le istanze utente siano esattamente le stesse utilizzate per il rendering degli elementi selezionati o che si implementi gli uguali per la classe utente.

Il codice non mostra da dove proviene availableLeaders, ma se questo viene prelevato da un DB su richiesta, il convertitore non converte la stessa identica istanza dell'oggetto nella lista che JSF risolve tramite #{userHome.selectItems}.

Dopo la conversione, JSF controllerà se l'istanza convertita può essere trovata in tale elenco usando il metodo equals().

+0

Salve, dove si trova esattamente nel codice mojarra, che ciò equivale al controllo.Sto scrivendo un componente personalizzato, e mi sono imbattuto in questo problema, e voglio eseguire il debug del codice mojarra per vedere cosa succede. Grazie –

+0

Questo succede in "UISelectMany # validateValue', con la chiamata effettiva a" equals' che accade in "SelectUtils # matchValue". –

+0

Sì, dopo un sacco di debug, sono in grado di capirlo, questa è una cattiva pratica da non convalidare? Il mio componente personalizzato si estende da UISelectOne, e questo metodo validateValue mi dà molto dolore, se ho overidde questo metodo con il contenuto vuoto, allora le cose funzionano correttamente. Ma ho la sensazione che sia qualcosa che non dovrei fare. Qualche pensiero? –

8

che hai costruito il SelectItem nel modo sbagliato. Come per lo class' documentation, il primo argomento dovrebbe rappresentare il valore dell'oggetto (che deve essere convertito e inviato) e il secondo argomento dovrebbe rappresentare l'etichetta dell'elemento (che deve essere visualizzato nell'elenco). Ma li hai specificati al contrario.

Fix di conseguenza:

selectItems.add(new SelectItem(user, user.getName())); 

Se questo ancora non si risolve il problema, allora vuol dire che il metodo di User classe equals() non è (correttamente) implementato. JSF lo userà per convalidare lo User selezionato rispetto a uno qualsiasi dei valori dell'articolo della lista dopo la conversione.


Estranei al problema concreto, può essere utile sapere che <f:selectItems> in JSF2 vi offre la possibilità di creare l'elenco, senza la necessità di costruire un elenco di SelectItem manualmente. Ecco un esempio che realizza esattamente la stessa:

<f:selectItems value="#{userHome.availableLeaders}" var="user" 
    itemValue="#{user}" itemLabel="#{user.name}" /> 

Ciò consente di sbarazzarsi dei supplementari selectItems proprietà e il ciclo nel costruttore di fagioli.

+1

+1 per mantenere il tipo SelectItem fuori dal backing bean e per utilizzarlo con semplici elenchi di oggetti di dominio;) –

Problemi correlati