【问题标题】:Get EntityManager using spring manual transaction management使用spring手动事务管理获取EntityManager
【发布时间】:2015-01-31 23:10:04
【问题描述】:

我有 PlatformTransactionManager 依赖项(实际上是 JpaTransactionManager)。我可以使用 TransactionTemplate 在事务中执行操作。但我不知道如何检索 EntityManager 以使用。

@Autowired PlatformTransactionManager transactionManager;

void doSomething() {
    TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            EntityManager entityManager = ???;
            // do work
        }
    });
}

相关配置如下:

@Bean
public DataSource dataSource() { ... }

@Bean
public FactoryBean<EntityManagerFactory> entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactory.setDataSource(dataSource());
    ...
    return entityManagerFactory;
}

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
    jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
    return jpaTransactionManager;
}

【问题讨论】:

    标签: java spring jpa transactions


    【解决方案1】:

    你可以注入它:

    @PersistenceContext
    private EntityManager entityManager;
    

    【讨论】:

      【解决方案2】:

      有一个名为EntityManagerFactoryUtils 的类,您可以从其中根据您在JpaTransactionManager 中配置的EntityManagerFactory 获取当前事务的实体管理器。

      例如:

      JpaTransactionManager tm = context.getBean(JpaTransactionManager.class);
      EntityManagerFactory emf = tm.getEntityManagerFactory();
      
      TransactionTemplate template = new TransactionTemplate(tm);
      template.execute(status -> {
          EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager(emf);
          Department department = new Department();
          department.setId(15);
          department.setName("Engineering");
          em.persist(department);
          return department;
      });
      

      【讨论】:

      • 我在一个用@Transactional 注释的函数中尝试了这段代码,EntityManagerFactoryUtils.getTransactionalEntityManager(emf) 返回了null。如果我尝试使用 @PersistenceContext 注释它不为空,但我不确定它是否是事务的正确 EntityManager。
      • 原来的问题是关于手动事务管理的。如果您的方法标记为@Transactional,那么您没有使用手动交易,使用此答案没有意义。
      • @EdwinDalorzo 你能指导如何在 Transactional 方法中获取 entityManager 引用吗?即来自当前活动的交易。因为我想将当前事务中的实体管理器注入 Hibernate Search 的 FulTextEntityManager。
      【解决方案3】:

      我实现了自己的简单交易模板:

      @Component
      public class JpaTransactionTemplate {
      
          @Autowired
          private EntityManagerFactory entityManagerFactory;
      
          public void execute(Consumer<EntityManager> consumer) {
              EntityManager entityManager = entityManagerFactory.createEntityManager();
              try {
                  EntityTransaction transaction = entityManager.getTransaction();
                  transaction.begin();
                  try {
                      consumer.accept(entityManager);
                      transaction.commit();
                  } catch (RuntimeException e) {
                      try {
                          transaction.rollback();
                      } catch (Exception rollbackException) {
                          e.addSuppressed(rollbackException);
                      }
                      throw e;
                  }
              } finally {
                  entityManager.close();
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-17
        • 1970-01-01
        • 1970-01-01
        • 2011-05-16
        • 1970-01-01
        • 2011-07-01
        • 2015-07-16
        相关资源
        最近更新 更多