I'll see if I can come up with a fairly self-contained example. As far as the value set, I think I can argue that the set of values is consistent, especially when taking into account the associated converter. Matter of fact, we're expecting the serialization/deserialization of the converter to *keep* the values consistent by only allowing valid EJB values to be selected, and not even allowing null. Internally, the value is always a non-null EJB. Externally, the value representations are the valid EJB's plus one representation of a "nothing has been selected" state. We want the "nothing has been selected" representation to force an error, either through required="true" or some other mechanism.
Mike Kienenberger wrote: > > Not really sure how much more I can add. I've posted examples of > similar code I have, but without seeing a simplified (but erroring) > example demonstrating why your setup isn't working, I'm not sure what > else to suggest. getAsObject has to return a homogenious set of > objects. But as long as your converter translates the string values, > I think you can have a heterogenious collection of SelectItem > itemValues fed into the renderer. I know I've mixed marker Strings > (representing null and disabled selections) with actual > ProjectTypeLocal-esque objects on my page code. > > > On 4/2/07, fastbob <[EMAIL PROTECTED]> wrote: >> >> Usually the selectItem values are EJB's, but in a couple of instances >> they >> strings that just happen to be the serialized form of the EJB. The >> prototypical code looks like: >> >> ArrayList projectTypes = new ArrayList( >> projectTypeHome.findAll() >> ); >> for( int i = 0; i < projectTypes.size(); i++ ) >> { >> ProjectTypeLocal projectType = >> (ProjectTypeLocal)projectTypes.get( i ); >> m_projectTypes.add( new SelectItem( projectType, >> projectType.getName() ) ); >> } >> >> What this means is when we get to the following lines in >> _SelectItemsUtil, >> the equals() method of the EJB is called with the empty ("") string (in >> 1.1.5): >> >> [item is class SelectItem] >> Object itemValue = item.getValue(); >> if (value==itemValue || value.equals(itemValue)) >> >> It appears that the 1.1.3 code handled the case of any String being >> passed. >> Since our converters look for an empty string, this results in the EJB >> equals() being passed null: >> >> Object itemValue = item.getValue(); >> if(converter != null && itemValue instanceof String) >> { >> itemValue = converter.getConvertedValue(context, >> (String)itemValue); >> } >> if (value==itemValue || value.equals(itemValue)) >> >> But I guess this circles back to non-standard conversion that was taken >> out. >> >> I'm pretty ignorant of all the JSF lifecycle semantics, but since this >> practice is always used with required="true", would an earlier check for >> a >> non-null, non-empty string fix this? >> >> I'm open to suggestions. >> >> >> Mike Kienenberger wrote: >> > >> > Yes, I think you're right. It's not the form String -> Object that's >> > causing the issue. >> > It looks like it's the contents of the selectItem values. What are >> > you initializing the selectItem value fields with? >> > >> > What's the contents of selectItem.value when it's of type String? >> > >> > On 3/30/07, fastbob <[EMAIL PROTECTED]> wrote: >> >> >> >> Hmmm. I must be missing something. Other than parameterization, >> including >> >> your use of disable and null values, I don't see any significant >> >> differences >> >> (I also tried moving the converter into the h:selectOneMenu - no >> effect). >> >> In >> >> fact, the Tomahawk example uses "" as a nothing -selected value, just >> as >> >> we >> >> do. And the converter code is essentially identical - we start with: >> >> >> >> if( string == null || string.trim().length() == 0 ) >> >> return null; >> >> >> >> So why are we getting an exception during the validation phase? >> >> >> >> Bob >> >> >> >> >> >> Mike Kienenberger wrote: >> >> > >> >> > Here's how the tomahawk examples do it: >> >> > >> >> > <h:selectOneMenu id="selone_menu_colors" >> >> > value="#{carconf.color}" styleClass="selectOneMenu" >> >> > converter="#{carconf.colorConverter}"> >> >> > <f:selectItem itemValue="" >> >> > itemLabel="#{example_messages['empty_selitem']}" /> >> >> > >> >> > >> >> > >> >> > public Object getAsObject(FacesContext facesContext, >> >> > UIComponent component, String string) throws ConverterException >> >> > { >> >> > if(string==null) >> >> > return null; >> >> > >> >> > >> >> > Here's how I do it on my own projects: >> >> > >> >> > public final static String DISABLED_OPTION_VALUE = >> >> > "com.xyz.utilities.web.jsf.converter.DISABLED_OPTION_VALUE"; >> >> > public final static String NULL_OPTION_VALUE = >> >> > "com.xyz.utilities.web.jsf.converter.NULL_OPTION_VALUE"; >> >> > >> >> > public String getNullSelectItemOptionValue() { >> >> > return >> >> > >> com.xyz.utilities.web.jsf.converter.ConverterOptions.NULL_OPTION_VALUE; >> >> > } >> >> > >> >> > <f:selectItem >> >> > itemValue="#{myPage.nullSelectItemOptionValue}" >> >> > itemLabel="<No selection>" /> >> >> > >> >> > public Object getAsObject(FacesContext context, UIComponent >> >> > component, String value) throws ConverterException >> >> > { >> >> > if (null == value) return null; >> >> > if (ConverterOptions.DISABLED_OPTION_VALUE.equals(value)) >> >> return >> >> > null; >> >> > if (ConverterOptions.NULL_OPTION_VALUE.equals(value)) >> return >> >> > null; >> >> > >> >> > On 3/30/07, fastbob <[EMAIL PROTECTED]> wrote: >> >> >> >> >> >> >> >> >> Mike Kienenberger wrote: >> >> >> > >> >> >> > Yes, that's how I would do it. If you specify an itemValue, then >> >> that >> >> >> > value must be of the correct type. Ie, " " is not a >> containerType >> >> >> > (Srinivas) and "0" is not a region (Carl). >> >> >> > >> >> >> Ouch. The assumption is that there is a one-one correspondence >> between >> >> >> the >> >> >> list items and the type in the model. This isn't always the case. >> >> >> >> >> >> We had a number of JSP's under 1.1.3 with the following sequence, >> for >> >> >> several different types of lists: >> >> >> >> >> >> <h:selectOneMenu id="client" >> value="#{myPage.projectType}"> >> >> >> <f:converter converterId="x.y.ProjectTypeConverter"/> >> >> >> <f:selectItem itemValue="" itemLabel="--- Select >> Project >> >> >> Type---"/> >> >> >> <f:selectItems value="#{myPage.projectTypeList}"/> >> >> >> </h:selectOneMenu> >> >> >> >> >> >> The values in the type are fixed (essentially an enumeration, but >> not >> >> >> implemented that way), and there is no "empty" value available. >> >> Instead, >> >> >> if >> >> >> the converters are passed a null or empty string for conversion to >> the >> >> >> underlying type, they immediately return null. So in this case null >> is >> >> >> used >> >> >> to indicate no value has been selected by the user, and they get an >> >> >> error. >> >> >> >> >> >> With 1.1.5, we get the following exception: >> >> >> >> >> >> java.lang.ClassCastException: java.lang.String cannot be cast to >> >> >> javax.ejb.EJBLocalObject >> >> >> at >> >> >> >> >> >> org.jboss.ejb.plugins.local.LocalProxy.isIdentical(LocalProxy.java:124) >> >> >> at >> >> >> org.jboss.ejb.plugins.local.LocalProxy.invoke(LocalProxy.java:174) >> >> >> at >> >> >> org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:40) >> >> >> at >> >> >> org.jboss.ejb.plugins.local.LocalProxy.invoke(LocalProxy.java:155) >> >> >> at >> >> >> org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:40) >> >> >> at $Proxy262.equals(Unknown Source) >> >> >> at >> >> >> >> >> >> javax.faces.component._SelectItemsUtil.matchValue(_SelectItemsUtil.java:65) >> >> >> at >> >> >> >> javax.faces.component.UISelectOne.validateValue(UISelectOne.java:56) >> >> >> at >> >> javax.faces.component.UIInput.validate(UIInput.java:354) >> >> >> at >> >> >> javax.faces.component.UIInput.processValidators(UIInput.java:184) >> >> >> […] >> >> >> >> >> >> Here are the relevant lines from _SelectItemsUtil.MatchValue(): >> >> >> >> >> >> [item is class SelectItem] >> >> >> Object itemValue = item.getValue(); >> >> >> if (value==itemValue || value.equals(itemValue)) >> >> >> >> >> >> The exception is thrown by the call to equals in an EJB. >> >> >> >> >> >> I haven't come up with a low-cost way to fix this. >> >> >> >> >> >> Bob >> >> >> -- >> >> >> View this message in context: >> >> >> >> >> >> http://www.nabble.com/ERROR%3A-Value-is-not-a-valid-option-tf3270984.html#a9762021 >> >> >> Sent from the MyFaces - Users mailing list archive at Nabble.com. >> >> >> >> >> >> >> >> > >> >> > >> >> >> >> -- >> >> View this message in context: >> >> >> http://www.nabble.com/ERROR%3A-Value-is-not-a-valid-option-tf3270984.html#a9762503 >> >> Sent from the MyFaces - Users mailing list archive at Nabble.com. >> >> >> >> >> > >> > >> >> -- >> View this message in context: >> http://www.nabble.com/ERROR%3A-Value-is-not-a-valid-option-tf3270984.html#a9797466 >> Sent from the MyFaces - Users mailing list archive at Nabble.com. >> >> > > -- View this message in context: http://www.nabble.com/ERROR%3A-Value-is-not-a-valid-option-tf3270984.html#a9798897 Sent from the MyFaces - Users mailing list archive at Nabble.com.