2 Replies Latest reply on Dec 27, 2011 6:03 AM by Bram Biesbrouck

    CDI and polymorphic producer methods

    Bram Biesbrouck Newbie

      Hi all,


      I'm encountering a problem with a quite common EJB pattern in the J2EE6 world and I was hoping to find an answer here...


      I have three entity beans that implement a common interface. On top of the methods of the interface, each bean has a few more custom methods too.


      When I use a polymorphic producer method (see below) that selects the correct implementation, everything works fine, but the custom properties of each bean get hidden behind the interface so I get a WeldClientProxy does not have the property  ... exception when I try to access the property from JSF:



      @Produces
      @Selected
      @Named
      @RequestScoped
      public Target getSelectedTarget()
      {...}
      



      It seems like the return type of the producer method (here, Target) is polymorphic, but blocks access to the (possible) custom properties of that specific implementation.


      This only happens when the return type is wrapped in a proxy method (so every scope but @Dependent), so my current workaround is to mark the manager bean @RequestScoped and use a factory method like


      @RequestScoped
      public class TargetManager
      {
          public Target getSelectedTarget()
          {     
              if (this.selectedTarget==null) {
                  ...
              }
      
              return this.selectedTarget;
          }
      }
      



      This works fine, but since the returned bean won't be wrapped in a proxy class, I wonder what the differences are between the two approaches.


      I guess this is a quite common pattern and very flexible to use, so maybe this can help out other developers too. Any way, all help or insight is highly appreciated.


      regards,


      bram

        • 1. Re: CDI and polymorphic producer methods
          Guido Bonazza Newbie

          Hi Bram,


          Please don't take it bad, but I think that your pattern is actually an anti-pattern: should you use your Target in Java code, you would use some instanceof to access properties and methods from different implementations, which means that you are breaking OO good practices; the fact that you do this in a more natural way because EL is non-type safe is not a real excuse. That said, I admit that I've also used this pattern quite a lot, especially with entities, having similar problems with Hibernate's proxies :P


          Depending on the case, I would enrich the Target interface to satisfy all the needs of the page, or I would use alternative JSF script chunks to address each specific Target implementation (using... well... some kind of instanceof on the page side).


          I hope this helps...

          • 2. Re: CDI and polymorphic producer methods
            Bram Biesbrouck Newbie

            Hi Guido,


            (sorry for this - way - overdue reply)


            You're right, I guess. It's painfully easy to access the non-accessible method/properties outside of the interface, which is why I've grown accustomed to use it as a pattern. Thanks for the insight.


            b.