在JPA中使用joinTransaction [英] Use of joinTransaction in JPA
问题描述
以下代码来自 JPA
规范。我无法理解 createLineItem(int quantity)
中需要 em.joinTransaction()
。
The following code is from JPA
specs. I could not understand why em.joinTransaction()
is required in createLineItem(int quantity)
.
任何人都可以提供合适的解释吗?
Can anyone provide an apt explanation?
@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();
}
}
推荐答案
首先,理论上的几句话......
First, a few words of theory...
应用程序管理的实体管理器以两种方式之一参与JTA交易方法。
An application-managed entity manager participates in a JTA transaction in one of two ways.
- 如果在事务内创建持久化上下文,持久性提供程序将自动将持久性上下文与事务同步。
- 如果先前创建了持久性上下文(在事务之外或在已经结束的事务中),则可以通过调用
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
)注释进行注释,所以目的是为了在Java EE环境中执行该类,默认情况下使用JTA事务。如果一个类在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()
/ code>方法?
通过调用 em.joinTransaction()
,我们通知应用程序管理的持久化上下文它应该与当前的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屋!