-
1. Re: SLSB Facade in front of Entity?
greening Feb 21, 2006 1:10 PM (in response to chaik)Brian and I are very interested in thoughts on this. Please weigh in if you've worked with EJB3.
I think having an SLSB facade in front of every entity bean, at least the way I've seen it done, is an anti-pattern. Here's my argument:
One purpose could be to eliminate the need for passing in an EntityManager when finding or storing entities, letting an EM be injected into each SLSB. However, if you create separate EntityManagers for every entity bean via these SLSB facades, you eliminate transaction atomicity (how can you start a transaction, make several entity-related operations possibly on different entities, and then commit the whole caboodle without passing around a single EntityManager?). And so, if you use this (anti)pattern, when you want to perform complex activities that require atomicity over several entities, you must add parallel find/create operations that take an entity manager. Now you have created more complexity and maintenance headaches for the convenience of omitting EMs in a few cases. (In the final version of JavaEE5, I believe you can inject EntityManagers into Servlets, which makes NOT using SLSB facades even easier.)
OK, suppose we agree with the previous paragraph. Let's fix our pattern by passing the entity manager to all these functions in the SLSB. Now we have the question of whether these find/create/remove operations require an SLSB. I think not, because the SLSB doesn't buy us anything. We wanted it before, because of the ability to inject the EntityManager, but now we are passing the EM around instead. No need for SLSB.
OK, now let's suppose we agree with the previous two paragraphs. So we turn this facade into a class that has some (static) methods with EntityManager passed in. Well, remove and create are irrelevant now, because the direct call through the EM is simpler: em.remove(entity) and em.persist(entity) versus Fascade.remove(em,entity) and Fascade.persist(em,entity). What remains is complex find operations. I think simpler EJB3 find operations are best coded as annotations with @NamedQuery like this:
customers = em.createNamedQuery("findAllCustomersWithName")
.setParameter("custName", "Smith")
.getResultList();
Sometimes find operations can get complex, requiring loops or conditionals and multiple SQL requests. One can argue, and I think fairly, that simple named queries AND these more complex find operations really ought to be encapsulated in a method like this:
static public List findCustomerWithName(
EntityManager em,
String name) {
return em.createNamedQuery("findAllCustomersWithName")
.setParameter("custName", "Smith")
.getResultList();
}
I would put this method in the POJO itself. Brian is thinking it might belong in a fascade class. So this is the jist of this pattern vs. anti-pattern argument:
Brian and I both think we SHOULD capture complex find operations either in the POJO itself as a static method, OR we should capture these complex find operations in some separate fascade. I'm mildly opposed to putting complex find operations in a separate fascade, because it bothers me that methods that solely deal with the POJO are put somewhere else, increasing maintenance problems. However I can see an opposing argument maybe.
If you have thoughts on this, could you please discuss? -
2. Re: SLSB Facade in front of Entity?
patrick_ibg Feb 21, 2006 6:01 PM (in response to chaik)What's wrong with using Generic DAOs?
-
3. Re: SLSB Facade in front of Entity?
epbernard Feb 21, 2006 6:44 PM (in response to chaik)the entitymanager is the same for all session beans executed in a single transaction.
-
4. Re: SLSB Facade in front of Entity?
greening Feb 21, 2006 8:20 PM (in response to chaik)epbernard: Thanks! Very interesting. How is the transaction demarcated? By the first call into the EJB jar file? (And then transaction completes upon return?)
patrick_ibg: I thought GenericDAOs were primarily for abstracting away different storage mechanisms. This is really a question about where the find methods belong. Do they belong as static methods on the POJO class with the EM as a first parameter?
I don't think this is a fact-based question, more like a pattern "what's a good way to do it" question.
I think this question will come up frequently as people start to use EJB3 persistence. -
5. Re: SLSB Facade in front of Entity?
persabi Feb 21, 2006 8:53 PM (in response to chaik)greening: I think your question has a lot of merit. We are also undecided as to which strategy will prove to be the 'pattern' in the end. AndroMDA now has a EJB3 cartridge and the finder methods exist in entity POJOs as static methods with EntityManager as the first argument to the finder method. This was designed that way because of the limitations of generics, code generation and UML. I've seen tutorials use this strategy, but others are strictly against passing the EntityManager to the POJO and maintaing everything related to the facade class.
-
6. Re: SLSB Facade in front of Entity?
epbernard Feb 22, 2006 8:46 AM (in response to chaik)I don't like the AndroMDA solution
A DAO should be represented as a @Staleless session beam where @PersistenceContext EM em is used to inject the appropriate EM
The transaction is started regarding the @TransactionAttribute annotation, this is very much like EJB2 except that you can define one of the transaction strategies through annotations. -
7. Re: SLSB Facade in front of Entity?
nholbrook Feb 22, 2006 5:37 PM (in response to chaik)Well, I think a proxy is pretty simple. I don't write them for every entity and don't see a need for it. Here's my simple interface.
public interface ServiceProxy
{
void insert( Serializable transientInstance );
void remove( Serializable persistentInstance );
T update( T detachedInstance );
T findById( Class transientInstance, Serializable id );
List findByNamedQuery( String queryName, Map<String, Serializable> queryParams );
List findAll( Class transientInstance );
}
Works great for me. I only expose what is required by the client. This covers almost all the cases. For other cases, I add a service method to the proxy. -
8. Re: SLSB Facade in front of Entity?
agreif Mar 24, 2006 8:50 AM (in response to chaik)"epbernard" wrote:
the entitymanager is the same for all session beans executed in a single transaction.
I tried this with the following code@Stateful @Remote(ShoppingCart.class) public class ShoppingCartBean implements ShoppingCart, java.io.Serializable { @PersistenceContext private EntityManager manager; private Order order; @EJB private MyDao myDao; public void buy(String product, int quantity, double price) { if (order == null) order = new Order(); order.addPurchase(product, quantity, price); } public Order getOrder() { return order; } @Remove @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void checkout() { System.out.println("ShoppingCartBean.checkout() - myDao: " + myDao); System.out.println("ShoppingCartBean.checkout() - manager: " + manager); myDao.doSomething(); manager.persist(order); } } ----------------------------------------------------------- @Stateless @Local(MyDao.class) public class MyDaoBean implements MyDao { @PersistenceContext private EntityManager manager; public void doSomething() { System.out.println("myDao.doSomething() - manager: " + manager); Order order = new Order(); order.addPurchase("bla", 1, 10); manager.persist(order); } }
The output is the following :14:41:21,586 INFO [STDOUT] ShoppingCartBean.checkout() - myDao: org.jboss.tutorial.entity.bean.MyDaoBean 14:41:21,586 INFO [STDOUT] ShoppingCartBean.checkout() - manager: org.jboss.ejb3.entity.InjectedEntityManager@1e17cff 14:41:21,626 INFO [STDOUT] myDao.doSomething() - manager: org.jboss.ejb3.entity.InjectedEntityManager@1a4835a
Could anybody please explain, why the entity managers have different hashcodes? This means they are different instances. Are these entityManagers really both the same?
Alex. -
9. Re: SLSB Facade in front of Entity?
epbernard Mar 25, 2006 10:21 AM (in response to chaik)these are wrappers