【发布时间】:2011-11-28 20:14:00
【问题描述】:
这是一个学术问题;我没有与此相关的损坏代码。我只是想扩大我对幕后发生的事情的理解。
我在 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?
非常感谢您的讨论。
【问题讨论】:
-
你考虑过 EJB 吗? EJB 使用容器管理的事务。这样您就不必担心自己管理事务(并且它使您的服务方法免于尝试捕获混乱)。
-
我的代码模式是从像 Burns JSF 2 这样的书籍中学到的。我不太介意这种代码模式,因为我设法将所有这些都限制在一个抽象的 DAO 对象中。我所有的具体 DAO 都是从那个对象扩展而来的,所以它的这个垃圾(如果这个词适用的话)部分几乎是看不见的。但并没有失去理智。