3 Replies Latest reply on Dec 2, 2006 12:48 PM by lowecg2004

    Injection at destroy time

    lowecg2004

      I have some stateless beans injected into a stateful bean that are only required at destroy time. Currently when destroy is invoked, these beans are null. Code is as follows:

      @Name("sessionTimeoutHandler")
      @Stateful
      @Scope(ScopeType.SESSION)
      public class SessionTimeoutHandlerHome implements SessionTimeoutHandler, Serializable
      {
       private static final long serialVersionUID = 1L;
      
       @Logger
       private Log log;
      
       @In(create=true)
       private SessionDao sessionDao; // this is stateless
      
       @In(create=true)
       private AuditLog auditLog; // and so is this
      
       private Session currentSession;
      
       ...
      
       @Remove @Destroy
       public void destroy() {
       // Session has timed out, so update the user session entry and perform
       // cleanup.
       currentSession.setClosed(new Date());
      
       sessionDao.merge(currentSession);
      
       auditLog.addAuditEntry("User session timeout for session id #0" currentSession.getId());
      
       log.info("User session timeout for session id #0" currentSession.getId());
       }
      }


      Should I be getting the stateless beans injected at this point? I'm sure I've seen this working in the past.

      When creating the bean I did notice what I believe to be inconsistent behaviour with respect to @Logger injection. I initially created the bean using method 1 below, by simply specifying the bean as an @Out parameter and instantiating the object within an action. Using this method, the @Logger object on SessionTimeoutHandler was null when @Destroy was called. However, when I changed to method 2 the logger was available - but still no stateless beans.
      Creation Method 1 - Using @Out
      @Name("login")
      @Stateful
      @Scope(ScopeType.EVENT)
      public class LoginAction implements Login, Serializable
      {
       @Out(required=false)
       private SessionTimeoutHandler sessionTimeoutHandler;
      
      
       public String login() {
       ...
      
       SessionTimeoutHandler sessionTimeoutHandler = new SessionTimeoutHandler();
      
       // create a session timeout handler
       sessionTimeoutHandler.setCurrentSession(currentSession);
       }
      }
      
      
      Creation Method 2 - Using @In(create = true)
      @Name("login")
      @Stateful
      @Scope(ScopeType.EVENT)
      public class LoginAction implements Login, Serializable
      {
       @In(create = true)
       @Out(required = false)
       private SessionTimeoutHandler sessionTimeoutHandler;
      
      
       public String login() {
       ...
      
       // create a session timeout handler
       sessionTimeoutHandler.setCurrentSession(currentSession);
       }
      }


      I am using Seam 1.1 CR2.

        • 1. Re: Injection at destroy time
          gavin.king

          Seam components are never instantiated during a call to a @Destroy method. It would be _really_bad_ if they were.

          NEVER try to create a Seam component using "new"! (Except in unit tests.) Use Component.getInstance().

          • 2. Re: Injection at destroy time
            lowecg2004

            Fair enough. I suppose that leads me to two questions:

            1. is there a better way (a Seam way?) of handling my case where I have to write something to the DB at session timeout?
            2. or is it okay both for me to use Component.getInstance() in this case?

            Thanks for your response.

            Chris.

            • 3. Re: Injection at destroy time
              lowecg2004

              Okay, I've been reading the seam reference for 1.1 and my problem appears to be solved using the following:

              @Observer("org.jboss.seam.preDestroyContext.SESSION")
               public void handleSessionTimeout() {
              
               }


              Cheers,

              Chris.