在 MVP/MVC 架构中使用有状态 bean 作为 presenter/controller 是个好主意吗?
Is it a good idea to use a stateful bean as a presenter/controller in a MVP/MVC architecture?
我想要一个能够无缝访问持久层的控制器,而 EJB 是实现此目的的一项不错的技术。我可以这样做:
@PersistenceContext
EntityManager em;
...
Cat timmy = em.findById(Cat.class, "Timmy");
timmy.color = "red";
而且感觉 timmy 在内存中。可悲的是,这必须在业务级别完成,因为 bean 仅在业务级别。但是,事务应该在 MVP 中的客户端级别定义。
这就是为什么我想要一个 Presenter 是一个 @Stateful bean。这样我就可以在客户端级别开始和结束交易。无论如何,我有一种奇怪的感觉,@Stateful bean 是邪恶的,我宁愿不使用它们。
是:
@PersistenceContext
EntityManager em;
...
Cat timmy = em.findById(Cat.class, "Timmy");
timmy.setColor("red");
em.merge(timmy);
工作?
在架构方面我使用@Stateless Dao
@Stateless
public class CatDao extends Dao<Cat> {
public CatDao () {
super(Cat.class);
}
}
public class Dao<E> {
@PersistenceContext(unitName = "myappPU")
private EntityManager em;
private final Class<E> entityClass;
protected Dao(Class<E> entityClass) {
this.entityClass = entityClass;
}
public E find(Object id) {
return em.find(entityClass, id);
}
public List<E> findAll() {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
Query q = entityManager.createQuery(cq) ;
return q.getResultList();
}
public void create(E entity) {
em.persist(entity);
}
public void edit(E entity) {
em.merge(entity);
}
public void remove(E entity) {
em.remove(entityManager.merge(entity));
}
}
所以在控制器中我做
@Inject
private CatDao dao;
//...
Cat cat = dao.find("Timmy");
cat.setColor("red");
dao.edit(cat);
查看...无状态
Netbeans 自动生成此 Dao 但称它们为 Facade(新>其他>Enterprise JavaBeans>实体的会话 bean 类)
我终于做到了!
解决方案隐藏在 CDI 规范中:
@Inject CatRepository catRepository;
@Transactional
void changeColorToCat(String color, String catName) {
Cat timmy = catRepository.findByName("Timmy");
timmy.color = "red";
}
大功告成!就好像数据库根本不存在一样!
我想要一个能够无缝访问持久层的控制器,而 EJB 是实现此目的的一项不错的技术。我可以这样做:
@PersistenceContext
EntityManager em;
...
Cat timmy = em.findById(Cat.class, "Timmy");
timmy.color = "red";
而且感觉 timmy 在内存中。可悲的是,这必须在业务级别完成,因为 bean 仅在业务级别。但是,事务应该在 MVP 中的客户端级别定义。 这就是为什么我想要一个 Presenter 是一个 @Stateful bean。这样我就可以在客户端级别开始和结束交易。无论如何,我有一种奇怪的感觉,@Stateful bean 是邪恶的,我宁愿不使用它们。
是:
@PersistenceContext
EntityManager em;
...
Cat timmy = em.findById(Cat.class, "Timmy");
timmy.setColor("red");
em.merge(timmy);
工作?
在架构方面我使用@Stateless Dao
@Stateless
public class CatDao extends Dao<Cat> {
public CatDao () {
super(Cat.class);
}
}
public class Dao<E> {
@PersistenceContext(unitName = "myappPU")
private EntityManager em;
private final Class<E> entityClass;
protected Dao(Class<E> entityClass) {
this.entityClass = entityClass;
}
public E find(Object id) {
return em.find(entityClass, id);
}
public List<E> findAll() {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
Query q = entityManager.createQuery(cq) ;
return q.getResultList();
}
public void create(E entity) {
em.persist(entity);
}
public void edit(E entity) {
em.merge(entity);
}
public void remove(E entity) {
em.remove(entityManager.merge(entity));
}
}
所以在控制器中我做
@Inject
private CatDao dao;
//...
Cat cat = dao.find("Timmy");
cat.setColor("red");
dao.edit(cat);
查看...无状态
Netbeans 自动生成此 Dao 但称它们为 Facade(新>其他>Enterprise JavaBeans>实体的会话 bean 类)
我终于做到了! 解决方案隐藏在 CDI 规范中:
@Inject CatRepository catRepository;
@Transactional
void changeColorToCat(String color, String catName) {
Cat timmy = catRepository.findByName("Timmy");
timmy.color = "red";
}
大功告成!就好像数据库根本不存在一样!