1 Reply Latest reply on Nov 13, 2009 10:31 AM by steffi.stephanie.stroka.salzburgresearch.at

    Understanding Injection and Outjection Lifecycles

    steffi.stephanie.stroka.salzburgresearch.at

      Hello out there,


      I'm developing upon the Seam Framework for quite a time now, but there's still something that leaves me curious sometimes: injection/outjection lifecycles


      I have a stateless service in my project, that injects an object which is session-scoped. I provided the annotation attribute create="true" to ensure that it will not be null. This session scoped object is created through a factory, which by itself is stateless. (also see code below)


      Now, I got some import actions in the stateless service, which save and update a lot of data in the database. Thus, I need to programmatically control transactions, so that (in this case) >= 50 entities get persisted in one transaction. As soon as I call Transaction.instance().commit(), the code ends up in the beforeCompletion() phase of the registered transaction-synchronization-class. From there I cann the statelessService method, which uses the injected object 'someSessionScopedObj'.


      When I reach this method, the injected object is null. The create="true" attribute seems to make no difference to the lost injection. I guess this happens, because I'm still in the stateless service and therefore it does not load the injections again, but on the other hand the Transaction.getInstance().commit() call forces the stateless service to get rid of all injections.


      Can someone confirm my thoughts?




      
      @Stateless
      @Name("statelessService")
      @Scope(ScopeType.STATELESS) 
      @AutoCreate
      public class StatelessService implements StatelessServiceLocal, StatelessServiceRemote {
      
          @In(value="someSessionScopedObj", create="true")
          private SomeSessionScopedObj someSessionScopedObj;
      
          public void someMethod() {
              // someSessionScopedObj == null
              if(someSessionScopedObj == null) {
                  someSessionScopedObj = (SomeSessionScopedObj)
                     Component.getInstance("someSessionScopedObj");
              }
              // someSessionScopedObj is not null anymore
          }
      
          public void importMethod(Set<Data> data) {
              if(!Transaction.instance().isActive()) {
                  Transaction.instance().begin();
              }
              
              int count = 1;
              for(Data d : data) {
                  count++;
      
                  SomeSynchronizationClass sync;
                  Transaction.instance().registerSynchronization(sync);
      
                  if(count % 50 == 0) {
                      Transaction.instance().commit();
                      Transaction.instance().begin();
                  }
              }
              Transaction.instance().commit();
          }
      }






      @Name("someSessionScopedObj")
      @Scope(ScopeType.SESSION)
      @AutoCreate
      public class ObjFactory() {
      
          @Unwrap
          public SomeSessionScopedObj getSomeSessionScopedObj() {
              // create and return someSessionScopedObj
          }
      
      }







      public class SomeSynchronizationClass {
          public void beforeCompletion() {
              ....
              statelessService.someMethod();
              ....
          }
      
          public void afterCompletion() {
          }
      }





      Thanks,
      Steffi!