javax.persistence.TransactionRequiredException: No transactional EntityManager available
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.
tomdavies
Updated on June 04, 2022Comments
-
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 over 7 yearswhere is the solution?