I know this issue has been already largely discussed but none of the solutions proposed on other topics here could actually help.
Context: here at work we've been just setting up hibernate on our spring project. The project is pretty old so we're mixing XML and Java config.
I'm having the following error when trying to persist an object:
javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
My web.xml has
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.xxx.y.configuration.AppConfig</param-value>
</context-param>
my AppConfig.java
@Configuration
@Import({ JpaConfig.class })
@ImportResource( { "/WEB-INF/config/application-context-spring.xml", "/WEB-INF/config/application-wscontext-service.xml" })
@ComponentScan(basePackages={"com.xxx.y.*"}, excludeFilters = @Filter(type = FilterType.ANNOTATION, value = Configuration.class))
public class AppConfig {
@Bean
public DozerBeanMapper dozerBeanMapper() {
return new DozerBeanMapper();
}
}
my JpaConfig.java
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.xxx.y.rest.dao.impl"}, entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager")
@ComponentScan(basePackages={"com.xxx.y.rest"}, excludeFilters = @Filter(type = FilterType.ANNOTATION, value = Configuration.class))
public class JpaConfig {
@PersistenceContext(unitName = "PersistenceContext")
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource());
entityManagerFactory.setPersistenceUnitName("PersistenceContext");
entityManagerFactory.setPackagesToScan(new String[] { "com.xxx.y.entity" });
entityManagerFactory.setJpaVendorAdapter(jpaAdapter());
entityManagerFactory.setJpaProperties(additionalProperties());
return entityManagerFactory;
}
@Bean
public DataSource dataSource() throws NamingException {
return (DataSource) new JndiTemplate().lookup("java:comp/env/jdbc/XYZ");
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", org.hibernate.dialect.Oracle10gDialect.class.getName());
return properties;
}
@Bean
public String jpaDialect() {
return org.hibernate.dialect.Oracle10gDialect.class.getName();
}
@Bean
public HibernateJpaVendorAdapter jpaAdapter() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.ORACLE);
vendorAdapter.setDatabasePlatform(jpaDialect());
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(true);
return vendorAdapter;
}
}
and here's the DAO
@Repository
public class DAOImpl extends CommonDAO implements DAO{
@PersistenceContext(unitName = "PersistenceContext")
EntityManager entityManager;
@Override
@Transactional
public void create(StationFare fare) {
entityManager.persist(fare);
}
The method create is the one causing the problem here.
and this is what we have in application-context-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- Enable the annotation usage (bean injection for instance) -->
<context:annotation-config />
</beans>
Some heritage from the old xml config, not sure whether is still needed.
So, this is it. I wonder if my @ComponentScan annotations have the right paths. I tried them all so I'll be glad if someone could help and don't hesitate asking for more details if needed. Thanks a lot!