2017-01-20 9 views
0

RichFacesを使用しているJSFアプリケーションでは、オブジェクトを表示するrich:dataTable の画面と、選択されたレコードの詳細を使用して、別のページを使用することができます。提出実行しているときに、この2番目のページでJSF - 不明な理由で値が有効なオプションではない>>重複を再評価する

は、要求されたデータを完了した後、検証がメッセージを返します。

:Value is not a valid option. 

this postで引用問題とは異なり、問題のフィールドの名前ではない、ということを見て表示されます。

デバッグ中にselecionarEmitente()メソッドでオブジェクトlocalidadeがnullであることがわかりました。 dataTableページでセットを作成し、選択されたオブジェクトの名前がsecondPageに表示されたら、何が欠けていますか?

この問題に関する他の投稿を既に調査しました。たとえば、this postによれば、私のjavabeansにはequals()hashCode()のメソッドがあります。このother postとは異なり、私はカスタムコンバータを使用しています。

私の間違いはどこですか?

私はRichFaces 4.5.1.Final、MyFaces 2.2.10、Spring 3.1.1を使用しています。

dataTable.xhtml

<h:selectOneMenu id="estado" 
    immediate="true" validator="#{validadorMB.validarEstado}" 
    converter="estadoConverter"> 
    <f:selectItem itemLabel="---" /> 
    <f:selectItems value="#{localidadeMB.estados}" 
        var="est" itemValue="#{est}" itemLabel="#{est.uf}" /> 
    <a4j:ajax event="change" actionListener="#{localidadeMB.filtrarUF}" render="table" /> 
</h:selectOneMenu> 

<a4j:region id="region" immediate="true"> 
    <rich:dataTable id="tabela" 
     value="#{localidadeMB.getLocalidadesPorUF()}" var="loc" 
     rowKeyVar="row" rows="20" width="800px" render="scroller"> 
     <rich:column id="col_localidade" sortBy="#{loc.nome}" filterBy="#{loc.nome}"> 
      <h:outputText id="nomeLocalidade" value="#{loc.nome}" /> 
     </rich:column> 
     ... 
     <rich:column> 
      <h:commandLink id="declaracaolink" action="#{localidadeMB.carregarLocalidade}"> 
       <h:graphicImage url="/img/declaracao.png" /> 
       <f:setPropertyActionListener value="#{loc}" target="#{localidadeMB.localidade}" /> 
      </h:commandLink> 
     </rich:column> 
    </rich:dataTable> 
</a4j:region> 

secondPage.xhtml

<h:body> 
    <h:form id="formDeclaracao" focus="estado"> 
     <h:panelGrid columns="2" columnClasses="labelFormulario"> 
      <h:outputLabel value="UF" for="estado" /> 
      <h:selectOneMenu id="estado" 
       value="#{localidadeMB.localidade.estado}" 
       label="#{localidadeMB.localidade.estado.uf}" 
       valueChangeListener="#{localidadeMB.selecionarEstado}" 
       validator="#{validadorMB.validarEstado}" immediate="true" 
       converter="estadoConverter" 
       style="width: 45px;" styleClass="listbox"> 
       <f:selectItems value="#{localidadeMB.estados}" 
         var="est" itemValue="#{est}" itemLabel="#{est.uf}" /> 
       <a4j:ajax event="change" render="nomeLocalidade" /> 
      </h:selectOneMenu> 

      <h:outputLabel value="Nome da localidade:" for="nomeLocalidade" /> 
      <h:selectOneMenu id="nomeLocalidade" 
       value="#{localidadeMB.localidade}" 
       label="#{localidadeMB.localidade.nome}" immediate="true" 
       valueChangeListener="#{localidadeMB.selecionarLocalidade}" 
       validator="#{validadorMB.validarLocalidade}" 
       converter="localidadeConverter" 
       style="width: 220px;" styleClass="listbox"> 
       <f:selectItems value="#{localidadeMB.localidades}" 
        var="loc" itemValue="#{loc}" itemLabel="#{loc.nome}" /> 
      </h:selectOneMenu> 

      <h:outputLabel value="Interessado:" for="interessado" /> 
      <h:inputText id="interessado" value="" required="true" 
       requiredMessage="xxxxxxxxx" immediate="true" 
       styleClass="listbox" style="width: 215px;"> 
      </h:inputText> 

      <h:outputLabel value="Solicitante:" for="solicitante" /> 
      <h:inputText id="solicitante" value="" required="true" 
       requiredMessage="xxxxxxxxxxxxx" immediate="true"> 
      </h:inputText> 

      <h:outputLabel value="Documento apresentado:" for="documento" /> 
      <h:inputText id="documento" value="" required="true" 
       requiredMessage="xxxxxxxxxxxxx" immediate="true"> 
      </h:inputText> 

      <h:outputLabel value="Emitente:" for="emitente" /> 
      <h:selectOneMenu id="emitente" 
       value="#{localidadeMB.emitente}" 
       label="#{localidadeMB.emitente.descricaoReduzida}" 
       valueChangeListener="#{localidadeMB.selecionarEmitente}" 
       validator="#{validadorMB.validarEmitente}" 
       converter="emitenteConverter"> 
       <f:selectItem itemLabel="---" /> 
       <f:selectItems value="#{localidadeMB.emitentes}" var="em" itemValue="#{em}" itemLabel="#{em.descricaoReduzida}" /> 
      </h:selectOneMenu> 

      <h:commandButton id="btnGerarDeclaracao" value="Get PDF" 
       action="#{localidadeMB.getPDF()}" style="width: 84px;" /> 
     </h:panelGrid> 
    </h:form> 
