为什么对 EJB 会话 bean 使用 Facade 模式
我想问一下访问EJB Session Bean时使用Facade Pattern的原因是什么?在我的 Netbeans 6.9.1 中,如果我执行 New
> 实体类的会话Bean
,假设我选择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);
}
这是正确的事情吗做什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用 EJB 的重点在于它们通过注释(或 XML 配置)提供声明性事务和安全性等功能。如果您不使用这些功能,那么拥有 EJB 就没有意义。
此外,自动生成的外观代码只是一个起点(也是一个糟糕的起点)。 EJB 应该形成一个域 API,而不是所有单独 CRUD 操作的包装器。它们应该只包含您实际想要在域模型上执行的操作,并且其中许多应该跨越需要在事务中执行的多个 CRUD 操作。例如:
应用程序服务器将执行事务中的所有操作,这确保您不会出现因某种原因引发异常的情况,并且最终会得到从一个 Schoold 中删除但未添加到的 User另一个。
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:
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.
是的,也不是。外观模式很有意义,但每个域对象都有一个单独的外观是没有意义的。
您将需要按域对象的功能组对外观进行分组。想象一下计费系统。它有账单、项目、客户、地址。因此,您可能会有一个用于账单处理(添加项目、设置客户、打印、标记为已付款)的外观,以及用于创建和更新用户、与地址关联等的不同外观。
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.
我认为您应该有一个用于典型 CRUD 操作的 AbstractFacade,如您所见,以及许多用于操作给定实体的 SpecificFacade。因此,您不能多次重新实现相同的基本逻辑……而只能专注于与实体关联的更复杂的逻辑(事务)。
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.