Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get EntityManager using spring manual transaction management

I have PlatformTransactionManager in dependency (JpaTransactionManager actually). I can use TransactionTemplate to perform an action in the transaction. But I can't figure out, how do I retrieve EntityManager to use.

@Autowired PlatformTransactionManager transactionManager;

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

Here's related configuration:

@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;
}
like image 586
vbezhenar Avatar asked Dec 03 '14 11:12

vbezhenar


People also ask

How is @transactional implemented in Spring?

At a high level, Spring creates proxies for all the classes annotated with @Transactional, either on the class or on any of the methods. The proxy allows the framework to inject transactional logic before and after the running method, mainly for starting and committing the transaction.

Which annotation is used for transaction management in Spring?

tx:annotation-driven element is used to tell Spring context that we are using annotation based transaction management configuration. transaction-manager attribute is used to provide the transaction manager bean name.


2 Answers

There is a class called EntityManagerFactoryUtils from where you can obtain the current transaction's entity manager based on the EntityManagerFactory you configured in your JpaTransactionManager.

For example:

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;
});
like image 53
Edwin Dalorzo Avatar answered Nov 07 '22 21:11

Edwin Dalorzo


You can inject it with:

@PersistenceContext
private EntityManager entityManager;
like image 37
adlerer Avatar answered Nov 07 '22 19:11

adlerer