当前位置: 首页 > 知识库问答 >
问题:

JPA中joinTransaction的使用

姜振濂
2023-03-14

下面的代码来自JPAspecs。我不明白为什么createlineitem(int quantity)中需要em.jointransaction()

有人能提供一个恰当的解释吗?

@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();
   }

}

共有1个答案

潘慈
2023-03-14

先说几句理论……

应用程序管理的实体管理器以以下两种方式之一参与JTA事务。

  1. 如果持久化上下文是在事务内部创建的,则持久化提供程序将自动将持久化上下文与事务同步。
  2. 如果持久性上下文是在较早时创建的(在事务外部或已结束的事务中),则可以通过在EntityManager接口上调用jointransaction()来手动将持久性上下文与事务同步。一旦同步,在提交事务时,持久性上下文将自动刷新。

阅读上述定义后,可能会产生一些问题:

>

  • 我们如何知道ShoppingCartimpl参与了JTA事务?因为该类已经用@statefult(或@stateless)注释注释了,所以其目的是在Java EE环境中执行该类,默认情况下Java EE环境使用JTA事务。一个类不需要这样的注释,如果它将在Java SE环境中执行。

    我们如何知道在这种特殊情况下使用了应用程序管理的实体管理器?因为我们使用@persistenceUnit注释注入EntityManagerFactory,然后手动创建和销毁EntityManager。通过这样做,我们告诉Java EE容器,我们不希望我们的事务被自动管理(就像事务范围的实体管理器或扩展的实体管理器类型的情况一样)。

    为什么createlineitem方法中需要em.jointransaction()?通过调用em.jointransaction(),我们通知应用程序管理的持久性上下文,它应该与当前的JTA事务同步。如果没有这样的调用,对order的更改将不会在事务提交时刷新到基础数据库(CreatelineItem方法的末尾)。注意:由于EntityManagerFactory实例是线程安全的,而EntityManager实例不是线程安全的,因此应用程序不能在多个并发事务中调用同一实体管理器上的em.jointransaction()

  •  类似资料:
    • 问题内容: 在JPA中,有一个名为的属性,可以根据此设置的含义设置该属性,有人可以举例说明可以在何处使用该属性吗? 问题答案: 在那里可以将另一列指定为另一张表的默认 ID 列,例如,考虑以下内容

    • 问题内容: 我已经打了一个拦截器将修复到现有project.the主要问题是,我一定会喜欢使用,并在照顾使用Hibernate实现JPA与会议现场(INSERT和UPDATE)。 原因? :需要进行此更改,因为有必要使用,而且我知道(因为我之前已经遇到过),liquibase使用默认的current_timestamp将时间戳转换为datetime,对于MySQL数据库来说太糟糕了。 所以我需要一

    • 问题内容: 我正在使用Struts 1.3 + JPA(使用Hibernate作为持久性提供程序)开发一个简单的“ Book Store”项目。我不能切换到Spring或任何其他更复杂的开发环境(例如Jboss),也不能使用任何特定于Hibernate的技术(例如,类)。 考虑到我处于JSE环境中,我需要显式管理整个EntityManager的生命周期。 该实体被定义如下: 我定义了三个类,分别负

    • 问题内容: 谁能指出我有关如何在JPA查询中使用的示例? 是在JPA中指定的,但我无法使其工作。我总是例外。既然在JPA中指定了它,那么所有提供商都应该遵守它吗? 我正在使用EclipseLink 2.0 BTW。 问题答案: 可以这样使用: … 建立的 是时间类型: 这不是一个很好的例子,但是您明白了。 我正在使用Eclipselink 1.1.2

    • 在我的应用程序中,我有一个场景,根据给定的输入代码和日期从实体中获取数据。代码和日期的组合将是唯一的,并将返回单个记录。 请建议。