javax.persistence.TransactionRequiredException: No transactional EntityManager available

11,168

As an earlier post already pointed out - NEVER mix versions like this.

You can use to enforce/lock down to a set version and if you use the neat "bill of materials" (bom) resource you remove the need to specify versions like this in multiple locations (with the clear risk of missing something down the track) - This feature also remove any transitive dependencies across your dependency tree.

If you also have a need for spring-security you can lock it down to springframework v4.0.2.RELEASE - According to spring doco (http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/#maven-bom) this is the max version that has been fully verified to work with spring-security 3.2.5.RELEASE. When you use the bom all spring-security's springframework v3.2.8.RELEASE resources will be brought up to spingframework v4.0.2.RELEASE automatically.

Share:
11,168
tomdavies
Author by

tomdavies

Updated on June 04, 2022

Comments

  • tomdavies
    tomdavies almost 2 years

    I'm struggling with this exception since yesterday... I checked almost everything, googled all links and I found nothing.

    I'm always getting an exception javax.persistence.TransactionRequiredException: No transactional EntityManager available when I call addCategory or removeCategory from category service. I attached all necessary configuration files.

    I want make Spring handle transactions.

    jpaContext.xml - in resources folder

    <?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:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
        xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
    
        <context:annotation-config />
    
        <context:component-scan base-package="com.example" />
    
        <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
    
        <bean id="emf"
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="persistenceUnitName" value="punit" />
            <property name="dataSource" ref="dataSource" />
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="showSql" value="true"></property>
                </bean>
            </property>
    
            <property name="jpaPropertyMap">
                <map>
                    <entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"></entry>
                    <entry key="hibernate.hbm2ddl.auto" value="create-drop"></entry>
                    <entry key="hibernate.format_sql" value="true"></entry>
                </map>
            </property>
        </bean>
    
        <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="emf" />
            <property name="dataSource" ref="dataSource" />
        </bean>
    
        <tx:annotation-driven transaction-manager="txManager" />
    
        <bean id="dataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <property name="url"
                value="jdbc:mysql://localhost:3306/shopify?autoReconnect=true" />
            <property name="username" value="root" />
            <property name="password" value="" />
        </bean>
    
    </beans>
    

    persistence.xml - in /META-INF/

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
     http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
        version="2.0">
    
        <persistence-unit name="punit">
    
        </persistence-unit>
    
    </persistence>
    

    web.xml - fragment, where I load contexts

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/jpaContext.xml
            /WEB-INF/security-config.xml
        </param-value>
    </context-param>
    

    category service

    package com.example.service;
    
    import java.util.Collections;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.example.dao.CategoryDao;
    import com.example.Category;
    
    
    @Service
    public class CategoryService {
    
        @Autowired
        @Qualifier("categoryDaoDatabase")
        private CategoryDao categoryDao;
    
        @Transactional
        public void addCategory(Category category) {
            category.setId(getLastCategoryId() + 1);
            categoryDao.addCategory(category);
        }
    
        @Transactional
        public void removeCategory(Category category) {
            categoryDao.removeCategory(category);
        }
    
        public void setCategoryDao(CategoryDao categoryDao) {
            this.categoryDao = categoryDao;
        }
    
    }
    

    category dao

    package com.example.dao;
    
    import java.util.List;
    
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;
    
    import org.springframework.stereotype.Repository;
    
    import com.example.domain.Category;
    
    
    @Repository
    public class CategoryDaoDatabase implements CategoryDao {
    
        @PersistenceContext
        private EntityManager entityManager;
    
        public void addCategory(Category category) {
            entityManager.persist(category);
            entityManager.flush();
        }
    
        public void removeCategory(Category category) {
            entityManager.remove(category);
        }
    
        public void setEntityManager(EntityManager entityManager) {
            this.entityManager = entityManager;
        }
    }
    

    Maven dependencies - pom.xml

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring4</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>1.9.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.7.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.7.Final</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.0.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
    </dependencies>
    

    Regards, Tom

    EDIT - solution

    As M. Deinum provided a solution, the problem was, that I put

    <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    
    <tx:annotation-driven transaction-manager="txManager" />
    

    in jpaContext.xml, where I didn't load all classes (they are loaded in shopify-servlet.xml - my main app context). I moved the above lines to my main context (shopify-servlet.xml), where I did component-scan, which scans and loads all controllers, services, repositories to the main context, so now @Transactional works :).

  • Ashish Ratan
    Ashish Ratan over 7 years
    where is the solution?