3 Replies Latest reply on Oct 27, 2009 2:32 AM by kapitanpetko

    Injection Paradigms, what are the pros and cons?

    stormtag
      So, here's the deal. I'm playing with Seam and EJB for the first time in more than just a "for fun" kind of way. I'm building my first feature and I'm trying to get some better understanding of how things with Seam 2 and EJB 3 work behind the scenes so I can understand what is going on if/when the abstraction leaks. ;)

      I have a service layer, implemented largely as Stateless EJB Beans. They access a the database through JPA, send Email, kiss babies, whatever. They are there primarily to act as the domain layer.

      I have the controller layer, implemented largely as Stateful Seam/EJBs. These are usually pretty thin and are really only there to handle interaction between the view (Richfaces/JSF at current but will probably include a RESF endpoints in the not toooooo distant future) and my service layer.

      The question is should I be using Seam to manage dependency injection between my Service and Controller layers or would it make more sense to rely on EJB and the container's managed DI? So far I've gotten the Seam based DI to work correctly and haven't gotten the EJB/Container DI to work. I'm pretty certain that this is just because I haven't really figured out the right way to do the latter (and probably not doing the former quite the best way either!)

      I'm lucky in that my deadline isn't so crushing that I don't have a little time to make sure I'm doing this the right way, so whatever help I can get would be appreciated!

      Here's a quick example of what I'm talking about. I've left out the interfaces, which contain the public methods are annotated as @Local and nothing else

      This would be my (not-working) EJB/Container Injection. Run on JBoss AS 5.1

      @Stateless
      public class CoreServiceImpl implements CoreService {

          @PersistenceContext EntityManager entityManager;

          public List<_Product> getAllProducts() {
              return entityManager.createQuery("FROM _Product").getResultList();
          }
      }

      @Stateful
      @Name("frontPageController")
      public class FrontPageControllerImpl implements FrontPageController {

          @EJB private CoreService coreService;

          @DataModel private List<_Product> frontPageList;

          //...Constructor, getters, setters

          @Factory("frontPageList")
          public void prepFrontPageList() {
              frontPageList = coreService.getAllProducts();
          }
      }



      And here is the (working) Seam DI powered example. Run on JBoss AS 5.1

      @Stateless
      @Name("CoreServiceImpl")
      public class CoreServiceImpl implements CoreService {

          @In EntityManager entityManager;

          public List<_Product> getAllProducts() {
              return entityManager.createQuery("FROM _Product").getResultList();
          }
      }

      @Stateful
      @Name("frontPageController")
      public class FrontPageControllerImpl implements FrontPageController {

          @In(create=true, value="#{CoreServiceImpl}") private CoreService coreService;

          @DataModel private List<_Product> frontPageList;


          @Factory("frontPageList")
          public void prepFrontPageList() {
              frontPageList = coreService.getAllProducts();
          }
      }

      I don't really like having to add the EL to the @In but I guess there are worse things

      So the TL;DR version is, check out the above two classes.
      -Anyone see why my EJB version isn't working?
      -Assuming I can fix the EJB version, what are the pros and cons to each paradigm?
      -Not a lot of code there, but if it's obvious I'm doing something a sub-optimally way, let me know.

      For the note, in my spare time I may work on a JSF2, RichFaces4, Weld, Seam3, JPA and EJB3 stack implementaion so I can keep myself as cutting edge as possible but the production system is going to be on JSF1.2, RichFaces3, Seam2, JPA and EJB3. For now. ;)
        • 1. Re: Injection Paradigms, what are the pros and cons?
          kapitanpetko

          Drew Arrigoni wrote on Oct 26, 2009 05:22:


          -Anyone see why my EJB version isn't working?



          Not obvious, but @EJB without attributes only works if the EJB resolution is straightforward (only one bean with this business interface, etc.) Anything special about your setup?



          -Assuming I can fix the EJB version, what are the pros and cons to each paradigm?


          If you use @EJB you get to use JEE services only (interceptors, etc.). If you use @In you get to use Seam services.
          @PersistenceContext vs @In EntityManger is a different story, check the docs for Seam-managed PC (SMPC)

          • 2. Re: Injection Paradigms, what are the pros and cons?
            stormtag

            Nikolay Elenkov wrote on Oct 26, 2009 10:25:

            Not obvious, but @EJB without attributes only works if the EJB resolution is straightforward (only one bean with this business interface, etc.) Anything special about your setup?


            Nope. Those were the only two classes in the JAR file. Whenever I tried with the @EJB, it would deploy fine but when it got in the factory method, the service would be null and throw a null pointer.



            Nikolay Elenkov wrote on Oct 26, 2009 10:25:

            If you use @EJB you get to use JEE services only (interceptors, etc.). If you use @In you get to use Seam services.


            Are all the JEE services available if I use the Seam services? ie. Using Interceptors on Seam Injected beans?




            Nikolay Elenkov wrote on Oct 26, 2009 10:25:

            @PersistenceContext vs @In EntityManger is a different story, check the docs for Seam-managed PC (SMPC)


            Will do.

            • 3. Re: Injection Paradigms, what are the pros and cons?
              kapitanpetko

              Drew Arrigoni wrote on Oct 26, 2009 15:41:



              Nikolay Elenkov wrote on Oct 26, 2009 10:25:

              Not obvious, but @EJB without attributes only works if the EJB resolution is straightforward (only one bean with this business interface, etc.) Anything special about your setup?


              Nope. Those were the only two classes in the JAR file. Whenever I tried with the @EJB, it would deploy fine but when it got in the factory method, the service would be null and throw a null pointer.



              There must be something wrong with your setup then. Check your application.xml and ejb-jar.xml files. Is your EJB jar listed as an module/ejb in application.xml? Other than that you can try specifying mappedName on @EJB to see if this make a difference (use the JMX console to list JNDI)




              Nikolay Elenkov wrote on Oct 26, 2009 10:25:

              If you use @EJB you get to use JEE services only (interceptors, etc.). If you use @In you get to use Seam services.


              Are all the JEE services available if I use the Seam services? ie. Using Interceptors on Seam Injected beans?



              Yes, Seam interceptors are generally stacked on top of the JEE ones. If you are using EJB's, your best bet is to annotate them with @Name and inject with @In. That way you can get the best of both worlds.