CDI @TransactionAttribute 用于 Bean

4

我正在测试应用程序中尝试使用 CDI。我有一个 DAO,它像这样注入了容器管理的 JTA 持久化上下文:

public class TestDAO implements Serializable {
    @PersistenceContext
    private EntityManager entityManager;

    public void insertEntity(Test test) {
        entityManager.persist(test);
    }
}

现在我有一个CDI控制器bean,就像这样:
@Named
@SessionScoped
public class TestController implements Serializable {
    @Inject
    private TestDAO testDAO;

    public void finishGame() {
        testDAO.insertEntity(new Test(1, 2, 3));
    }
}

如果我运行这个程序,当尝试插入实体时,会在DAO中收到一个错误,因为没有可用的活动事务。目前为止还好,我可以通过将控制器bean设置为有状态的EJB来解决这个问题,它将在一个事务中包装finishGame()。
但是假设我不想要一个EJB。作为一个测试,我使用@TransactionAttribute注释了finishGame(),它起作用了(控制器bean不是EJB)。那么我的问题是:它是如何工作的?CDI是否为普通bean定义了@TransactionAttribute?我知道Seam Persistence Module这样做了,但我没有使用它。实际上,我把它添加到项目中,但之后我把它删除了,因为我收到了奇怪的异常。
能否有人解决我的困惑?CDI是否真的为普通bean定义了@TransactionAttribute?
另外,我有另一种问题。我看到的趋势是将所有EJB注释移植到普通bean中。那么,EJB将在未来变得过时吗?我的意思是,我在JIRA中看到,@TransactionAttribute将来会被添加到普通bean中(该任务仍未解决)。那么这不是使EJB变得不重要,而是重复功能吗?
最好的问候, Petar
1个回答

3
您需要定义一个事务拦截器。基本上,定义一个@Transactional注释并拦截所有带有它的方法。在拦截器中只需开始、提交或回滚事务。当事务传播进入图像时,情况变得更加复杂。因此,请检查Seam是否没有任何准备好使用的内容http://seamframework.org/Seam3/PersistenceModule

1
+1,感谢您提供有用的答案!但我的问题是为什么@TransactionAttribute在普通的CDI bean上可以工作,而不需要做任何事情?我一直认为@TransactionAttribute只适用于EJBs - Petar Minchev
是的,我认为这是事实 - @TransactionAttribute 不应该开箱即用。 - Bozho
1
是的,这就是奇怪的地方。如果你有足够的时间,能否制作一个简单的CDI应用程序,并尝试在普通的CDI bean上是否可以使用@TransactionAttribute。这让我感到疯狂,因为我知道它不应该在普通的bean上工作... - Petar Minchev
我还会从头开始制作一个示例应用程序,以确认是否有遗漏的地方,这是最有可能的情况 :) - Petar Minchev
2
这就是情况。Glassfish已经缓存了库和描述符,尽管我告诉NetBeans清理构建。现在它抛出了一个必须要事务的异常,正如它应该的那样。感谢您的帮助 :) - Petar Minchev
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接