JSF-“值不是有效选项”,原因未知>>重新计算“重复”
在使用RichFaces的JSF应用程序中,我有一个带有rich:dataTable的屏幕 显示我的对象,以及引用另一页的列,其中包含所选记录的详细信息,以便使用 在第二个页面中,完成请求的数据后,运行submit时,验证将返回以下消息:JSF-“值不是有效选项”,原因未知>>重新计算“重复”,jsf,richfaces,converter,jsf-2.2,managed-bean,Jsf,Richfaces,Converter,Jsf 2.2,Managed Bean,在使用RichFaces的JSF应用程序中,我有一个带有rich:dataTable的屏幕 显示我的对象,以及引用另一页的列,其中包含所选记录的详细信息,以便使用 在第二个页面中,完成请求的数据后,运行submit时,验证将返回以下消息: :Value is not a valid option. 请注意,与中引用的问题不同,未显示问题字段的名称 在调试过程中,我注意到在SelecioNamente方法中,对象localidade为null。如果我在dataTable页面上进行了设置,并且所选
:Value is not a valid option.
请注意,与中引用的问题不同,未显示问题字段的名称
在调试过程中,我注意到在SelecioNamente方法中,对象localidade为null。如果我在dataTable页面上进行了设置,并且所选对象的名称出现在第二个页面上,那么缺少什么
我已经研究了其他关于这个问题的帖子。例如,根据,我的JavaBean包含equals和hashCode方法。与此不同,我使用的是自定义转换器
我的错在哪里
我使用的是RichFaces 4.5.1.Final、MyFaces 2.2.10、Spring 3.1.1
dataTable.xhtml
转换器
您的问题可能与这一行有关:
value="#{(localidadeMB.localidade.localidadeId != null) ? localidadeMB.localidade.localidadeId :localidadeMB.localidade}"
a的值应该是一个简单的属性,而不是表达式,因为它必须设置
编辑:
您的代码可能存在另一个问题:
您可以使用实体的ID作为value属性来构造这些SelectItems,然后使用converter将字符串转换为实体本身或实体本身
因此,您有几种可能性:
使用转换器和整个实体作为SelectItem的值。
或者不使用Selectitems,而是使用实体本身的列表,就像您的应用程序一样。
另一种可能是使用虚拟实体,设置其id属性,然后在valueChangeListener中通过id检索实体。
你能把这个问题缩小到一个组件吗?你不应该在getter中有任何业务逻辑,尽管很难说这是否是问题所在。对不起,Emil Sierzega,我不理解你的问题。Makhiel,我个人不认为问题出在getter中,因为它只是构造了SELECT元素。如此之多以至于select在HTML中完美地显示出来。所选的值将与select元素进行比较,这就是错误的来源。除了多次调用getter之外,它可能不会返回相同的值。谢谢您的回答。我认为没有这个限制,但根据您的建议,我删除了表达式并保留了简单的值localidadeMB.localidade.localidadeId,但它不起作用。value属性确实是错误的,但这只会在更新模型值阶段表现为一个问题,并出现以下错误:javax.el.propertynotwriteableexception:Set操作的非法语法。然而,OP的具体问题已经发生在验证阶段,并产生了一个完全不同的错误。我更改了代码并插入了另一页的摘录,以便理解上下文。
<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
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());
}
}
}
value="#{(localidadeMB.localidade.localidadeId != null) ? localidadeMB.localidade.localidadeId :localidadeMB.localidade}"