14

I want to ask what is the reason to use Facade Pattern when access EJB Session Bean. In my Netbeans 6.9.1, if I do New > Sessions Bean for Entity Classes, and let say that I select User entity, then Netbeans would generate this code

AbstractFacade.java
public abstract class AbstractFacade<T> {
    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public T edit(T entity) {
        return getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        ...
    }

    public int count() {
        ...
    }

AND

UserFacade.java    

package com.bridgeye.ejb;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class UserFacade extends AbstractFacade<User> {
    @PersistenceContext(unitName = "Bridgeye2-ejbPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public UserFacade() {
        super(User.class);
    }        
}

I want to ask what is the benefit of this. If I have 10 entities, then Netbeans would generated 10 Facade classes plus the AbstractFacade. This seems to be overkill to me. Let say somewhere inside my managed bean, i have to persist a User and School then I have do this

someManagedBean.java

...
@EJB
private UserFacade userEJB;

@EJB
private SchoolFacade schoolEJB;

...

public void someMethod(User user, School school){
    ...
    userEJB.create(user);
    schoolEJB.create(school);    
}

Is this the right things to do?

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
Thang Pham
  • 35,825
  • 73
  • 192
  • 279

3 Answers3

24

The point of using EJBs at all is that they provide features such as declarative transactions and security via annotations (or XML configurations). If you don't use those features, there is no point in having EJBs.

Additionally, that autogenerated facade code is jsut a starting point (and a bad one). The EJBs should form a domain API, not a wrapper for all individual CRUD operations. They should only contain the operations you actually want to be performed on your domain model, and many of them should span several CRUD operations that need to be performend within a transaction. For example:

@TransactionAttribute
public void transferUser(User u, School from, School to){
    from.getUsers().remove(u);
    to.getUsers().add(u);
    u.setSchool(to);
    getEntityManager().merge(from);
    getEntityManager().merge(to);
    getEntityManager().merge(u);
}

The app server will execute all operations within a transaction, which ensures, for example, that you cannot have a situation where an exception is thrown for some reason and you end up with User that is removed from one Schoold but not added to the other one.

Michael Borgwardt
  • 327,225
  • 74
  • 458
  • 699
  • I am still a bit confused. The reason I create a EJB is because I need to interact with JPA to perform CRUD, such as `persist` or `merge` or `Query#getResultList`, so in this case, should I use EJB. I use `@Statsless` EJB btw. Can u elaborate a bit more on your second paragraph, maybe some sample codes, so I can see the actually structure, would be greatly appreciated. – Thang Pham Apr 12 '11 at 14:49
  • 2
    @Harry: you don't need to use EJBs to use JPA, you can access the EntityManager directly. But it might still make sense to use EJBs to get transactions. I'll add an example. – Michael Borgwardt Apr 12 '11 at 14:59
  • Thank you. If it is possible, will you add an example of how to correctly implement facade pattern for EJB? I would greatly appreciated it :D – Thang Pham Apr 12 '11 at 15:02
  • The above method is inside your EJB, correct? You use `getEntityManager()` instead of specify your EntityManager as a global variable, what kind of structure you have there. I am learning on how to correctly structure my code so if any of my questions dont make any sense, please forgive my ignorance. – Thang Pham Apr 12 '11 at 15:26
  • 1
    @Harry: yes, that's an EJB method (otherweise, the annotation would have no effect). Using a getter for the entity manager is just something I did the same as in your sample generated code to emphasize the similarity. There, it's done because it's an abstract method, but that's not really important. – Michael Borgwardt Apr 12 '11 at 15:29
  • I have another question here, will you take a look at this. I has similar concept http://stackoverflow.com/questions/5641310/design-generic-crud-session-bean – Thang Pham Apr 12 '11 at 20:40
7

Yes and no. The Facade pattern makes a lot of sense, but having a separate facace per domain object makes no sense.

You will want to group facades per groups of functionality of domain objects. Imagine a billing system. It has bills, items, customer, addresses. So you would there perhaps a Facade for bill handling (adding items, setting customer, printing, marking as paid) and a different facade for creation and update of users, associating with addresses and so on.

Heiko Rupp
  • 28,212
  • 13
  • 79
  • 118
1

I think you should have one AbstractFacade for typical CRUD operations as you can see and many SpecificFacade for manipulating a given entity. So you can not reimplement the same basic logic many times just one... and concentrate only on more complex logic (transactions) associated with entities.

Michał Ziobro
  • 7,390
  • 6
  • 50
  • 99