Ich habe ein Problem mit ap: selectOneMenu, egal was ich tue, ich kann JSF nicht dazu bringen, den Setter auf der JPA-Entität aufzurufen. Die JSF-Validierung schlägt mit dieser Meldung fehl:
form: location: Validation Error: Wert ist ungültig
Ich habe diese Arbeit an mehreren anderen Klassen des gleichen Typs (dh an Tabellenklassen teilnehmen), kann diese aber für mein ganzes Leben nicht zum Laufen bringen.
Wenn jemand Tipps zur Fehlerbehebung / zum Debuggen für diese Art von Problem geben kann, wäre er sehr dankbar.
Mit Hilfe von Protokollanweisungen habe ich Folgendes überprüft:
- Das
Conveter
gibt korrekte, nichtnull
Werte zurück. - Ich habe keine Bean-Validierung in meinen JPA-Entitäten.
- Der Setter
setLocation(Location location)
wird nie aufgerufen.
Dies ist das einfachste Beispiel, das ich machen kann, und es wird einfach nicht funktionieren:
<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>
Konverter:
@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());
}
}
Konsolenausgabe:
// 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]
quelle
equals
Prüfung stattfindet ? Meine Situation ist etwas komplex. Ich erstelle meine eigene benutzerdefinierte Komponente, die es dem Benutzer ermöglicht, ein komplexes Radio-Layout zu haben. Es funktioniert gut, wenn ich nur eine Funkgruppe habe (f: selectItems direkt unter meiner benutzerdefinierten Komponente). Wenn das Layout jedoch komplexer wird (mehrere Funkgruppen, jede hat ihre eigenen f: selectItems, aber alle haben dieselbe Auswahl), muss ich f: selectItems in ui: repeat haben, dann befindet sich die ui: repeat unter meiner benutzerdefinierten Komponente. Ich bin dann auf dieses Problem gestoßen. Ich möchte den Mojarra-Code sehen, der damit umgehtIn meinem Fall habe ich vergessen, eine korrekte get / set-Methode zu implementieren. Es ist passiert, weil ich im Laufe der Entwicklung viele Attribute geändert habe.
Ohne eine geeignete Get-Methode kann JSF Ihren ausgewählten Artikel nicht wiederherstellen, und es passiert, was BalusC unter Punkt 1 seiner Antwort gesagt hat:
quelle
Dies kann ein Konverterproblem oder ein DTO-Problem sein. Versuchen Sie dies zu lösen, indem Sie Ihrem Objekt DTO die Methoden hashCode () und equals () hinzufügen. Im obigen Szenario können Sie diese Methoden innerhalb der Location-Objektklasse generieren, die hier als 'DTO' angegeben sind.
Beispiel:
@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; }
quelle