Reputation: 495
I had a problem with persisting objects to the database using Spring 4.3, JPA 2.1 and Hibernate 5. Figured out something was wrong with transactions. Here is my configuration:
@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;
}
Here is my service. The code has run, no exceptions were thrown. But the object was not persisted to the database. I have intuitively understood that either something was wrong with a transaction creation (as the logger didn't show any transactions) or data was not committed to the database. EntityManagerFactory
was not null.
@Service
public class Manager {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Transactional
public void persist(Entity entity){
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.persist(entity);
}
}
After I replaced @Autowired EntityManagerFactory
with @javax.persistence.PersistenceContext EntityManager
, everything worked fine.
@Service
public class Manager {
@javax.persistence.PersistenceContext
private EntityManager entityManager;
@Transactional
public void persist(Entity entity){
entityManager.persist(entity);
}
}
Why doesn't it work with @Autowired EntityManagerFactory
?
Upvotes: 3
Views: 1707
Reputation: 124998
You are using Spring for transaction management and as such you want to get the current transactional EntityManager
. If you are injecting the EntityManagerFactory
and use it to get an EntityManager
you have a good change you end up with a new one, this new one isn't bound to the started transaction.
Instead inject the EntityManager
using @PersistenceContext
@PersistenceContext
private EntityManager em.
If you really want to inject the EntityMangerFactory
you have to use @PersistenceUnit
instead of @Autowired
. The @PersistenceUnit
is handled different then a plain @Autowired
.
@PersistenceUnit
private EntityManagerFactory emf;
Upvotes: 3