2011-08-20 90 views
10

我使用managedBean USERHOME在requestScope,在該實體「用戶」將是堅持。 用戶具有在多對一relation.My代碼映射領導列看起來像這樣JSF轉換器驗證錯誤:值無效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; 
} 

我試圖通過h:selectOneMenu這樣得到這個領導者的價值

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

我的轉換器看起來像這樣

@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); 
     } 
    } 
} 

雖然試圖挽救我收到錯誤USEREDIT用戶:j_idt18:驗證錯誤:值無效

回答

14

添加到BalusC的回答:在回發之後,您需要確保User實例與您用於呈現選擇項的實例完全相同,或者您爲User類實現equals。

代碼沒有顯示availableLeaders來自哪裏,但是如果這是從數據庫按需提取的,那麼轉換器將不會轉換爲JSF通過#{userHome.selectItems}解析的列表中完全相同的對象實例。

轉換後,JSF將使用equals()方法檢查是否可以在該列表中找到轉換後的實例。

+0

嗨,它在mojarra代碼中的確切位置,這就等於檢查發生了。我正在編寫一個自定義組件,並且遇到了這個問題,我想調試mojarra代碼以查看正在發生的事情。謝謝 –

+0

這發生在'UISelectMany#validateValue'中,實際調用'SelectUtils#matchValue'中發生的'equals'。 –

+0

是的,經過大量的調試,我能夠弄清楚這是否認爲這是一個不好的做法不驗證?我的自定義組件從UISelectOne擴展而來,並且這個方法的validateValue給了我很多的傷感,如果我用這個空的內容描述這個方法,那麼事情就會正常工作。但我有一種感覺,這是我不應該做的。任何想法? –

8

您已經構建了SelectItem走錯了路。根據class' documentation,第一個參數應表示項目值(將被轉換並提交),第二個參數應表示項目標籤(將在列表中顯示)。但是你反過來指定他們。

修復它的相應地:

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

如果仍然沒有解決問題,那麼就意味着User類的equals()方法沒有(正確地)執行。 JSF將使用它來驗證所選的User與轉換後列表中的任何項目值。


無關到具體的問題,它可能是有用的知道,<f:selectItems>在JSF2爲您提供了生成列表,而無需手動生成的SelectItem名單的可能性。下面是其實現完全一樣的例子:

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

這可以讓你擺脫額外selectItems財產,在bean構造循環。

+1

+1用於保持SelectItem類型不在支持bean中,並讓它使用域對象的簡單列表;) –