JPA中joinTransaction的使用 [英] Use of joinTransaction in JPA
问题描述
以下代码来自 JPA
规范.我不明白为什么在 createLineItem(intquantity)
中需要 em.joinTransaction()
.
The following code is from JPA
specs. I could not understand why em.joinTransaction()
is required in 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();
}
}
推荐答案
先说几句理论...
应用程序管理的实体管理器以两种方式之一参与 JTA 事务.
An application-managed entity manager participates in a JTA transaction in one of two ways.
- 如果持久化上下文是在事务内部创建的,持久化提供者将自动将持久化上下文与事务同步.
- 如果持久化上下文是较早创建的(在事务之外或已结束的事务中),持久化上下文可以通过调用
joinTransaction()
手动与事务同步joinTransaction()
code>EntityManager 接口.同步后,持久化上下文将在事务提交时自动刷新.
- If the persistence context is created inside the transaction, the persistence provider will automatically synchronize the persistence context with the transaction.
- If the persistence context was created earlier (outside of a transaction or in a transaction that has since ended), the persistence context can be manually synchronized with the transaction by calling
joinTransaction()
on theEntityManager
interface. Once synchronized, the persistence context will automatically be flushed when the transaction commits.
阅读上述定义后,可能会出现几个问题:
After reading the above definition a few questions may arise:
我们怎么知道
ShoppingCartImpl
参与了JTA 事务?
因为这个类已经用@Stateful
(或@Stateless
) 注释,因此目的是在默认情况下使用 JTA 事务的 Java EE 环境中执行类.一个类不需要这样的注解,如果它会在 Java SE 环境中执行.
how do we know that
ShoppingCartImpl
participates in JTA transaction ?
Because the class has been annotated with@Stateful
(or@Stateless
) annotation so the intention is to execute the class within Java EE environment which by default uses JTA transactions. A class doesn't need such annotation, if it will be executed in Java SE environment.
我们怎么知道在这种特殊情况下使用了应用程序管理的实体管理器?
因为我们使用 @PersistenceUnit
注释来注入EntityManagerFactory
,然后手动创建和销毁EntityManager
.通过这样做,我们告诉 Java EE 容器我们不希望我们的事务被自动管理(例如事务范围实体管理器或扩展实体管理器类型).
how do we know application-managed entity manager is used in this particular case?
Because we are using @PersistenceUnit
annotation to inject EntityManagerFactory
and then manually creating and destroying EntityManager
. By doing this we are telling Java EE container that we don't want our transaction to be automatically managed (like in case of transaction-scoped entity manager or extended entity manager types).
为什么在 createLineItem
方法中需要 em.joinTransaction()
?
通过调用 em.joinTransaction()
code> 我们通知应用程序管理的持久化上下文它应该与当前的 JTA 事务同步.如果没有这样的调用,当事务提交时(在 createLineItem
方法结束时),对 Order
的更改不会刷新到底层数据库.
注意:由于 EntityManagerFactory
实例是线程安全的而 EntityManager
实例不是,因此应用程序不得调用 em.joinTransaction()代码>在多个并发事务中的同一个实体管理器上.
why em.joinTransaction()
is required in createLineItem
method?
By calling em.joinTransaction()
we notify the application-managed persistence context that it should synchronize itself with the current JTA transaction. Without such call the changes to Order
would not be flushed to the underlying database when the transaction commits (at the end of createLineItem
method).
NOTE: since EntityManagerFactory
instances are thread-safe and EntityManager
instances are not, an application must not call em.joinTransaction()
on the same entity manager in multiple concurrent transactions.
这篇关于JPA中joinTransaction的使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!