2

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!

  • can you also add application-context-spring.xml and application-context-service.xml – MyTwoCents Mar 20 '18 at 16:34
  • @Ashish451 You can already see the application-context-spring.xml above, while the application-wscontext-service.xml isn't really interesting for this problem and, as it contains only sensible information, I can't really do that. We only have to the webservices we use in the application. – DanielScott Mar 20 '18 at 16:38
  • possible duplicate https://stackoverflow.com/questions/32269192/spring-no-entitymanager-with-actual-transaction-available-for-current-thread – lucid Mar 20 '18 at 17:54
  • @lucid I've already came across that question but the proposed solution doesn't fit In this case. I already annotate all methods with Transactional but it doesn't seem to work :/ I wonder if that's even taken in consideration in the case the paths specified in Compone tScan aren't the right ones. – DanielScott Mar 20 '18 at 17:58
  • what's exactly you have in dao.impl package. I hope @Entity classes – lucid Mar 20 '18 at 18:04
  • @lucid Not at all. My entity classes are in the package com.xxx.y.entity, which is the one I specify in the method setPackagestToScan() for my entityManagerFactory. In com.xxx.y.rest.dao.impl I have, as you can guess, my DAOs implementations (or Repositories). You can see one example in my original question. Is that wrong? – DanielScott Mar 20 '18 at 18:19
  • that's correct only, my bad – lucid Mar 20 '18 at 18:28

0 Answers0