为什么使用Facade模式用于EJB会话bean

Tha*_*ham 14 netbeans ejb facade java-ee

我想问一下访问EJB会话Bean时使用Facade Pattern的原因是什么.在我的Netbeans 6.9.1,如果我做New> Sessions Bean for Entity Classes,让说,我选择User实体,然后Netbeans的会看到这个代码

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() {
        ...
    }
Run Code Online (Sandbox Code Playgroud)

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);
    }        
}
Run Code Online (Sandbox Code Playgroud)

我想问一下这有什么好处.如果我有10个实体,那么Netbeans将生成10个Facade类和AbstractFacade.这似乎对我来说太过分了.让地方说我管理的bean里面,我有persist一个UserSchool以后,我这样做

someManagedBean.java

...
@EJB
private UserFacade userEJB;

@EJB
private SchoolFacade schoolEJB;

...

public void someMethod(User user, School school){
    ...
    userEJB.create(user);
    schoolEJB.create(school);    
}
Run Code Online (Sandbox Code Playgroud)

这是正确的事情吗?

Mic*_*rdt 23

使用EJB的关键在于它们通过注释(或XML配置)提供声明式事务和安全性等功能.如果您不使用这些功能,那么拥有EJB是没有意义的.

此外,自动生成的门面代码是一个起点(而且是一个坏的).EJB应该形成域API,而不是所有单独CRUD操作的包装器.它们应该只包含您实际要在域模型上执行的操作,其中许多操作应该跨越需要在事务中执行的多个CRUD操作.例如:

@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);
}
Run Code Online (Sandbox Code Playgroud)

应用服务器将执行事务中的所有操作,这可以确保,例如,您不会出现由于某种原因而抛出异常的情况,并且您最终会从一个Schoold中删除但未添加到另一个Schoold的用户.

  • @Harry:您不需要使用EJB来使用JPA,您可以直接访问EntityManager.但是使用EJB来获取事务可能仍然有意义.我将添加一个例子. (2认同)

Hei*_*upp 7

是的,不是.Facade模式很有意义,但每个域对象具有单独的facace是没有意义的.

您将希望按域对象的每组功能对外观进行分组.想象一下计费系统.它有账单,物品,客户,地址.所以你可能会有一个Facade用于账单处理(添加项目,设置客户,打印,标记为付费)和不同的外观,用于创建和更新用户,关联地址等.