</h:body> 

ManagedBean

@ManagedBean 
public class LocalidadeMB{ 
    private Emitente emitente; 
    private Estado estado; 
    private Localidade localidade; 

    public String carregarLocalidade() { 
     estado = localidade.getEstado(); 
     localidade = getLocalidade(); 
     getLocalidades(); 
     carregarLocalidadePorUF(estado); 
     return "secondPage.xhtml"; 
    } 

    public void filtrarUF(ActionEvent action) { 
     try { 
      String uf = JSFHelper.getRequestParameter("formConsulta" 
       + UINamingContainer.getSeparatorChar(JSFHelper 
        .getFacesContext()) + "estado"); 
      estado = estadoFacade.getEstado(Integer.parseInt(uf)); 
     } catch (Exception e) { 
      ... 
     } 
    } 

    public List<Emitente> getEmitentes() { 
     try { 
      return emitenteFacade.getEmitentes(); 
     } catch (Exception e) { 
      ... 
     } 
    } 

    public List<Emitente> getEstados() { 
     try { 
      return estadoFacade.getEstados(); 
     } catch (...) { 
      ... 
     } 
    } 

    public List<Localidade> getLocalidades() { 
     try { 
      return localidadeFacade.getLocalidades(); 
     } catch (Exception e) { 
      ... 
     } 
    } 

    public List<Localidade> getLocalidadesPorUF() { 
     try { 
      String uf = JSFHelper.getRequestParameter("formConsulta" 
       + UINamingContainer.getSeparatorChar(JSFHelper 
         .getFacesContext()) + "estado"); 
      if ((uf != null) && (!uf.equals("---"))) { 
       estado = estadoFacade.getEstado(Integer.parseInt(uf)); 
       return localidadeFacade.getLocalidadesPorEstado(estado); 
      } else { 
       return null; 
      } 
     } catch (Exception e) { 
      ... 
     } 
    } 


    public void selecionarEmitente(ValueChangeEvent evento) { 
     emitente = (Emitente)evento.getNewValue(); 
    } 

    public void selecionarEstado(ValueChangeEvent evento) { 
     estado = (Estado)evento.getNewValue(); 
    } 

    public void selecionarLocalidade(ValueChangeEvent evento) { 
     localidade = (Localidade)evento.getNewValue(); 
    } 
} 

のバリ

@ManagedBean(name = "validadorMB") 
public class ValidadorLocalidadeMB { 
    public void validarEmitente(FacesContext context, UIComponent componentToValidate, Object value) throws ValidatorException { 
     if (((Emitente) value).getEmitenteId() == 0) { 
      FacesMessage msg = new FacesMessage(null, "Selecione o emitente"); 
      throw new ValidatorException(msg); 
     } 
    } 

    public void validarEstado(FacesContext context, UIComponent componentToValidate, Object value) throws ValidatorException { 
     if (((Estado) value).getEstadoId() == 0) { 
      FacesMessage msg = new FacesMessage(null, "Selecione uma UF"); 
      throw new ValidatorException(msg); 
     } 
    } 

    public void validarLocalidade(FacesContext context, UIComponent componentToValidate, Object value) throws ValidatorException { 
     if (((Localidade) value).getLocalidadeId() == 0) { 
      FacesMessage msg = new FacesMessage(null, "Selecione uma localidade"); 
      throw new ValidatorException(msg); 
     } 
    } 
} 

