jsf - Conversion Error setting value for 'null Converter' -


i have problems understanding how use selection in jsf 2 pojo/entity effectively. example, i'm trying select warehouse entity via below dropdown:

<h:selectonemenu value="#{bean.selectedwarehouse}">     <f:selectitem itemlabel="choose 1 .." itemvalue="#{null}" />     <f:selectitems value="#{bean.availablewarehouses}" /> </h:selectonemenu> 

and below managed bean:

@named @viewscoped public class bean {      private warehouse selectedwarehouse;     private list<selectitem> availablewarehouses;      // ...      @postconstruct     public void init() {         // ...          availablewarehouses = new arraylist<>();          (warehouse warehouse : warehouseservice.listall()) {             availablewarehouses.add(new selectitem(warehouse, warehouse.getname()));         }     }      // ... } 

notice use whole warehouse entity value of selectitem.

when submit form, fails following faces message:

conversion error setting value 'com.example.warehouse@cafebabe' 'null converter'.

i hoping jsf set correct warehouse object managed bean when wrap in selectitem. wrapping entity inside selectitem meant skip creating converter entity.

do have use converter whenever want make use of entities in <h:selectonemenu>? should jsf possible extract selected item list of available items. if have use converter, practical way of doing it? far came this:

  1. create converter implementation entity.
  2. overriding getasstring(). think don't need since label property of selectitem used display dropdown option label.
  3. overriding getasobject(). think used return correct selectitem or entity depending on type of selected field defined in managed bean.

the getasobject() confuses me. efficient way this? having string value, how associated entity object? should query entity object service object based on string value , return entity? or perhaps somehow can access list of entities form selection items, loop them find correct entity, , return entity?

what normal approach of this?

introduction

jsf generates html. html in java terms 1 large string. represent java objects in html, have converted string. also, when html form submitted, submitted values treated string in http request parameters. under covers, jsf extracts them httpservletrequest#getparameter() returns string.

to convert between non-standard java object (i.e. not string, number or boolean el has builtin conversions, or date jsf provides builtin <f:convertdatetime> tag), have supply custom converter. selectitem has no special purpose @ all. it's leftover jsf 1.x when wasn't possible supply e.g. list<warehouse> directly <f:selectitems>. has no special treatment labels , conversion.

getasstring()

you need implement getasstring() method in such way desired java object been represented in unique string representation can used http request parameter. normally, technical id (the database primary key) used here.

public string getasstring(facescontext context, uicomponent component, object modelvalue) {     if (modelvalue == null) {         return "";     }      if (modelvalue instanceof warehouse) {         return string.valueof(((warehouse) modelvalue).getid());     } else {         throw new converterexception(new facesmessage(modelvalue + " not valid warehouse"));     } } 

note returning empty string in case of null/empty model value significant , required javadoc. see using "please select" f:selectitem null/empty value inside p:selectonemenu.

getasobject()

you need implement getasobject() in such way exactly string representation returned getasstring() can converted exactly same java object specified modelvalue in getasstring().

public object getasobject(facescontext context, uicomponent component, string submittedvalue) {     if (submittedvalue == null || submittedvalue.isempty()) {         return null;     }      try {         return warehouseservice.find(long.valueof(submittedvalue));     } catch (numberformatexception e) {         throw new converterexception(new facesmessage(submittedvalue + " not valid warehouse id"), e);     } } 

in other words, must technically able pass returned object modelvalue argument of getasstring() , pass obtained string submittedvalue argument of getasobject() in infinite loop.

usage

finally annotate converter @facesconverter hook on object type in question, jsf automatically take care of conversion when warehouse type ever comes picture:

@facesconverter(forclass=warehouse.class) 

that "canonical" jsf approach. it's after not effective indeed have grabbed item <f:selectitems>. important point of converter returns unique string representation, java object identified simple string suitable passing around in http , html.

generic converter based on tostring()

jsf utility library omnifaces has selectitemsconverter works based on tostring() outcome of entity. way not need fiddle getasobject() , expensive business/database operations anymore. concrete use examples, see showcase.

to use it, register below:

<h:selectonemenu ... converter="omnifaces.selectitemsconverter"> 

and make sure tostring() of warehouse entity returns unique representation of entity. instance directly return id:

@override public string tostring() {     return string.valueof(id); } 

or more readable/reusable:

@override public string tostring() {     return "warehouse[id=" + id + "]"; } 

see also:


unrelated problem, since jsf 2.0 it's not explicitly required anymore have list<selectitem> <f:selectitem> value. list<warehouse> suffice.

<h:selectonemenu value="#{bean.selectedwarehouse}">     <f:selectitem itemlabel="choose 1 .." itemvalue="#{null}" />     <f:selectitems value="#{bean.availablewarehouses}" var="warehouse"         itemlabel="#{warehouse.name}" itemvalue="#{warehouse}" /> </h:selectonemenu> 
private warehouse selectedwarehouse; private list<warehouse> availablewarehouses; 

Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -