javax.persistence.TransactionRequiredException:没有可用的事务性 EntityManager
javax.persistence.TransactionRequiredException: No transactional EntityManager available
从昨天开始,我就一直在为这个异常而苦苦挣扎...我几乎检查了所有内容,用谷歌搜索了所有链接,但一无所获。
当我从类别服务调用 addCategory 或 removeCategory 时,我总是遇到异常 javax.persistence.TransactionRequiredException:没有可用的事务性 EntityManager。我附上了所有必要的配置文件。
我想让 Spring 处理交易。
jpaContext.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: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 - 在/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 - 片段,我在其中加载上下文
<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>
分类服务
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;
}
}
类别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 依赖项 - 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>
此致,
汤姆
编辑 - 解决方案
由于 M. Deinum 提供了一个解决方案,问题是,我把
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
在 jpaContext.xml 中,我没有加载所有 类(它们加载在 shopify-servlet.xml - 我的主要应用上下文中)。我将上面的行移动到我的主上下文 (shopify-servlet.xml),在那里我进行了组件扫描,它扫描并将所有控制器、服务、存储库加载到主上下文,所以现在 @Transactional 可以工作了:).
正如之前 post 已经指出的那样 - 永远不要混合这样的版本。
您可以使用 enforce/lock 到一个设定的版本,如果您使用简洁的 "bill of materials" (bom) 资源,您就不需要在多个位置指定这样的版本(使用清晰的遗漏某些东西的风险)- 此功能还会删除依赖关系树中的任何传递依赖关系。
如果您还需要 spring-security,您可以将其锁定到 springframework v4.0。2.RELEASE
- 根据 spring doco (http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/#maven-bom),这是已完全验证可用于 spring-security 3.2.5.RELEASE 的最大版本。当您使用 bom 时,所有 spring-security 的 springframework v3.2.8.RELEASE 资源将自动升级到 spingframework v4.0.2.RELEASE。
从昨天开始,我就一直在为这个异常而苦苦挣扎...我几乎检查了所有内容,用谷歌搜索了所有链接,但一无所获。
当我从类别服务调用 addCategory 或 removeCategory 时,我总是遇到异常 javax.persistence.TransactionRequiredException:没有可用的事务性 EntityManager。我附上了所有必要的配置文件。
我想让 Spring 处理交易。
jpaContext.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: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 - 在/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 - 片段,我在其中加载上下文
<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>
分类服务
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;
}
}
类别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 依赖项 - 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>
此致, 汤姆
编辑 - 解决方案
由于 M. Deinum 提供了一个解决方案,问题是,我把
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
在 jpaContext.xml 中,我没有加载所有 类(它们加载在 shopify-servlet.xml - 我的主要应用上下文中)。我将上面的行移动到我的主上下文 (shopify-servlet.xml),在那里我进行了组件扫描,它扫描并将所有控制器、服务、存储库加载到主上下文,所以现在 @Transactional 可以工作了:).
正如之前 post 已经指出的那样 - 永远不要混合这样的版本。
您可以使用 enforce/lock 到一个设定的版本,如果您使用简洁的 "bill of materials" (bom) 资源,您就不需要在多个位置指定这样的版本(使用清晰的遗漏某些东西的风险)- 此功能还会删除依赖关系树中的任何传递依赖关系。
如果您还需要 spring-security,您可以将其锁定到 springframework v4.0。2.RELEASE - 根据 spring doco (http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/#maven-bom),这是已完全验证可用于 spring-security 3.2.5.RELEASE 的最大版本。当您使用 bom 时,所有 spring-security 的 springframework v3.2.8.RELEASE 资源将自动升级到 spingframework v4.0.2.RELEASE。