1 Reply Latest reply on Oct 17, 2008 8:47 PM by sschaffert

    Transaction component returns new object each time it is retrieved or injected

    sschaffert

      I am currently working on integrating a Sesame RDF store in our Seam application. An important feature would be transaction support, so I'd like to track all changes and only commit them when the transaction is actually committed. My implementation works by keeping a HashMap(UserTransaction,TripleTransactionBean), where TripleTransactionBean is used to keep track of all changes done to the RDF store.


      Now here is the problem: unfortunately, Seam wraps the JTA transaction into a new Seam UserTransaction instance every time it is injected or retrieved using Component.getInstance(org.jboss.seam.transaction.transaction, ScopeType.EVENT). Since this is a new object, it is pretty useless to use it as a HashMap key, because in the worst case every method call creates a new object; keeping track of transaction state becomes pretty impossible this way, and I am not aware of any other way to do it properly in Seam.


      My current solution is to inject the Seam transaction in my action beans and outject it again to the event scope under a different name. This way, I can get the desired behaviour, but this is not only inconvenient but also error prone:



          @In("org.jboss.seam.transaction.transaction")
          @Out(value="kiwiTransaction", scope=ScopeType.EVENT)
          private UserTransaction transaction;
      



      And in the method where I manage the HashMap, I do:



                     // first, try to get the current kiwi transaction, which might have been outjected by some other component
                      // this is a way to ensure a long-running transaction to capture all changes
                      UserTransaction transaction = 
                              (UserTransaction) Component.getInstance("myTransaction");
                      
                      try {
                              // then try to use the injected transaction; works well with import/export but not so well when
                              // triple store is accessed from outside
                              if(transaction == null || !transaction.isActive()) {
                                      transaction =  this.userTransaction;
                              }
                              // if there is no other transaction, use the normal EVENT-scoped Seam transaction
                              if(transaction == null || !transaction.isActive()) {
                                      transaction =  (UserTransaction) Component.getInstance("org.jboss.seam.transaction.transaction", ScopeType.EVENT);
                              }
                      } catch (SystemException e) {
                              e.printStackTrace();
                      }
      
      



      Now, what I would rather like to see is that Seam transactions that wrap the same JTA transaction (or other transaction provider transaction) would either be the same object or at least have the same hashcode and equals methods. I would file a bug report, but apparently I cannot submit issues to Jira.:-)

        • 1. Re: Transaction component returns new object each time it is retrieved or injected
          sschaffert

          Replying to myself ...


          I have now chosen a different, cleaner approach by copying from Seam's Transaction class the method for directly accessing the JTA UserTransaction (getUserTransaction). With the JTA UserTransaction as a hashmap key, the rest of my code works as expected (for the moment: flawlessly :-) ).


          Still, this is not really a solution, because I now loose portability to other transaction implementations ...