4 Replies Latest reply on Jan 14, 2009 4:01 PM by Chris Moerz

    h:selectOne returns null

    Felix Khazin Newbie

      I've been using Seam for almost a year now and i still run into the stupidest problems...You'd think that after a year i would have the experience to know what to do, but i don't have a clue. But here is my situation:

      I have an h:selectOne:

                        <f:facet name="header">Duplicate</f:facet>
                        <h:selectOneMenu value="#{duplicateIVRScript.selectedIVRForDup}" rendered="#{not empty ivrListForDup}">
                             <s:selectItems value="#{ivrListForDup}" var="ivr" label="#{ivr.serviceCode}" noSelectionLabel="Select..."/>
                             <s:convertEntity />
                        <s:button value="Duplicate" action="#{duplicateIVRScript.duplicateIVR(ivrScript)}"></s:button>

      I run the debugger and duplicateIVRScript.selectedIVRForDup is always NULL!!

      Here is the bean:

      public class DuplicateIVRScriptAction implements DuplicateIVRScript
           private CustomerProduct customerProduct;
           private List<SEIVR> ivrListForDup;
           private SEIVR selectedIVRForDup;
           private EntityManager em;
           private Log log;
           private FacesMessages facesMessages;
           public void populateIVRList()
                ivrListForDup = (List) em.createQuery("FROM SEIVR seivr WHERE seivr.customerProduct=:cp")
                                       .setParameter("cp", customerProduct)
           public void duplicateIVR(SEIVRScript script)
                SEIVRScript s = new SEIVRScript();
           public void setIvrListForDup(List<SEIVR> ivrListForDup)
                this.ivrListForDup = ivrListForDup;
           public List<SEIVR> getIvrListForDup()
                return ivrListForDup;
           public void setSelectedIVRForDup(SEIVR selectedIVRForDup)
                this.selectedIVRForDup = selectedIVRForDup;
           public SEIVR getSelectedIVRForDup()
                return selectedIVRForDup;
           @Remove @Destroy
           public void destroy()

      What the heck am i doing wrong? Can anyone spot it?


        • 1. Re: h:selectOne returns null
          Chris Moerz Newbie

          Did you ever find a solution to this? I'm running into pretty much precisely the same problem. I get it running so far that the drop down is filled but it doesn't select the right element and it always results in Seam thinking that (null) was selected.

          The only reason my app isn't crashing is that I prevent null from being set on the specific @NotNull item.

          my components.xml

          <?xml version="1.0" encoding="UTF-8"?>
          <components xmlns="http://jboss.com/products/seam/components"
                          "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.1.xsd 
                           http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.1.xsd 
                           http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.1.xsd
                           http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.1.xsd
                           http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.1.xsd
                           http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.1.xsd
                           http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd">
             <core:init debug="@debug@" jndi-pattern="@jndiPattern@"/>
             <core:manager concurrent-request-timeout="500" 
             <persistence:managed-persistence-context name="entityManager"
             <security:rule-based-permission-resolver security-rules="#{securityRules}"/> 
             <!-- security:identity authenticate-method="#{authenticator.authenticate}" remember-me="true" /-->
             <!-- security:identity authenticate-method="#{identity.login}" remember-me="true" / -->
             <security:identity-manager identity-store="#{jpaIdentityStore}" />
             <security:jpa-identity-store name="jpaIdentityStore"
                       role-class="org.nycentral.hermes.entity.Role" />
                       user-permission-class="org.nycentral.hermes.entity.UserPermission" />
             <drools:rule-base name="securityRules">
             <event type="org.jboss.seam.security.notLoggedIn">
                <action execute="#{redirect.captureCurrentView}"/>
             <event type="org.jboss.seam.security.loginSuccessful">
                <action execute="#{redirect.returnToCapturedView}"/>
             <mail:mail-session host="localhost" port="2525" username="test" password="test" />
               <ui:jpa-entity-loader entity-manager="#{entityManager}" />
               <framework:entity-query name="allCountries" 
                    ejbql="select country from Country country" 
                    order="country.name" />        
             <!-- For use with jBPM pageflow or process management -->

          The data/entity I want to be rendered in the dropbox:

          package org.nycentral.hermes.entity;
          import java.io.Serializable;
          import javax.persistence.Entity;
          import javax.persistence.GeneratedValue;
          import javax.persistence.Id;
          import javax.persistence.Table;
          import javax.persistence.Transient;
          import org.hibernate.validator.Length;
          import org.hibernate.validator.NotNull;
          public class Country implements Serializable {
               private static final long serialVersionUID = -5515171854078135507L;
               //private String          id;
               private Long          id;
               private String          name;
               public Long getId() {
                    return this.id;
               public void setId( Long id ) {
                    this.id = id;
               public String getId() {
                    return id;
               public void setId(String id) {
                    this.id = id;
               public String getName() {
                    return name;
               public void setName(String name) {
                    this.name = name;
               public String toString() {
                    return this.name;
               public int hashCode() {
                    // FIXME non-optimal hash-code
                    return (this.id+this.name).hashCode();
               public boolean equals(Object o) {
                    Country     c;
                    if ( !( o instanceof Country )) {
                         return false;
                    c = (Country) o;
                    if ( c.getId() == this.getId() ) {
                         return true;
                    return false;

          I initially had a String as primary key and changed that to Long, just to be sure it's not caused by that. However, that didn't work either.

          The xhtml file rendering:

          <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
          <ui:composition xmlns="http://www.w3.org/1999/xhtml"
               <ui:define name="details">
                    <s:decorate id="fieldCompanyName" template="../layout/edit.xhtml">
                         <ui:define name="label">Name:</ui:define>
                         <h:inputText id="CompanyName" value="#{company.name}" required="true" />
                    <s:decorate id="fieldCompanyStreet" template="../layout/edit.xhtml">
                         <ui:define name="label">Street:</ui:define>
                         <h:inputText id="CompanyStreet" value="#{company.address.street}" required="true" />
                    <s:decorate id="fieldCompanyCity" template="../layout/edit.xhtml">
                         <ui:define name="label">City:</ui:define>
                         <h:inputText id="CompanyCity" value="#{company.address.city}" required="true" />
                    <s:decorate id="fieldCompanyZIP" template="../layout/edit.xhtml">
                         <ui:define name="label">ZIP:</ui:define>
                         <h:inputText id="CompanyZIP" value="#{company.address.zip}" required="true" />
                    <s:decorate id="fieldCompanyState" template="../layout/edit.xhtml">
                         <ui:define name="label">State:</ui:define>
                         <h:inputText id="CompanyState" value="#{company.address.state}" required="true" />
                    <s:decorate id="fieldCompanyCountry" template="../layout/edit.xhtml">
                         <ui:define name="label">Country:</ui:define>
                         <h:selectOneMenu id="CompanyCountry" value="#{company.address.country}">
                              <s:selectItems value="#{allCountries}" 
                                   hideNoSelectionLabel="true" />
                              <s:convertEntity />
               <ui:define name="actionButtons">
                    <h:commandButton value="Save Changes" action="#{companyEdit.saveCompany}" /> 
                    <h:commandButton value="Cancel" action="#{companyEdit.cancel}" />

          It's really weird. I don't understand why it's so damn difficult to render a stupid dropdown box??? I even tried to implement my own converter, that didn't work either:

          package org.nycentral.hermes.session.helper;
          import java.io.Serializable;
          import javax.faces.component.UIComponent;
          import javax.persistence.EntityManager;
          import org.jboss.seam.annotations.In;
          import org.jboss.seam.annotations.Name;
          import org.jboss.seam.annotations.Transactional;
          import org.jboss.seam.annotations.faces.Converter;
          import org.jboss.seam.faces.FacesContext;
          import org.nycentral.hermes.entity.Country;
          @Converter(forClass = Country.class)
          public class CountryConverter implements Serializable {
               private static final long serialVersionUID = 4329423846512375269L;
               private EntityManager entityManager;
               public Class<?> forClass() {
                    return Country.class;
               public Object getAsObject(FacesContext context, UIComponent component,
                         String value) {
                    if (value != null) {
                         try {
                              return entityManager.find(Country.class, Long.parseLong( value ));
                         } catch ( NumberFormatException e ) {
                              return null;
                    return null;
               public String getAsString(FacesContext context, UIComponent component,
                         Object value) {
                    if (value instanceof Country) {
                         Country c = (Country) value;
                         return c.getId().toString();
                    } else {
                         return null;

          That thing never gets called. I had a couple of breakpoints set - never was called at all. Does anyone have a clue what could be wrong with this??

          any help is really appreciated


          • 2. Re: h:selectOne returns null
            Binesh Gummadi Novice

            One reason that I can think of is it might be failing at validation phase. Do you see the same behavior if you fill in all required fields? I would say add a h:messages on top of your page with a4j:region around it and see the error messages. That might give you a clue. I don't see a h:form either but I guess you have it in your template.


            • 3. Re: h:selectOne returns null
              Chris Moerz Newbie

              I added a a4j and message segment as you suggested, but I didn't get any messages. So I guess my problem stems from some other area. To give you a better overview, I'll post a couple more things.

              First of all, here's the template, as you correctly assumed, my forms tag is in the template:

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <html xmlns="http://www.w3.org/1999/xhtml"
              <ui:composition template="../layout/template.xhtml">
                   <ui:define name="body">
                        <div class="section">
                        <rich:panel id="contactTable">
                             <f:facet name="header">#{messages['org.nycentral.labels.ContactData']}</f:facet>
                                  <h:messages />
                             <h:panelGrid columns="2">
                                  <ui:insert name="details" />
                        <div class="actionButtons">
                             <h:form id="manipulateForm">
                                  <ui:insert name="actionButtons" />

              And there's my updated stateful session bean that handles the whole thing:

              package org.nycentral.hermes.session;
              import static javax.ejb.TransactionAttributeType.REQUIRES_NEW;
              import static javax.persistence.PersistenceContextType.EXTENDED;
              import java.util.List;
              import javax.ejb.Remove;
              import javax.ejb.Stateful;
              import javax.ejb.TransactionAttribute;
              import javax.persistence.EntityManager;
              import javax.persistence.PersistenceContext;
              import org.jboss.seam.ScopeType;
              import org.jboss.seam.annotations.Begin;
              import org.jboss.seam.annotations.Create;
              import org.jboss.seam.annotations.Destroy;
              import org.jboss.seam.annotations.End;
              import org.jboss.seam.annotations.In;
              import org.jboss.seam.annotations.Logger;
              import org.jboss.seam.annotations.Name;
              import org.jboss.seam.annotations.Out;
              import org.jboss.seam.annotations.Scope;
              import org.jboss.seam.annotations.security.Restrict;
              import org.jboss.seam.core.Events;
              import org.jboss.seam.log.Log;
              import org.nycentral.hermes.entity.Company;
              import org.nycentral.hermes.entity.Country;
              // FIXME address doesn't show country when reloading or coming back to view screen
              // TODO try to add a string property and just use itemValue to get the listing of countries
              public class CompanyEditAction implements CompanyEdit {
                   private EntityManager          entityManager;
                   private Log                         log;
                   @In @Out
                   private Company                    company;
                   private List<Country>          countries;
                   private Events                     events;
                   public void init() {
                        /*if ( this.getCountrySelector() == null ) {
                             this.setCountrySelector( (CountrySelector) Component.getInstance( CountrySelector.class )); 
                        if ( this.getCountries() == null ) {
                             this.countries = entityManager.createQuery( "from Country" ).getResultList();
                        // transfer country id into helper variable
                        log.debug( this.getClass().getSimpleName() + " initialized." );
                   public void editCompany(Company company) {
                        this.company = company;
                        //this.getCountrySelector().setSelection( this.company.getAddress().getCountry().getId() );
                   public void saveCompany() {
                        log.debug( "Starting {0}.saveCompany()", this.getClass().getSimpleName() );
                        log.debug( "Company.address = {0}", this.getCompany().getAddress() );
                        log.debug( "Company.address.country = {0}", this.getCompany().getAddress().getCountry() );
                        //String selection = this.countrySelector.getSelection();
                        //log.debug( "Current string selection: {0}", selection );
                        //this.getCompany().getAddress().setCountry( this.countrySelector.getCountry() );
                        if ( this.getCompany().getAddress().getCountry() == null ) {
                             log.error( "Unable to select appropriate country entry on {0}", this.getCompany() );
                        entityManager.merge( this.getCompany() );
                   public Company getCompany() {
                        return this.company;
                   /*public Converter getCountryConverter() {
                        return new EntityConverter() {
                             private static final long serialVersionUID = -6412404845003367238L;
                             public String getAsString(FacesContext facesContext,
                                       UIComponent cmp, Object value) throws ConverterException {
                                  if ( value instanceof Country) {
                                       Country     c = (Country) value;
                                       return c.getId();
                                  return value+"";
                             public Object getAsObject(FacesContext facesContext,
                                       UIComponent cmp, String value) throws ConverterException {
                                  return em.find( Country.class, value );
                   public void cancel() {
                        log.debug( "{0} terminating.", this.getClass().getSimpleName() );
                   public List<Country> getCountries() {
                        return countries;

              This bean has the local interface:

              package org.nycentral.hermes.session;
              import java.util.List;
              import javax.ejb.Local;
              import org.nycentral.hermes.entity.Company;
              import org.nycentral.hermes.entity.Country;
              public interface CompanyEdit {
                   public void init();
                   public void cancel();
                   public void editCompany(Company company);
                   public void saveCompany();
                   public Company getCompany();
                   public List<Country> getCountries();

              I don't understand why this isn't working. It's really frustrating - I've been circling around the same issue for several days now and though everything is programmed the way it is required according to all the documentation and postings, it still doesn't work. It's just beyond me.

              Anyone able to help me? I'm totally lost.


              • 4. Re: h:selectOne returns null
                Chris Moerz Newbie

                I just figured it out, I believe. If you look closely at the template, I accidentally put the forms around the buttons only. That means, all the fields - including the dropdown box weren't inside the form and therefore didn't get transmitted.

                Duuuh! Thanks anyways for the reply!