There is an article available at OnJava now describing how to optimize deployment so that get-methods are excluded from transactions and JBoss uses commit option A. (http://www.onjava.com/pub/a/onjava/2003/05/28/jboss_optimization.html?page=1)
Basically this is pretty easy to set up following the instructions in the article.
However, when it comes to CMR getters, things get slightly more complicated, because one can't manipulate a read-only CMR collection, still it'd be nice to access the CMR collection read-only when there is no updates to be done, to gain speed.
A suggestion from the authors is to make two deployments of the same bean, one with the cmr-getter read-only, and one with write-access. This will work, but I suppose it requires some deployment descriptor overhead:
Suppose I have a TeamEJB and a MemberEJB and a one to many or many to many relation between them, implying a getMembers() function in TeamEJB.
Also suppose I've already optimized deployment in accordance with the article, setting getMembers() (and all other getters in TeamEJB) read-only in jboss.xml. Now, I have code that add members; a'la
This won't work anymore because getMembers() returns a read-only collection, and JBoss throws an exception runtime.
So the proposed solution is to create a new deployment, so that I can get a bean instance where getMembers() is not read-only. In order to do this I suppose I must:
1. create description of TeamEJB_RW in ejb-jar.xml. This could be done just copying the from the original deployment of TeamEJB and just change <ejb-name> and <display-name>
2. create needed transaction attributes for methods in the new description created in 1.
3. update jbosscmp-jdbc.xml so that both deployments (TeamEJB and TeamEJB_RW) access the same table (I suppose it's the ejb-name and not the actuall class names that affect this)
4. update jboss.xml so that all getters _except_ getMembers() in TeamEJB_RW are read-only. (All getters (including getMembers() in TeamEJB would still be read-only too)
5. Duplicate the relation between TeamEJB and MemberEJB so that TeamEJB_RW and MemberEJB are related in the same way.
Now, it'd be possible to access all getters read-only using TeamEJB and still manipulate the getMembers() collection thru' TeamEJB_RW when needed. I suppose this is all I've got to do (but I'm not completely sure, please share your knowledge :-)
Still, I feel I've produced quite an amount of xml to achieve this. When I have more than a few beans and a larger amount of relations amongst them, this sounds like a lot of work to deploy, and not exactly what one would love to maintain.
So I wonder how I could do this a little easier. Would anyone care to comment on an alternative approach, perhaps like below:
1. Deploy optimizations like described in the article so that all getters are read-only.
2. Define a second getter and a new collection attribute for the collection of read-write members, lets call the attribute membersRW, in the bean (and appropriate interface), and let's call the method getMembersRW(), specify it in ejb-jar.xml as well in the section, and define transaction attribute.
3. Make a new <ejb-relation> in ejb-jar.xml, just like the previous one, except that it'd map to the new attribute, members_RW.
Now I'd be able to use separate getters on the same TeamEJB to get a read-only and a read-write version of the members collection. I'm not sure it'd work, though. For instance, would adding a member to the read-write collection/relation cause the new member to show up in the old read-only members collection/relation?
Any hints and tips on the subject would be most welcome.
Jon Martin Solaas