在 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";
 }

大功告成!就好像数据库根本不存在一样!