【问题标题】:Why didn't @Transactional work with @Autowired EntityManagerFactory?为什么@Transactional 不能与@Autowired EntityManagerFactory 一起使用?
【发布时间】:2016-02-28 18:49:46
【问题描述】:

我在使用 Spring 4.3、JPA 2.1 和 Hibernate 5 将对象持久化到数据库时遇到了问题。 发现交易有问题。 这是我的配置:

@Configuration
@EnableTransactionManagement
public class PersistenceConfig {

   /**
     * most bean methods skipped, left only the relevant ones
    **/


    @Bean
    @Autowired
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter){
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource);
        entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        entityManagerFactoryBean.setPackagesToScan("com.company");
        entityManagerFactoryBean.setJpaProperties(jpaProperties());
        return entityManagerFactoryBean;
    }

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

这是我的服务。代码已经运行,没有抛出异常。但是该对象没有持久化到数据库中。我直观地理解,要么事务创建有问题(因为记录器没有显示任何事务),要么数据没有提交到数据库。 EntityManagerFactory 不为空

@Service
public class Manager {

@Autowired
private EntityManagerFactory entityManagerFactory;

@Transactional
public void persist(Entity entity){
    EntityManager entityManager = entityManagerFactory.createEntityManager();
    entityManager.persist(entity);
}

}

在我将@Autowired EntityManagerFactory 替换为@javax.persistence.PersistenceContext EntityManager 后,一切正常。

@Service
public class Manager {

@javax.persistence.PersistenceContext
private EntityManager entityManager;


@Transactional
public void persist(Entity entity){
    entityManager.persist(entity);
}

}

为什么它不适用于@Autowired EntityManagerFactory

【问题讨论】:

  • 因为您正在使用它创建一个新的EntityManager,它不是事务实体管理器,因此在用于调用persistEntityManager 上没有提交。通过自动连接EntityManager,您将获得事务性EntityManager
  • @M.Deinum:您能否添加您的评论作为答案,以便我接受?

标签: java spring hibernate jpa entitymanager


【解决方案1】:

您正在使用 Spring 进行事务管理,因此您希望获得当前的事务EntityManager。如果您要注入EntityManagerFactory 并使用它来获得EntityManager,那么您有一个很好的更改,您最终会得到一个新的,这个新的不会绑定到已启动的事务。

而是使用@PersistenceContext 注入EntityManager

@PersistenceContext
private EntityManager em.

如果你真的想注入EntityMangerFactory,你必须使用@PersistenceUnit 而不是@Autowired@PersistenceUnit 的处理方式与普通的 @Autowired 不同。

@PersistenceUnit
private EntityManagerFactory emf;

【讨论】:

  • @m-deinum 只是为了确定。 EntityManager 应该只使用 PersistenceContext 注释注入 Spring 服务或存储库,而不是 Autowired。对吗?
  • 虽然两者都可以在基于 Spring 的应用程序中工作,但请坚持使用通用 JPA 方式并使用 @PersistenceContext
  • @m-denium,@Autowired 是否为每个事务创建单独的 EntityManager(就像 @PersistenceContext 一样),而不是为整个应用程序创建一个 EntityManager bean?
  • 是的,它的工作原理是一样的,你会得到一个代理,它会在需要时创建一个线程绑定EntityManager
猜你喜欢
  • 1970-01-01
  • 2013-09-01
  • 2016-02-23
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2018-03-09
相关资源
最近更新 更多