12 Replies Latest reply on Jul 1, 2015 3:23 AM by Roger Lee

    Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB

    Roger Lee Apprentice

      I'm porting a live JBoss 6.1, RichFaces 3.x & Seam 2.x application to:

       

      JBoss WildFly 8.2, RichFaces 4.5.1 & JBoss Weld 2.2

       

      I'm having trouble retrieving the selected value from a RichFaces selectOneMenu, which I need to select the values for the second selectOneMenu list,

       

      My first selectOneMenu is populated with two rows from the database using @Produces


      I have it working in all my Seam applications, but in the Weld CDI application it's returning 'null'.

       

      XHTML

       

      <code>

      <h:selectOneMenu value="#{selectedAwcat}" valueChangeListener="#{categoriesBean.selectedAwcatChanged}">

        <f:selectItems value="#{categoriesBean.awcatsList}" var='awCat' itemValue="${awCat.awcat}" itemLabel="#{awCat.awcat}" />

        <f:converter converterId="awcatConverter" />

        <a4j:ajax event="valueChange" execute="@this" />

      </h:selectOneMenu>

      </code>


      My EJB

       

      <code>

      @Stateless
      @Named("categoriesBean")

      public class CategoriesBean implements CategoriesLocal {

       

          ...........

       

          @Inject
          private Awcat selectedAwcat;

       

          @Produces
          public List<Awcat> getAwcatsList() {

                .....

       

                return return awcatList;

          }

       

          /**
            *
            *  @param awcat
            * /
          public void setSelectedAwcat(Awcat selectedAwcat) {

                  this.selectedAwcat = selectedAwcat;

          }

       

          /**
            *
            * @return
            */
          public Awcat getSelectedAwcat() {

                  return this.selectedAwcat;

          }

       

          /**
              *
            */
          public void selectedAwcatChanged() {

                  logger.info(">>>>> selectedAwcatChanged selectedAwcat == " + this.selectedAwcat.getAwcat());

          }

      </code>


      AwCat is an Entity bean:


      <code>

      public class Awcat implements Serializable {

      }

      <code>


      I also wrote a customer converter


      <code>

      @FacesConverter("awcatConverter")

      public class AwCatConverter implements Converter {

       

        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {

        System.out.println(">>>>> AwCatConverter s = " + s);

       

        Awcat awcat = new Awcat();

        awcat.setAwcat(s);

        //return null;
        return awcat;

        }

       

        @Override
        public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) {

        System.out.println(">>>>> AwCatConvçerter getAsString o = " + o.toString());

       

        //return null;
        return o.toString();

        }

      }

      <code>

       

      In Seam I used:


      <s:convertEntity/>

       

      The JBoss WildFly console shows:

       

      12:17:31,487 INFO  [com.nohagl.ejb.CategoriesBean] (default task-128) >>>>> getAwcatsList .....

      12:17:31,489 INFO  [com.nohagl.ejb.CategoriesBean] (default task-128) >>>>> getAwcatsList awcatList = 2

      12:17:31,489 INFO  [stdout] (default task-128) >>>>> AwCatConvçerter  getAsString o = Cycling

      12:17:31,490 INFO  [stdout] (default task-128) >>>>> AwCatConvçerter  getAsString o = Motorcycling

      12:17:35,042 INFO  [stdout] (default task-15) >>>>> AwCatConverter  s = Motorcycling

      12:17:35,043 INFO  [com.nohagl.ejb.CategoriesBean] (default task-15) >>>>> getAwcatsList .....

      12:17:35,043 INFO  [com.nohagl.ejb.CategoriesBean] (default task-15) >>>>> getAwcatsList awcatList = 2

      12:17:35,044 INFO  [stdout] (default task-15) >>>>> AwCatConverter  s = Cycling

      12:17:35,044 INFO  [stdout] (default task-15) >>>>> AwCatConverter  s = Motorcycling

      12:17:35,045 INFO  [com.nohagl.ejb.CategoriesBean] (default task-15) >>>>> getAwcatsList .....

      12:17:35,045 INFO  [com.nohagl.ejb.CategoriesBean] (default task-15) >>>>> getAwcatsList awcatList = 2

      12:17:35,045 INFO  [stdout] (default task-15) >>>>> AwCatConverter  s = Cycling

      12:17:35,045 INFO  [stdout] (default task-15) >>>>> AwCatConverter  s = Motorcycling

      12:17:35,047 INFO  [com.nohagl.ejb.CategoriesBean] (default task-15) >>>>> selectedAwcatChanged selectedAwcat == null


      I can't get my head around what I'm doing wrong. Any pointers greatly received.


      N.B. For many reasons I want to use EJB as my 'backing' beans, unless I've misunderstood the spec this is possible.

        • 1. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
          Tomas Remes Expert

          Hi Roger,

           

          I guess you don't need to specify "Produces" annotation on your list getter ( in other words: producing new managed bean) when you acces the value by "#{categoriesBean.awcatsList}".  How is the list created/filled? 

          • 2. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
            Roger Lee Apprentice

            The @Produces is needed to create the list to populate the selectOneMenu? It's the replacement annotation for the Seam @Factory. This part is working fine:

             

            @Produces
            public List<Awcat> getAwcatsList() {

               logger.info(">>>>> getAwcatsList .....");

             

              TypedQuery<Awcat> awcatTypedQuery = entityManager.createNamedQuery("Awcat.findAll", Awcat.class);

             

               //List<Awcat> awcatList = null;
               this.awcatList = null;

               try {

               awcatList = awcatTypedQuery.getResultList();

              } catch (NoResultException nre) {

              }

             

               logger.info(">>>>> getAwcatsList awcatList = " + awcatList.size());

             

               return awcatList;

            }

             

            Gives:

             

            13:11:53,292 INFO  [com.nohagl.ejb.CategoriesBean] (default task-3) >>>>> getAwcatsList .....

            13:11:53,306 INFO  [com.nohagl.ejb.CategoriesBean] (default task-3) >>>>> getAwcatsList awcatList = 2

            13:11:53,309 INFO  [stdout] (default task-3) >>>>> AwCatConvçerter  getAsString o = Cycling

            13:11:53,309 INFO  [stdout] (default task-3) >>>>> AwCatConvçerter  getAsString o = Motorcycling

            • 3. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
              Tomas Remes Expert

              Ok I misunderstood your problem. So there is no Awcat instance during valueChangeListener  call. Can you provide some basic reproducer?  

              • 4. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
                Roger Lee Apprentice

                Tomas,

                 

                The selectedAwcat object is null, though I create it in the custom converter:


                EJB:

                @Inject
                private Awcat selectedAwcat;



                <f:converter converterId="awcatConverter" />


                @FacesConverter("awcatConverter")

                public class AwCatConverter implements Converter {

                 

                  @Override
                  public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {

                  System.out.println(">>>>> AwCatConverter s = " + s);

                 

                Awcat selectedAwcat = new Awcat();

                  selectedAwcat.setAwcat(s);

                  return selectedAwcat;

                  }

                 

                  @Override
                  public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) {

                  System.out.println(">>>>> AwCatConvçerter getAsString o = " + o.toString());

                 

                  //return null;
                  return o.toString();

                  }

                }

                 

                Have just noticed that in the 'logger' from the custom converter that the selected value from the selectedOneMenu is displayed but then goes all awry:

                 

                14:01:10,305 INFO  [stdout] (default task-42) >>>>> AwCatConvçerter  getAsString o = Cycling

                14:01:10,306 INFO  [stdout] (default task-42) >>>>> AwCatConvçerter  getAsString o = Motorcycling

                14:01:13,379 INFO  [stdout] (default task-53) >>>>> AwCatConverter  s = Motorcycling

                14:01:13,380 INFO  [com.nohagl.ejb.CategoriesBean] (default task-53) >>>>> getAwcatsList .....

                14:01:13,381 INFO  [com.nohagl.ejb.CategoriesBean] (default task-53) >>>>> getAwcatsList awcatList = 2

                14:01:13,381 INFO  [stdout] (default task-53) >>>>> AwCatConverter  s = Cycling

                14:01:13,381 INFO  [stdout] (default task-53) >>>>> AwCatConverter  s = Motorcycling

                14:01:13,382 INFO  [com.nohagl.ejb.CategoriesBean] (default task-53) >>>>> getAwcatsList .....

                14:01:13,382 INFO  [com.nohagl.ejb.CategoriesBean] (default task-53) >>>>> getAwcatsList awcatList = 2

                14:01:13,383 INFO  [stdout] (default task-53) >>>>> AwCatConverter  s = Cycling

                14:01:13,383 INFO  [stdout] (default task-53) >>>>> AwCatConverter  s = Motorcycling

                14:01:13,384 INFO  [com.nohagl.ejb.CategoriesBean] (default task-53) >>>>> selectedAwcatChanged selectedAwcat == null

                 

                Even though I create & set the value in selectedAwcat it's still null when it's returned I thought by naming it in the XHTML and annotating in the EJB it would inject it with the newly created and 'set' object?

                • 5. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
                  Tomas Remes Expert

                  Yes I know. The selectedAwcat is null (after setting) because it's not managed by CDI.  It seems to me little bit complicated that's why I asked for reproducer.

                  • 6. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
                    Roger Lee Apprentice

                    Tomas,

                     

                    What do you mean by "reproducer"? My source?

                    • 7. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
                      Tomas Remes Expert

                      Yes. The WAR archive you are deploying to WildFly along with the source code if possible...

                      • 8. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
                        Roger Lee Apprentice

                        Tomas,

                         

                        I appreciate you're trying to help but the EAR is 24 Mb. and requires a MySQL database to connect to. Also the product is subject to a NDA.

                         

                        Have you used RichFaces SelectOneMenu with an EJB?

                         

                        Thanks

                        • 9. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
                          Tomas Remes Expert

                          Well I don't know RichFaces (always used plain JSF) but I used selectOneRadio where I simply bound selected value to integer attribute of some bean. I guess there is no default mechanism (in RichFaces) which will create CDI managed bean instance (selectedAwcat in your case) based on UI action like selecting some value. 

                          • 10. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
                            Roger Lee Apprentice

                            It is, just a plain old JSF 2 component in this instance,

                             

                            <h:selectOneMenu value="#{selectedAwcat}" valueChangeListener="#{categoriesBean.selectedAwcatChanged}">


                            I've injected JSF 2 & RichFaces component's values into EJBs using Seam with no issues. Will have a look at the source of the Seam taglib <s:convertEntity> to see is I'm missing something in my customer converter.


                            I can see my selected value from the 'selectOneMenu' in the logging of my custom converter so the issue may be there.



                            • 11. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
                              Tomas Remes Expert

                              Yes the selected value you are seeing is just String and then you are doing:

                              Awcat selectedAwcat = new Awcat();

                                selectedAwcat.setAwcat(s);

                                return selectedAwcat;

                              CDI is not aware of this newly created instance that's why you cannot injected with "@Inject Awcat selectedAwcat". You will need to create producer method (Weld 2.2.14.Final - CDI Reference Implementation) to become Awcat available for injection, however I am not sure if the FacesConverter is best class for placing this new producer.  

                              1 of 1 people found this helpful
                              • 12. Re: Injecting 'selected' value from RichFaces 'selectOneMenu' into an EJB
                                Roger Lee Apprentice

                                Tomas,

                                 

                                Thanks for that suggestion. I misunderstood and thought that @Produces was just a replacement for Seam's @Factory and could only be used only on a method.

                                 

                                In my EJB I changed the annotation to Awcat to:

                                 

                                @Produces
                                private static Awcat selectedAwcat;

                                 

                                and now Awcat is injected from the XHTML with the value selected:

                                 

                                08:08:51,364 INFO  [com.nohagl.ejb.CategoriesBean] (default task-16) >>>>> selectedAwcatChanged selectedAwcat == com.nohagl.entities.Awcat[ awcat=Cycling ]

                                 

                                I've also removed my custom converter.

                                 

                                Many thanks for all your help.

                                 

                                 

                                - See more at: https://developer.jboss.org/message/934970#934970