I was on a project recently where we wrote a ton of session beans that mostly (95%) did findBy and create/update/delete operations. We used JBoss 2.x along with an O/R implementation (i.e. no entity beans).

Writing all these session beans was a very painful process (I'm much more receptive to EJB-is-overkill-in-many-situations advice now). A couple major problems that come to mind:

- debugging bean code is a slow, arduous process, that can result in code that's less readable. Yes Intellij, Forte, etc have distributed debugging plugins for the major appservers, but this is slow, esp when you're running a 100mb appserver, 100mb dbserver, 80mb servlet container, 150mb+ ide - seems to me that most people resort to debugging by using logging statements (filling your classes with non-essential code).

- debugging rountrip - compile/deploy/start appserver/test changes/check logfile has probably been mentioned countless times by EJB critics/realists.

So why not write one "low-level" session bean that has your basic create/update/delete/query operations (that, in the case of a JDO implementation, delegates to the relevant db-object method). Then write a DAO (plain) java class for each entity, which does its own transactoin mgmt via UserTransaction, that you either "new" or call statically from the client.

Quick example: You want to update a count in the db every time you save an object of class Alpha. Pseudocode:

public class AlphaDAO
{
  public void create(Alpha a)
  {
    ...get a reference to UserTransaction from JNDI
    try
    {
      ...start usertransaction
      new CountDAO.increment(Alpha.class);
      ...lookup "low-level" session bean DAO
      sessionDAO.create(a);
      ...end usertransaction
    }
    catch (Throwable t)
    {
      ...usertransaction.rollback
    }
  }
}

a servlet or applet client would make this call:
new AlphaDAO.create(a);

Possible disadvantages:
- network traffic - you're making more lookups to the low-level sessoin dao because presumably you'll be calling it frequently. I don't see this as a major performance-driver, thinking through typical CRUD and query scenarios - certainly it's not by itself a reason put all this code in a sesion bean.

- transaction mgmt code - I don't see why this is a big deal. It's a few lines of extra code, and anyway when you compare that maintenance cost vs a session bean (3 classes per bean, more logging code in practice). Also I may have been mistaken in my call to CountDAO, which would have its own transaction code...maybe there's a nesting-transaction here?

Advantages:
- no need to redeploy or restart an appserver
- easily debuggable
- persistence concerns still abstracted from client (i.e. if for some reason you wanted to put this code in its own bean later on, you just use a factory and get another AlphaDAO implementation that essentially does a lookup and delegates to your new bean).
- fewer classes
- jarring and appserver startup are faster
- still getting the scalability advantages of EJB thru the "low-level" session DAO bean.

I'm probably missing some considerations. Comments/critiques are appreciated. I'd be surprised if this hadn't been proposed somewhere before - however some quick research on my part didn't turn up anything.

-Steve