Tengo un problema con ap: selectOneMenu, no importa lo que haga, no puedo hacer que JSF llame al establecedor en la entidad JPA. La validación JSF falla con este mensaje:
formulario: ubicación: Error de validación: el valor no es válido
Tengo esto funcionando en varias otras clases del mismo tipo (es decir, unirse a clases de tabla) pero no puedo por mi vida hacer que funcione.
Si alguien puede ofrecer algunos consejos de solución de problemas / depuración para este tipo de problema, sería muy apreciado.
Usando declaraciones de registro, he verificado lo siguiente:
- El
Conveter
devuelvenull
valores correctos, sin valores. - No tengo validación de Bean en mis entidades JPA.
- El colocador
setLocation(Location location)
nunca es llamado.
Este es el ejemplo más simple que puedo hacer y simplemente no funcionará:
<h:body>
<h:form id="form">
<p:messages id="messages" autoUpdate="true" />
<p:selectOneMenu id="location" value="#{locationStockList.selected.location}" converter="locationConverter">
<p:ajax event="change" update=":form:lblLocation"/>
<f:selectItems value="#{locationStockList.locationSelection}"/>
</p:selectOneMenu>
</h:form>
</h:body>
Convertidor:
@FacesConverter(forClass=Location.class, value="locationConverter")
public class LocationConverter implements Converter, Serializable {
private static final Logger logger = Logger.getLogger(LocationConverter.class.getName());
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value.isEmpty())
return null;
try {
Long id = Long.parseLong(value);
Location location = ((LocationManagedBean) context.getApplication().getELResolver().getValue(context.getELContext(), null, "location")).find(id);
logger.log(Level.SEVERE, "Converted {0} to {1}" , new Object[] {value, location});
return location;
} catch (NumberFormatException e) {
return new Location();
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null || value.toString().isEmpty() || !(value instanceof Location))
return "";
return String.valueOf(((Location) value).getId());
}
}
Salida de consola:
// Getter method
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0]
// Session Bean
INFO: Finding ejb.locations.Location with id=3
// Session Bean
INFO: ### Returning : ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3]
// Converter
SEVERE: Converted 3 to ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3]
// Getter method -> Where did my selected Location go ??
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0]
fuente
equals
verificación? Mi situación es un poco compleja. Creo mi propio componente personalizado que permite al usuario tener un diseño de radio complejo. Funciona bien si solo tengo un grupo de radio (f: selectItems justo debajo de mi componente personalizado). Sin embargo, a medida que el diseño se vuelve más complejo (varios grupos de radio, cada uno tiene su propio f: selectItems pero todos comparten la misma selección), tengo que tener f: selectItems dentro de ui: repeat, luego ui: repeat está debajo de mi componente personalizado. Luego me encontré con este problema. Quiero ver el código mojarra que maneja estoEn mi caso, olvidé implementar un método get / set correcto. Sucedió porque cambié muchos atributos a lo largo del desarrollo.
Sin un método de obtención adecuado, JSF no puede recuperar el elemento seleccionado y sucede lo que dijo BalusC en el elemento 1 de su respuesta:
fuente
Esto puede ser un problema de convertidor o un problema de DTO. Intente resolver esto agregando los métodos hashCode () y equals () en su objeto DTO; En el escenario anterior, puede generar estos métodos dentro de la clase de objeto Location que se indica como 'DTO' aquí.
Ejemplo:
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (id ^ (id >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Location other = (Location) obj; if (id != other.id) return false; return true; }
fuente