这是一个学术问题;我没有破坏与此相关的代码。我只是想扩大我对引擎盖下发生的事情的理解。
我在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?
非常感谢任何讨论。
答案 0 :(得分:13)
因为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
这不是某种单身人士,你可以拥有不止一种。但每个线程只能激活一个。