13 Replies Latest reply on Oct 12, 2007 4:27 PM by Pete Muir

    Re-working EJB Extended Context To Use SMPC - Need Help

    Curtney Jacobs Newbie

      I have a read number of posts that indicates it is possible to have the following architecture listed below, however, putting @Name on the abstract class throws an IllegalArgumentException. If I remove @Name annotation from the abstract class, then my entityManager is null; it does not get injected.

      @Name("genericdao");
      public abstract MyBase <T, ID extends Serializable> implements mybaseInterface <T, ID> {
      
      @In
      protected EntityManager entityManager;
      }
      
      
      @Stateless
      @TransactionAttribute (TransactionAttributeType.REQUIRED)
      @Name ("bean1")
      public class Bean1 extends MyBase <Entity, ID> implements Bean1Interface {
      
      //do some dao acess here
      }
      
      @Stateful
      @Name ("bean2")
      public class Bean2 implements Bean2Interface {
      
      //I have commented this in and out, does not make a difference.
      @In private EntityManager entityManager;
      
      @In
      Bean1 bean1
      
      //use bean1 to do dao stuff, persist, remove, refresh, etc.
      
      }


      component.xml has the following:
      <persistence:managed-persistence-context name="entityManager" auto-create="true"
       persistence-unit-jndi-name="java:/myEntityManagerFactory"/>


      persistence.xml has the following:
      ....
      <persistence-unit name="myDatabase">
       <provider>org.hibernate.ejb.HibernatePersistence</provider>
       <jta-data-source>java:/DefaultDS</jta-data-source>
       <jar-file>../my-common.jar</jar-file>
       <jar-file>../my-party.jar</jar-file>
       <jar-file>../my-security.jar</jar-file>
       ......
       <properties>
       .....
       <property name="jboss.entity.manager.factory.jndi.name" value="java:/myEntityManagerFactory"/>
      ....
      </persistence-unit>
      ....

      I am trying to re-work my EJB style extended persistence context to use SMPC. Where
      I had @PersistenceContext to inject entityManager and @EJB to inject the beans. However swithching to @In to inject entityManager and my beans does not work.

      Please help, I have being reading old posts all knight long, and unable to get this to work. I am sure I am missing something obvious.



        • 1. Re: Re-working EJB Extended Context To Use SMPC - Need Help
          Matt Drees Master

          Does SMPC injection work for non-hierarchical components?

          • 2. Re: Re-working EJB Extended Context To Use SMPC - Need Help
            Curtney Jacobs Newbie

            Yes, it works for non-hierarchical components. I forgot to mention that. Is there a reason why it doesn't go down the chain? Can it?

            • 3. Re: Re-working EJB Extended Context To Use SMPC - Need Help
              Matt Drees Master

              That's odd. I'm fairly certain it ought to work for (non-@Named) superclasses. I know it does for JavaBean components, anyway (I don't yet need to live in EJB land), and I can see that Component.initMembers() (which looks for injectable attributes) doesn't seem to care whether it's a JavaBean or an EJB.

              I guess you'll have to do some debugging to figure out why it's not working.

              • 4. Re: Re-working EJB Extended Context To Use SMPC - Need Help
                Matt Drees Master

                Are you trying to use the entityManager in a lifecycle method when a conversation context is not active (i.e RestoreView)?

                • 5. Re: Re-working EJB Extended Context To Use SMPC - Need Help
                  Curtney Jacobs Newbie

                  I have been reading the Seam reference document and I am going to abandoned this approach and looked into extending EntityHome (Seam framework class), instead of creating my own base class. I believe my problem is my base abstract class. I cannot annotate it with @Name, thus unable to inject the entity manager. Besides, EntityHome might be what I am looking for in that I can have a one-to-one correspodence between my domain object and mechanism that stores it.

                  public MyDomainObjectRepositoryImpl extends EntityHome <MyDomain> impements MyDomainRepository {}


                  However, it sucks that I cannot parameterize the domain ID as well, similar to my base abstract class.

                  Thanks for your suggestions,

                  Curtney


                  • 6. Re: Re-working EJB Extended Context To Use SMPC - Need Help
                    Matt Drees Master

                     

                    "curtney" wrote:
                    I cannot annotate it with @Name, thus unable to inject the entity manager


                    I really don't think that's a valid conclusion. It is true you can't/shouldn't annotate it with @Name, but concrete implementations should get injection anyway. (Someone correct me if I'm wrong)

                    If you can reproduce this in a simple test case, you can raise a Jira issue and I'm sure someone will look into it. If there is a bug, the Seam community would appreciate knowing about it. :-)

                    As far as parameterized IDs, maybe you could do something like:
                    public class MyBase<T, ID extends Serializable> extends EntityHome<T> {
                    
                     @Override
                     public ID getId() {
                     return (ID) super.getId();
                     }
                    
                     public void setId(ID id) {
                     super.setId(id);
                     }
                    
                     @Override
                     public void setId(Object id) {
                     throw new UnsupportedOperationException("Not correct type:" +id.getClass());
                     }
                    }


                    • 7. Re: Re-working EJB Extended Context To Use SMPC - Need Help
                      Curtney Jacobs Newbie

                       

                      ...concrete implementations should get injection anyway.


                      That is what I thought, however it was not happening. Previous posts indicates that this is possible. So, I don't think it is a bug. In any event, I did gave up on this to quickly, I will spend some more time on it. I will try re-reading the docs again. I know I am missing something obvious.

                      Thanks Matt

                      • 8. Re: Re-working EJB Extended Context To Use SMPC - Need Help
                        Pete Muir Master

                         

                        "matt.drees" wrote:
                        I'm fairly certain it ought to work for (non-@Named) superclasses. I know it does for JavaBean components, anyway (I don't yet need to live in EJB land)/quote]

                        As Matt says, injection works for abstract superclasses which are not annotated @Name. You likely have some other problem.


                        • 9. Re: Re-working EJB Extended Context To Use SMPC - Need Help
                          Curtney Jacobs Newbie

                          Sorry for having to rehash this again, but I am still getting wierd results. I have tripple check my configuration, looked at all the examples applications and still not working.

                          Pete and et al, please read the following perhaps my reasoning/understanding is way off.

                          I have tried three different scenarios (getting desparate here):

                          Scenario One:

                          I am using @EJB annotation to inject my ejb components, instead of Seam's @In annotation. My ejb components are injected successfully, but the entity manager is not injected on subsequent ejb components (The first ejb component, MyStatefulBean, does get the entity manager injected).

                          Scenario Two:

                          All ejb components are injected using Seam's @In annotation (Switched from @EJB to @In annotation). Why the switch? I am assumming the swith will solve my problem of the entity manager not being injected. Seam now has controll of the creation and injection of the ejb components, thus proper injection of the entity manager. However, that is not the case injection fails on both ejb components and entity manager. Before, it was only the entity manager that did not get injected.

                          Scenario Three:

                          Remove all ejb annotations (Just POJOS) and have Seam do all injections. It works! All injections works, except that I get an exception on my generic dao object. But hey, injection works!!

                          java.lang.ClassCastException java.lang.Class
                          
                          //Implementation was taken from Hibernate persistence book
                          public MyGenericDAO () {
                           this.bean = (Class<T>) ((ParameterizeType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
                          }
                          


                          See below for ejb component setup:

                          I have a Stateful bean with @Name annotation I can inject an entity manager instance,
                          using @In (It works, entityManager is not null). In this same stateful bean I have a stateless bean(MyStatlessBean) that is being inject via @EJB annotation. The injection works.

                          @Stateful
                          @Name("myStateful")
                          public MyStatefulBean implements SomeInterface {
                          
                          @In
                          EntityManager entityManager; //Injected (not null)
                          
                          @EJB
                          MyStatelessBean myStatlessBean;//Injected (not null)
                          
                          


                          MyStatelessBean has another stateless bean (MyStatlessDAO) that is also being injected with @EJB.
                          However, the declared entity manager is not injected. I am assumming it fails because Seam does not have control of the creation and injection of the ejb (myStatlessDAO)???

                          public MyStatelessBean implements SomeInterface {
                          
                          @In
                          private EntityManager entityManager; //Not injected (null)
                          
                          @EJB
                          private MyStatelessDAO myStatelessDAO;//Injected (not null)
                          
                          }
                          


                          Again, MyStatelessDAO entity manager is not injected (It inherits this from MyGenericDAO). It fails because Seam does not have control of the creation and injection of the ejb?

                          @Stateless
                          @Name("myStateless")
                          public MyStatlessDAO extends MyGenericDAO <MyObject, Its Type) implements SomInterface {
                          
                          //Super class entity manager is null, not injected.
                          
                          }
                          
                          
                          public abstract class MyGenericDAO <T, ID> implements MyGenericInterfce <T, ID> {
                          
                          @In
                          protected EntityManager entityManager; //Not injected (null)
                          
                          }
                          






                          • 10. Re: Re-working EJB Extended Context To Use SMPC - Need Help
                            Matt Drees Master

                             

                            "curtney" wrote:

                            Scenario Two:

                            All ejb components are injected using Seam's @In annotation (Switched from @EJB to @In annotation). Why the switch? I am assuming the switch will solve my problem of the entity manager not being injected. Seam now has control of the creation and injection of the ejb components, thus proper injection of the entity manager. However, that is not the case injection fails on both ejb components and entity manager. Before, it was only the entity manager that did not get injected.



                            This should work, and is probably what you want. Could you be more specific on what breaks when you do this? (and post code)

                            Also, note that the variable name needs to match the component name. So you'll need to change MyStatelessBean's field "myStatelessDAO" to "myStateless". (Or change the component name, or use @In's value attribute, etc).

                            • 11. Re: Re-working EJB Extended Context To Use SMPC - Need Help
                              Pete Muir Master

                              I'm not quite getting your scenarios.

                              "curtney" wrote:


                              MyStatelessBean has another stateless bean (MyStatlessDAO) that is also being injected with @EJB.
                              However, the declared entity manager is not injected. I am assumming it fails because Seam does not have control of the creation and injection of the ejb (myStatlessDAO)???


                              Yes, you've injected the MyStatelessDAO using @EJB right? So it's not a Seam component so Seam has nothing to do with it.


                              Again, MyStatelessDAO entity manager is not injected (It inherits this from MyGenericDAO). It fails because Seam does not have control of the creation and injection of the ejb?


                              Yes, as above

                              • 12. Re: Re-working EJB Extended Context To Use SMPC - Need Help
                                Curtney Jacobs Newbie

                                I just listed all the scenarios that I went through. I knew scenario one would not work, but I tried and listed it anyway for confirmation (You never know...).

                                Ideally, scenario two is what I wanted and what should work, however it is not working.

                                In reply to matt, I did confirm that the variable name did match the components name. I even explicitly stated it at times (@In(value="xxxxx"), it makes no difference. The code breaks on a simple authentication, using a stateless dao to do authentication. If I disable authentication, subsequent code breaks as well. Not on my dev computer right now, but will post code that breaks.

                                Forgot to mention that I am using JBoss 4.2.1.GA and Seam 2.0.0.CR2. I am thinking this may be a library problem. As soon, as I get to my desk I will check this out.