javax.persistence.TransactionRequiredException:没有可用的事务性EntityManager

时间:2015-01-15 09:37:39

标签: spring hibernate jpa orm transactions

我从昨天起就一直在努力解决这个问题...我检查了几乎所有内容,用Google搜索了所有链接,但我什么也没找到。

当我从类别服务中调用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工作:)。

1 个答案:

答案 0 :(得分:0)

正如之前的帖子已经指出的那样 - 永远不要混合这样的版本。

您可以使用强制/锁定到设置版本,如果您使用简洁的“物料清单”(bom)资源,则无需在多个位置指定此类版本(明显存在丢失某些内容的风险)沿着轨道) - 此功能还会删除依赖关系树中的任何传递依赖项。

如果您还需要弹簧安全性,可以将其锁定到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。