6 Replies Latest reply on Feb 26, 2009 9:30 AM by amarkhel

    combobox using entities returning 'null' values

      Hello everybody,

      Let me start of by thanking those that actually take the effort of reading it all! I know it's a very long post.

      TLDR Version:
      I'm going a bit crazy over my inability to get the Combobox provided by RichFaces working with a list of Entities in combination with the convertentity option.
      It keeps on returning a 'null' value somehow.

      I've been busting my brain on this for over a week and googled 12.000lbs of CO2 into the air searching for a solution. So I turn to the forums.
      I would like to know if there is something I'm doing wrong. If there is another way of solving this. If it's a known bug.

      What I want to do:
      I've got an application that was generated using seam-gen, based on an existing database I've used in the past to supply a swing-application with data.
      The concept is that I wish to show a combobox (as described and exampled on the richfaces live demo site) with a list of my 'Speler' objects. Following a selection of one of the items in the combobox I wish to have the corresponding object behind it to be passed to a variable in my action bean behind it.
      I check this through the use of the logging tool supplied.

      The problem:
      I keep on getting a 'null' value that is returned to my action bean.

      What I have tried:
      1) created a custom entity converter and neither of the getAsString and getAsObject were being called

      2) used the convertentity and overridden the toString, hashCode and equals methods in my model bean

      3) used all different type of scopes: Session, Page, Conversation (just to check em all)

      Suffice to say, all to no avail.

      Development Environment:
      Eclipse Europa EE with JBossTools
      JBoss AS 4.2.3 GA
      Seam 2.1.1
      RichFaces 3.3.0 (previously tested with supplied RichFaces in Seam 2.1.1 with same results)

      The Code:

      Model / Entity Bean (remember this was created by seam-gen):

      // Generated 23-feb-2009 11:49:34 by Hibernate Tools 3.2.2.GA
      
      // package and import stuff left out
      
      /**
       * Speler generated by hbm2java
       */
      @Entity
      @Table(name = "speler", catalog = "saga", uniqueConstraints = @UniqueConstraint(columnNames = "login"))
      @Roles( { @Role(name = "loggedIn", scope = ScopeType.SESSION),
       @Role(name = "selectedSpeler", scope = ScopeType.SESSION) })
      public class Speler implements java.io.Serializable {
      
       private Long id;
       private String naam;
       private String paswoord;
       private String login;
       private String voornaam;
       private String role;
      
       public Speler() {
       }
      
       public Speler(String role) {
       this.role = role;
       }
      
       public Speler(String naam, String paswoord, String login, String voornaam,
       String role) {
       this.naam = naam;
       this.paswoord = paswoord;
       this.login = login;
       this.voornaam = voornaam;
       this.role = role;
       }
      //Getters & Setters left out
      


      Action Beans
      The Listingbean (created by seamGen)
      // package and import stuff left out
      
      @Name("spelerList")
      @Scope(ScopeType.PAGE)
      public class SpelerList extends EntityQuery<Speler> {
      
       private static final String EJBQL = "select speler from Speler speler";
      
       private static final String[] RESTRICTIONS = {
       "lower(speler.login) like concat(lower(#{spelerList.speler.login}),'%')",
       "lower(speler.naam) like concat(lower(#{spelerList.speler.naam}),'%')",
       "lower(speler.paswoord) like concat(lower(#{spelerList.speler.paswoord}),'%')",
       "lower(speler.role) like concat(lower(#{spelerList.speler.role}),'%')",
       "lower(speler.voornaam) like concat(lower(#{spelerList.speler.voornaam}),'%')",};
      
       private Speler speler = new Speler();
      
       public SpelerList() {
       setEjbql(EJBQL);
       setRestrictionExpressionStrings(Arrays.asList(RESTRICTIONS));
      // setMaxResults(25);
       }
      
       public Speler getSpeler() {
       return speler;
       }
      }
      


      Action bean behind the page (I wrote this thing)

      // package and import stuff left out
      
      @Name("spelerSelection")
      @Scope(ScopeType.SESSION)
      public class SpelerSelection
      {
       @Logger private Log log;
      
       @In StatusMessages statusMessages;
      
       Speler selectedSpeler;
      
       public void spelerSelection()
       {
       // implement your business logic here
       log.info("spelerSelection.spelerSelection() action called");
       log.info("SelectedSpeler = " + selectedSpeler);
       statusMessages.add("spelerSelection");
       }
      
       public void testSelection(Speler s) {
       log.info("Selection made in list: " + s);
       }
      
       public Speler getSelectedSpeler() {
       return selectedSpeler;
       }
      
       public void setSelectedSpeler(Speler selectedSpeler) {
       this.selectedSpeler = selectedSpeler;
       }
      
       // add additional action methods
      
      }
      


      The converter I wrote and use, for reference the log messages I put in are NEVER shown:

      // package and imports left out
      
      import sagacreator.model.Speler;
      
      @Name("spelerConverter")
      @org.jboss.seam.annotations.faces.Converter
      @BypassInterceptors
      public class SpelerConverter implements Converter {
      
       @Logger private Log log;
      
       @In List<Speler> spelerList;
      
       @Override
       public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
       log.debug("****************************************");
       log.debug("getAsObject Called with String = " + arg2);
       log.debug("****************************************");
       return null;
       }
      
       @Override
       public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
       log.debug("****************************************");
       log.debug("getAsObject Called with Object = " + arg2);
       log.debug("****************************************");
       String s = "";
       if (arg2 instanceof Speler) {
       Speler speler = (Speler) arg2;
       return speler.toString();
       }
       return null;
       }
      
      }
      



      the xhtml page (template used is the default one created by seamgen)

      <!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"
       xmlns:s="http://jboss.com/products/seam/taglib"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:rich="http://richfaces.org/rich"
       xmlns:a="http://richfaces.org/a4j" template="layout/template.xhtml">
      
       <ui:define name="body">
      
       <rich:panel>
       <f:facet name="header">spelerSelection</f:facet>
      
       <h:form id="spelerSelectionForm">
       <rich:comboBox selectFirstOnUpdate="false"
       defaultLabel="Type the first few letters..."
       value="#{spelerSelection.selectedSpeler}"
       converter="#{spelerConverter}">
       <s:selectItems var="_selectedSpeler" value="#{spelerList}" />
       </rich:comboBox>
      
       <h:commandButton id="spelerSelection" value="spelerSelection!"
       action="#{spelerSelection.spelerSelection}" />
      
       </h:form>
      
       </rich:panel>
      
       </ui:define>
      
      </ui:composition>
      


      Console output:
      On Page loading:

      15:40:21,406 INFO [STDOUT] Hibernate:
       select
       speler0_.ID as ID14_,
       speler0_.ROLE as ROLE14_,
       speler0_.PASWOORD as PASWOORD14_,
       speler0_.NAAM as NAAM14_,
       speler0_.login as login14_,
       speler0_.VOORNAAM as VOORNAAM14_
       from
       saga.speler speler0_
      


      On button click:

      15:41:38,000 INFO [SpelerSelection] spelerSelection.spelerSelection() action called
      15:41:38,000 INFO [SpelerSelection] SelectedSpeler = null
      



      I hope I was clear enough in my problem description! (and please excuse any mistakes I made in my english, I'm native dutch speaking :) )

      A duplicate of this post is made on the Seam Framework Forums.

      Thanks in advance for ANY help that is provided!

      regards,
      Pieter







        • 1. Re: combobox using entities returning 'null' values
          nbelaevski

          Hi Pieter,

          I guess converter messages are not printed because they have debug log level. Have you enabled it?

          Also the problem can be in this code part:

          @Override
           public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
           log.debug("****************************************");
           log.debug("getAsObject Called with String = " + arg2);
           log.debug("****************************************");
           return null;
           }


          Try returning non-null item.

          • 2. Re: combobox using entities returning 'null' values

             

            "nbelaevski" wrote:
            Hi Pieter,

            I guess converter messages are not printed because they have debug log level. Have you enabled it?

            Also the problem can be in this code part:
            @Override
             public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
             log.debug("****************************************");
             log.debug("getAsObject Called with String = " + arg2);
             log.debug("****************************************");
             return null;
             }


            Try returning non-null item.


            *facepalm*
            I switched the log to .info and poof, I got to see the messages...
            God, how silly things can drive you crazy.

            Thanks!

            So anyways, I modified the getAsObject method so it searched in my List for the entry that I selected (I see the String arg2, am able to manipulate it so I can use it)

            But now it seems that my 'spelerList' (the one that is injected) keeps turning out to be a 'null' object.

            I'm confused at this point, I USE the spelerList in my xhtml page, it is SessionScoped (well not in the code example, but in my tested code here on my pc).
            Furthermore, I thought I understood the @In annotation as being: if an object with said name is found in the context and it's initialized it will be injected, if it's not found, but it can be created it will be created.

            Or am I mistaken once again?

            • 3. Re: combobox using entities returning 'null' values
              amarkhel

               

              import sagacreator.model.Speler;
              
              @Name("spelerConverter")
              @org.jboss.seam.annotations.faces.Converter
              @BypassInterceptors
              public class SpelerConverter implements Converter {
              


              In your converter you use @BypassInterceptors annotation, that's purpose - is disabling Seam-interceptors and BijectionInterceptor too.. So no injections occured, may be problem there?

              • 4. Re: combobox using entities returning 'null' values

                 

                "amarkhel" wrote:
                import sagacreator.model.Speler;
                
                @Name("spelerConverter")
                @org.jboss.seam.annotations.faces.Converter
                @BypassInterceptors
                public class SpelerConverter implements Converter {
                


                In your converter you use @BypassInterceptors annotation, that's purpose - is disabling Seam-interceptors and BijectionInterceptor too.. So no injections occured, may be problem there?


                • 5. Re: combobox using entities returning 'null' values

                  Sorry for the double posting :( had a double closing tag on the quote and it ate my reply...

                  "amarkhel" wrote:
                  import sagacreator.model.Speler;
                  
                  @Name("spelerConverter")
                  @org.jboss.seam.annotations.faces.Converter
                  @BypassInterceptors
                  public class SpelerConverter implements Converter {
                  


                  In your converter you use @BypassInterceptors annotation, that's purpose - is disabling Seam-interceptors and BijectionInterceptor too.. So no injections occured, may be problem there?


                  I follow your logic, yet fail to see the logic in it...

                  The @BypassInterceptors annotation is necessary for a converter, otherwise it won't register in the seam context (unless I'm completely wrong on this)

                  But on the other hand that same annotation prohibits any and all bijection?

                  If that is the case, how are you able to write the 'getAsObject' method then?
                  I'm completely lost atm tbh...

                  • 6. Re: combobox using entities returning 'null' values
                    amarkhel

                    Please, Try this

                    import org.jboss.seam.annotations.faces.Converter;
                    ...
                    @Name("spelerConverter")
                    @Converter
                    @BypassInterceptors
                    public class SpelerConverter implements Converter {
                    
                    private static Log logger = Logging.getLog( SpelerConverter.class );
                    private List<Speler> spelerList = (List<Speler>) Component.getInstance( "spelerList" ) ;