我想问一下访问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() {
...
}
和
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);
}
}
我想问一下这有什么好处。如果我有10个实体,那么Netbeans将生成10个Facade类和AbstractFacade。这似乎对我来说太过分了。让我说在我的托管bean里面,我必须persist
一个User
和School
然后我就这样做了
someManagedBean.java
...
@EJB
private UserFacade userEJB;
@EJB
private SchoolFacade schoolEJB;
...
public void someMethod(User user, School school){
...
userEJB.create(user);
schoolEJB.create(school);
}
这是正确的事吗?
答案 0 :(得分:22)
使用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);
}
应用服务器将执行事务中的所有操作,例如,确保您不会出现由于某种原因引发异常的情况,并且您最终会从一个Schoold中删除但未添加到用户的用户另一个。
答案 1 :(得分:7)
是和否。 Facade模式很有意义,但每个域对象有一个单独的facace毫无意义。
您需要为域对象的每组功能分组外观。想象一下计费系统。它有账单,物品,客户,地址。所以你可能会有一个Facade用于账单处理(添加项目,设置客户,打印,标记为付费)和不同的外观,用于创建和更新用户,与地址相关联等。
答案 2 :(得分:1)
我认为你可以看到一个AbstractFacade用于典型的CRUD操作,你可以看到许多用于操作给定实体的SpecificFacade。所以你不能多次重新实现相同的基本逻辑......而只关注与实体相关的更复杂的逻辑(事务)。