11 Replies Latest reply on Jan 20, 2010 6:40 AM by gavin.king

    CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?

      I have a Junit-driven test that uses the embeddable EJB container to perform an integration test of an EJB. The Stateless EJB invokes a CDI bean (DAO) that has an..


      @Inject EntityManager em;


      Then there is another (utility) CDI bean that defines a producer field for the persistence context:


      public class Resources {
              @Produces @PersistenceContext
              EntityManager em;
      }


      With this set-up, the embeddable container (RI) reports:



      Unable to retrieve EntityManagerFactory for unitName null

      If I change the DAO to a @Stateless EJB, test fails with:


      WELD-000044 Unable to obtain instance from org.jboss.weld.bean-/...Resources.em


      If I remove the Resource class above, and define the persistence context in the dao (CDI bean), like this:


              @PersistenceContext
              protected EntityManager em;
      ...I get the following error:



      Unable to retrieve EntityManagerFactory for unitName null

      What finally makes the test run clean, is to declare the DAO as @Stateless.


      To my understanding, all the variations listed above should be valid. From my tests with the embeddable EJB container, it seems the integration of EJB 3.0 Light and CDI as described in chapter 3.5.1. Declaring a resource has yet to be implemented?


        • 1. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?
          meetoblivion

          I'm inclined to say it's a scoping issue.  Is your persistence.xml in the same jar as the test? As the Resources class?


          Every situation I've seen something like this, the unitName was specified.  I can only conclude that the unitName being specified is required due to scoping conflicts (if we're dealing with something that's multi-module)

          • 2. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?

            It is a single module and all classes are in src/main/java except the test case, which is in src/test/java. persistence.xml is in src/main/resources. Unfortunately, the embeddable container does not allow any other set up, according to my experience.


            Regarding lack of unitName: I've now run the cases with unitName specified. It made the trick. All cases worked. Thanks!!

            • 3. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?

              Another observation I have problems to understand:


              Now that there is a...




              @Produces PersistenceContext(unitName="...") EntityManager em





              then..




              @Inject EntityManager em




              ...only works for EJBs that have an interface. If the EJB does not extend a business interface, I have to use ...




              @PersistenceContext EntityManager em





              ...in the EJB implementation class


              Is that by spec?


              /Johan

              • 4. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?
                meetoblivion

                injection should be happening the same way, regardless of the injection point being owned by an EJB or a ManagedBean.  There should not be a difference between a @LocalBean and a @Local session bean. 


                what container are you using to test this? it sounds almost like it doesn't support @LocalBean style.

                • 5. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?

                  This works:


                  public class OrderServiceImpl implements OrderService {
                       @Resource EJBContext ctx;
                       //@PersistenceContext
                       @Inject
                       EntityManager em;
                       
                       public CustomerOrder createCustomerOrder(String artno, int items) throws NotSupportedException, SystemException {
                            ...
                       }
                  }


                  This doesn't:


                  public class OrderServiceImpl {
                       @Resource EJBContext ctx;
                       //@PersistenceContext
                       @Inject
                       EntityManager em;
                       
                       public CustomerOrder createCustomerOrder(String artno, int items) throws NotSupportedException, SystemException {
                            ...
                       }
                  }


                  While this does work:


                  public class OrderServiceImpl {
                       @Resource EJBContext ctx;
                       @PersistenceContext
                       //@Inject
                       EntityManager em;
                       
                       public CustomerOrder createCustomerOrder(String artno, int items) throws NotSupportedException, SystemException {
                            ...
                       }
                  }



                  Container is the RI Embeddable EJB container (e.g. Glassfish embeddable 3.0)

                  • 6. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?

                    After some more testing, my conclusion is another (sorry about that):
                    For...


                    @Inject EntityManager


                    to work in the only container I've tested (the Java EE 6 RI implementation of embeddable EJB container, i.e Glassfish 3), the followimg rules seem to apply:


                    - There need to be a producer (this is by spec), like this;


                    @Produces @PersistenceContext(unitName="...") EntityManager em;



                    At least one managed bean (CDI bean) MUST use...


                    @PersistenceContext EntityManager em;



                    ...rather than @Inject. Then all other beans may use...


                    @Inject EntityManager em;



                    It doesn't matter whether that the bean using...


                    @PersistenceContext EntityManager em;


                    ...is on the call path  or not (or - in case it is - where it is on the call path) - it just needs to be in the archive. So there need to be a producer that must name the persistence unit and there must be a CDI bean that uses the PersistenceContext annotation to inject an EntityManager. When these two pre-reqs are fulfilled, all other CDI beans may inject entity managers using the Inject-annotation.


                    /Johan

                    • 7. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?

                      Issue created on Glassfish EJB container: My Link

                      • 8. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?
                        meetoblivion

                        I am a bit confused - are you saying that in addition to the managed bean that has the producer, you need to have in a second location a reference using @PersistenceContext ?

                        • 9. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?

                          Me too :) Yes, I've elaborated a zillion of combinations. I've not been able to get a working sample with only a producer and an injection point for an EntityManager.

                          • 10. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?
                            meetoblivion

                            So I haven't tried it yet, it's on my to do for a project I'm working on, but try in your producer like this (I'm thinking you're using a field producer and weld's getting confused, but correct me if i'm wrong).




                            //this all goes in one class
                            @PersistenceContext(unitName="yourPU") EntityManager em;
                            @Produces @YourPU
                            public EntityManager produceYourPUEM() {
                            return em;
                            }
                            



                            • 11. Re: CDI spec "3.5.1. Declaring a resource" does not seem to work in RI?
                              gavin.king

                              Definitely sounds like a GlassFish bug, not a Weld bug.