Sam*_*mah 4 java persistence jpa transactions
以下代码来自JPA规范.我无法理解为什么em.joinTransaction()需要createLineItem(int quantity).
任何人都可以提供合适的解释吗
@Stateful
public class ShoppingCartImpl implements ShoppingCart {
@PersistenceUnit
private EntityManagerFactory emf;
private EntityManager em;
private Order order;
private Product product;
@PostConstruct
public void init() {
em = emf.createEntityManager();
}
public void initOrder(Long id) {
order = em.find(Order.class, id);
}
public void initProduct(String name) {
product = (Product) em
.createQuery("select p from Product p where p.name = :name")
.setParameter("name", name).getSingleResult();
}
public LineItem createLineItem(int quantity) {
em.joinTransaction();
LineItem li = new LineItem(order, product, quantity);
order.getLineItems().add(li);
em.persist(li);
return li;
}
@Remove
public void destroy() {
em.close();
}
}
Run Code Online (Sandbox Code Playgroud)
wyp*_*prz 12
首先,说几句理论......
一个应用程序管理的实体管理器参与两种方式之一JTA事务.
joinTransaction()的上EntityManager接口.一旦同步,持久化上下文将在事务提交时自动刷新.阅读上述定义后,可能会出现一些问题:
我们怎么知道ShoppingCartImpl参与JTA交易?
因为该类已使用@Stateful(或@Stateless)注释进行注释,因此目的是在Java EE环境中执行该类,该类默认使用JTA事务.如果一个类将在Java SE环境中执行,则它不需要这样的注释.
在这种特殊情况下,我们如何知道应用程序管理的实体管理器?
因为我们使用@PersistenceUnit注释来注入EntityManagerFactory然后手动创建和销毁EntityManager.通过这样做,我们告诉Java EE容器我们不希望自动管理我们的事务(就像事务范围的实体管理器或扩展的实体管理器类型一样).
为什么em.joinTransaction()方法需要createLineItem?
通过调用em.joinTransaction()我们通知应用程序管理的持久性上下文它应该与当前的JTA事务同步.如果没有这样的调用,Order当事务提交时(在createLineItem方法结束时),更改将不会刷新到底层数据库.
注意:由于EntityManagerFactory实例是线程安全的而EntityManager实例不是,因此应用程序不得em.joinTransaction()在多个并发事务中调用同一实体管理器.