コンバータ

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

    @Override 
    public Object getAsObject(FacesContext context, UIComponent ui, String value) throws ConverterException { 
     ValueExpression vex = context 
      .getApplication() 
      .getExpressionFactory() 
      .createValueExpression(context.getELContext(), 
        "#{emitenteFacade}", EmitenteFacadeImpl.class); 

     EmitenteFacadeImpl fac = (EmitenteFacadeImpl) vex.getValue(context 
      .getELContext()); 
     try { 
      return fac.getEmitentePorId(Integer.valueOf(value)); 
     } catch (NumberFormatException | DAOException e) { 
     .... 
     } 
    } 

    @Override 
    public String getAsString(FacesContext context, UIComponent ui, Object value) throws ConverterException { 
     if (value == null) { 
      return ""; 
     } 

     if (value instanceof Emitente) { 
      return String.valueOf(((Emitente) value).getEmitenteId()); 
     } 
    } 
} 

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

    @Override 
    public Object getAsObject(FacesContext context, UIComponent ui, String value) throws ConverterException { 
     ValueExpression vex = context 
      .getApplication() 
      .getExpressionFactory() 
      .createValueExpression(context.getELContext(), 
        "#{estadoFacade}", EstadoFacadeImpl.class); 

     EstadoFacadeImpl fac = (EstadoFacadeImpl) vex.getValue(context 
      .getELContext()); 
     try { 
      return fac.getEstadoPorId(Integer.valueOf(value)); 
     } catch (NumberFormatException | DAOException e) { 
     .... 
     } 
    } 

    @Override 
    public String getAsString(FacesContext context, UIComponent ui, Object value) throws ConverterException { 
     if (value == null) { 
      return ""; 
     } 

     if (value instanceof Estado) { 
      return String.valueOf(((Estado) value).getEstadoId()); 
     } 
    } 
} 

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

    @Override 
    public Object getAsObject(FacesContext context, UIComponent ui, String value) throws ConverterException { 
     ValueExpression vex = context 
      .getApplication() 
      .getExpressionFactory() 
      .createValueExpression(context.getELContext(), 
        "#{localidadeFacade}", LocalidadeFacadeImpl.class); 

     LocalidadeFacadeImpl fac = (LocalidadeFacadeImpl) vex.getValue(context.getELContext()); 
     try { 
      return fac.getLocalidadePorId(Integer.valueOf(value)); 
     } catch (NumberFormatException | DAOException e) { 
     .... 
     } 
    } 

    @Override 
    public String getAsString(FacesContext context, UIComponent ui, Object value) throws ConverterException { 
     if (value == null) { 
      return ""; 
     } 

     if (value instanceof Localidade) { 
      return String.valueOf(((Localidade) value).getLocalidadeId()); 
     } 
    } 
} 
+0

この質問を1つのコンポーネントに絞り込むことはできますか? –

+0

ゲッターにはビジネスロジックはありませんが、それが問題なのかどうかは分かりません。 – Makhiel

+0

申し訳ありません、Emil Sierzega、あなたの質問を理解できませんでした。 –

答えて

1

あなたの問題は、この行を次のようになります。

value="#{(localidadeMB.localidade.localidadeId != null) ? localidadeMB.localidade.localidadeId :localidadeMB.localidade}" 

<h:selectOneMenu>の値は、単純なプロパティではなく、表現する必要があり、それは設定する必要があります。


編集:あなたはvalueプロパティとしてエンティティのIDを持つものSelectItem Sを構築し、その後Stringに/からを変換するコンバータを使用

あなたのコードで別の問題がある可能性がありますエンティティ自体

このようにあなたのためのいくつかの可能性があります。

  1. SelectItemvalueとしてコンバータ、および「全体」エンティティを使用してくださいが。
  2. first linkのように、Selectitemが、Listのエンティティ自体は使用しないでください。
  3. もう1つの方法は、ダミーエンティティを使用してidプロパティを設定し、valueChangeListenerでIDでエンティティを取得することです。
+0

ありがとう、私はこの制限があるとは思わないが、あなたの提案にしたがって、式を削除して単純な値(localidadeMB.localidade.localidadeId)を残しましたが、うまくいきませんでした。 –

+0

value属性は実際には間違っていますが、これは正確にこのエラーでモデル値の更新段階で問題として現れます: 'javax.el.PropertyNotWritableException:設定操作の不正な構文'。しかし、OPの具体的な問題は、すでに検証段階で発生しており、全く異なるエラーが発生しています。 – BalusC

+0

提案に従ってコードを変更しましたが、エラーは残ります。私はコードを変更し、別のページから抜粋を挿入して、文脈を理解できるようにしました。 –

関連する問題