I'm in the process of developing a multi-tiered financial processing application in Java using EJB3 (Hibernate + Glassfish for the app and web services layer, Lift on Glassfish for the web UI) and I'm struggling with the question of where to put my business logic.
When this project started, our first notion was to put the bulk of our business logic into the stateless session beans. As time has gone on, though, we've found the dependency injection provided by the EJB framework too limiting, so a lot of our business logic has ended up in POJOs that are assembled by Guice in the @PostConstruct method of the stateless session beans. This progress has led to fragmentation of our business logic between the session beans and the POJOs, and I'm trying to figure out an approach for correcting this.
Initially, we tried to have our web tier use the remote interfaces of the session beans to perform some functions that are accessible both from the UI and from the web service layer, which is provided by @WebService-annotated stateless session beans. This turned out to be a nightmare from a persistence and performance perspective, because our entity graph can grow quite large and reattaching the detached entity graph to the persistence context turned out to be highly error-prone, so our solution was to start just passing object identifiers around and looking up the entities from the database wherever they were needed.
My basic question is this: what principles and guidelines can you suggest for deciding whether business logic should go in a session bean or a POJO? When does it make sense to pass entity beans around, given a complex object graph?