这是一个学术问题;我没有与此有关的坏代码。我只是想加深对引擎盖下正在发生的事情的理解。

我在JPA DAO中为典型的JSF Web应用程序使用的代码模式(从书籍和教程中复制)基本上是这样的:

public class someDAO {

    @PersistenceContext protected EntityManager   em;
    @Resource           private   UserTransaction utx;

    public void persist(Entity entity) {
        try {
            utx.begin();
            em.persist(entity);
            utx.commit();
        } catch ( // gawd awful long list of possible exceptions )

        // etc


所以我的问题如下:


为什么在EntityManager实例和UserTransaction实例中注入了两个看似无关的包中的注释?
为什么使用注释@Resource和@PersistenceContext而不是@ManagedProperty或@Inject?
persist()方法如何访问utx对象并与之交互?如果我忘记了utx.begin()调用,则实体管理器会知道并抛出异常。它必须以某种神奇的方式找到UserTransaction对象。定义像em.persist(utx,entity)这样的接口不是更好的体系结构吗?
如果utx是某种单例-一次可以打开多个UserTransaction吗?


非常感谢您的讨论。

最佳答案

因为UserTransaction是Java Transaction API(JTA)的一部分,而EntityManager是Java Persistence API(JPA)的一部分。 JTA不属于JPA。 JPA使用JTA提供的服务。
不是ManagedProperty是一些注释,仅在使用@ManagedBean注释的类中有效。也许最好不要注入UserTransaction
托管Bean中使用不同的方式。
JNDI查找活动事务。保留名称似乎是java:comp / UserTransaction。一种实现:http://www.java2s.com/Open-Source/Java-Document/Database-ORM/hibernate/org/hibernate/transaction/JTATransactionFactory.java.htm
这不是某种单例,您可以有多个。但是每个线程只能激活一个。

10-07 20:37