3 Replies Latest reply on Mar 18, 2009 2:02 PM by mkoperski

    s:convertEntity null objects

    mkoperski

      Hi I ve faced such problem.
      I had entity bean called Order it contains entity bean Client.
      When you make order you need to select client via selectOneMenu.
      Ofcourse I overidden hashcode and equals methods in Client.
      But when I want to edit order the client bounded to order is not selected, but I had
      default value of selectOneMenu - 'please select...'.


      I made some investigation and I found that equals method is invoked on current client object
      as many times as we have available clients to select. But the parameter of equals method is always NULL so method return value false. This is the reason why none value is selected in selectOneMenu.


      What I ve found more that such situation occurs when Client object is a part of entity bean fetched from DB - propably it is a proxy object. When I construct Order via constructor and set client to it via setClient method and Client was constructed via constructor everything works fine.


      I think that the problem is somewhere in s:convertentity so it cannot fetch proper instances form db having proxy object. But I am not sure. And I have no idea how to overcome this problem.



      Regards

        • 1. Re: s:convertEntity null objects
          joblini

          Try writing your own converter, here is an example:


          @Name("fooConverter") 
          @BypassInterceptors 
          @Converter
          public class FooConverter implements Converter {
             
            @Transactional
            public Object getAsObject(FacesContext context, UIComponent cmp, String value) {
              EntityManager entityManager = (EntityManager) Component.getInstance("entityManager");
              entityManager.joinTransaction();
              // Do the conversion
            }
            
            public String getAsString(FacesContext context, UIComponent cmp, Object value) {
              // Do the conversion
            }
            
          }


          • 2. Re: s:convertEntity null objects
            mkoperski

            Nope it is not working.
            It is very strange for me. Cause as I said there is no problem with list with clients they are fetched from DB, but when bounded object is proxy there is a problem that parameters are null in equals method. For me a little bit illogical. That depends if bounded object is proxy or not affect list of objects in selectOneMenu.


            The only one solution I ve found is to read client bounded to Order construct new Client via constructor and set it to Order again. It s not very elegant solution.

            • 3. Re: s:convertEntity null objects
              mkoperski

              OK Finally I have found solution.


              If You take a look to class:
              com.sun.faces.renderkit.html basic.MenuRenderer
              (jsf-impl.jar version 1.2 04 which comes with JBoss 4.2.2.GA)
              on line 535 We ve got such piece of code:


              try {
                 newValue = context.getApplication().getExpressionFactory().
                 coerceToType(itemValue, type);
               } catch (Exception e) {
                 // this should catch an ELException, but there is a bug
                 // in ExpressionFactory.coerceToType() in GF
                 newValue = null;
              }



              The problem is that when type is proxy object class method coerceToType throws excpetion which is silently catched and newValue is null. This is the reason of null parameters in equals method that I mentioned.


              Ok that is the diagnosis now the solution: I did something like this:


              1. I ve added method getObjectClass to MenuRenderer:


                   private Class getObjectClass(Object o) {
                        Class r = o.getClass();
                        if (r.getName().contains("$$")) {
                             r = r.getSuperclass();
                        }
                        return r;
                   }


              2. And modify line 535 like this


              try {
                 type = getObjectClass(itemValue);
                 newValue = context.getApplication().getExpressionFactory().
                 coerceToType(itemValue, type);
               } catch (Exception e) {
                 // this should catch an ELException, but there is a bug
                 // in ExpressionFactory.coerceToType() in GF
                 newValue = null;
              }



              I ve based my solution on this post.
              And I addiotionaly modified method getCurrentSelectedValues as mentioned in the post above.


              Concusion is that the problem occurs in JSF implemmentation. I am not sure but maybe upgrade to newest version of JSF impl will help but I did not have time to check it.