Mam problem z ap: selectOneMenu, bez względu na to, co zrobię, nie mogę zmusić JSF do wywołania ustawiacza na encji JPA. Walidacja JSF kończy się niepowodzeniem z tą wiadomością:
formularz: lokalizacja: Błąd walidacji: Wartość jest nieprawidłowa
Mam to działające na kilku innych klasach tego samego typu (tj. Dołączam do zajęć przy stole), ale nie mogę sprawić, by ta działała przez całe życie.
Jeśli ktoś może rzucić kilka wskazówek dotyczących rozwiązywania problemów / debugowania tego rodzaju problemów, byłby bardzo wdzięczny.
Korzystając z instrukcji dziennika, zweryfikowałem następujące kwestie:
Conveter
Wraca poprawne, niżnull
wartości.- W moich podmiotach JPA nie ma funkcji Bean Validation.
- Rozgrywający
setLocation(Location location)
nigdy nie jest wywoływany.
To najprostszy przykład, jaki mogę zrobić i po prostu nie zadziała:
<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>
Przetwornik:
@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());
}
}
Wyjście konsoli:
// 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]
źródło
equals
sprawdzenie ma miejsce. Moja sytuacja jest nieco złożona. Tworzę własny niestandardowy komponent, który pozwala użytkownikowi mieć złożony układ radia. Działa dobrze, jeśli mam tylko jedną grupę radiową (f: selectItems tuż pod moim niestandardowym komponentem). Jednak w miarę jak układ staje się bardziej złożony (wiele grup radiowych, każda ma swoje własne f: selectItems, ale wszystkie mają ten sam wybór), muszę mieć f: selectItems w interfejsie ui: repeat, a następnie ui: repeat jest pod moim niestandardowym komponentem. Wtedy natknąłem się na ten problem. Chcę zobaczyć kod mojarra, który to obsługujeW moim przypadku zapomniałem zaimplementować poprawnych metod get / set. Stało się tak, ponieważ wraz z rozwojem zmieniłem wiele atrybutów.
Bez odpowiedniej metody pobierania JSF nie może odzyskać wybranego elementu i dzieje się tak, jak powiedział BalusC w punkcie 1 swojej odpowiedzi:
źródło
Może to być problem z konwerterem lub problem z DTO. Spróbuj rozwiązać ten problem, dodając metody hashCode () i equals () w swoim obiekcie DTO; W powyższym scenariuszu można wygenerować te metody w ramach klasy obiektu Location, które wskazują tutaj jako „DTO”.
Przykład:
@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; }
źródło