Transaction component returns new object each time it is retrieved or injected
sschaffert Oct 17, 2008 8:02 PMI 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.:-)