i have problem p:selectonemenu, no matter cannot jsf call setter on jpa entity. jsf validation fails message:
form:location: validation error: value not valid
i have working on several other class of same type (ie, join table classes) cannot life of me 1 working.
if can throw troubleshooting/debugging tips sort of problem appreciated.
using log statements have verified following:
- the
conveter
returning correct, nonnull
values. - i have no bean validation in jpa entities.
- the setter
setlocation(location location)
never called.
this simplest example can , not work:
<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>
converter:
@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} {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()); } }
console output:
// 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 id=3 // session bean info: ### returning : ejb.locations.location[id=3, name=mdmd, latitude=4.5, longitude=2.3] // converter severe: converted 3 ejb.locations.location[id=3, name=mdmd, latitude=4.5, longitude=2.3] // getter method -> did selected location go ?? info: current value=ejb.locations.location[id=null, name=null, latitude=0.0, longitude=0.0]
validation fails message "form:location: validation error: value not valid"
this error boils down selected item not match of available select item values specified nested <f:selectitem(s)>
tag during processing of form submit request.
as part of safeguard against tampered/hacked requests, jsf reiterate on available select item values , test if selecteditem.equals(availableitem)
returns true
@ least 1 available item value. if no 1 item value matches, you'll validation error.
this process under covers below, whereby bean.getavailableitems()
fictionally represents entire list of available select items defined <f:selectitem(s)>
:
string submittedvalue = request.getparameter(component.getclientid()); converter converter = component.getconverter(); object selecteditem = (converter != null) ? converter.getasobject(context, component, submittedvalue) : submittedvalue; boolean valid = false; (object availableitem : bean.getavailableitems()) { if (selecteditem.equals(availableitem)) { valid = true; break; } } if (!valid) { throw new validatorexception("validation error: value not valid"); }
so, based on above logic, problem can logically have @ least following causes:
- the selected item missing in list of available items.
- the
equals()
method of class representing selected item missing or broken. - if custom
converter
involved, has returned wrong object ingetasobject()
. perhaps it'snull
.
to solve it:
- ensure same list been preserved during subsequent request, particularly in case of multiple cascading menus. making bean
@viewscoped
instead of@requestscoped
should fix in cases. make sure don't perform business logic in getter method of<f:selectitem(s)>
, instead in@postconstruct
or action event (listener) method. if you're relying on specific request parameters, you'd need explicitly store them in@viewscoped
bean, or re-pass them on subsequent requests e.g.<f:param>
. see how choose right bean scope? - ensure
equals()
method implemented right. done right on standard java types suchjava.lang.string
,java.lang.number
, etc, not on custom objects/beans/entites. see right way implement equals contract. in case you're usingstring
, make sure request character encoding configured right. if contains special characters , jsf configured render output utf-8 interpret input e.g. iso-8859-1, fail. see a.o. unicode input retrieved via primefaces input components become corrupted. - debug/log actions of custom
converter
, fix accordingly. guidelines, see conversion error setting value 'null converter' in case you're usingjava.util.date
available items<f:convertdatetime>
, make sure don't forget full time part in pattern. see "validation error: value not valid" error f:datetimeconverter.
see also:
- our
selectonemenu
wiki page - how populate options of h:selectonemenu database?
- make multiple dependent / cascading selectonemenu dropdown lists in jsf
if can throw troubleshooting/debugging tips sort of problem appreciated.
just ask clear , concrete question here. not ask broad questions ;)
Comments
Post a Comment