新搭建了一个 Spring MVC+Spring Data JPA+Hibernate的一个工程
在DAO的方法之上加了注解@Query、@Modifying,但是在运行过程中一直抛出
javax.persistence.TransactionRequiredException: Executing an update/delete query 的异常,实在无力了,希望有大大来帮助
2015-04-29 23:44:12,534[INFO ]com.mchange.v2.log.MLog:MLog clients using slf4j logging.
2015-04-29 23:44:12,747[INFO ]com.mchange.v2.c3p0.C3P0Registry:Initializing c3p0-0.9.5 [built 02-January-2015 13:25:04 -0500; debug? true; trace: 10]
2015-04-29 23:44:13,142[INFO ]org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean:Building JPA container EntityManagerFactory for persistence unit 'elev'
2015-04-29 23:44:14,041[INFO ]com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource:Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hgeby9991mfjmq1wjzcl2|66c88fce, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceUseNamedDriverClass -> false, identityToken -> 1hgeby9991mfjmq1wjzcl2|66c88fce, idleConnectionTestPeriod -> 0, initialPoolSize -> 20, jdbcUrl -> jdbc:mysql://localhost:3306/elev, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 45, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 10, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
2015-04-29 23:44:15,422[DEBUG]org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler:Creating new EntityManager for shared EntityManager invocation
2015-04-29 23:44:15,496[DEBUG]org.springframework.orm.jpa.EntityManagerFactoryUtils:Closing JPA EntityManager
2015-04-29 23:44:15,521[DEBUG]org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler:Creating new EntityManager for shared EntityManager invocation
2015-04-29 23:44:15,521[DEBUG]org.springframework.orm.jpa.EntityManagerFactoryUtils:Closing JPA EntityManager
2015-04-29 23:44:15,763[DEBUG]org.springframework.transaction.annotation.AnnotationTransactionAttributeSource:Adding transactional method 'BusinessUserServiceImpl.editUser' with attribute: PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED; 'transactionManager'
2015-04-29 23:44:15,982[DEBUG]org.springframework.transaction.annotation.AnnotationTransactionAttributeSource:Adding transactional method 'BusinessUserServiceImpl.editUser' with attribute: PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED; 'transactionManager'
从日志上看,好像事务已经加上了。。。
以下是工程部分代码:
applicationContext-main.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"
xsi:schemaLocation="
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.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.feinno">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<import resource="applicationContext-profile.xml"/>
<import resource="applicationContext-jpa.xml"/>
<import resource="applicationContext-mvc.xml"/>
</beans>
applicationContext-mvc.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.feinno">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="prettyPrint" value="true" />
<property name="supportedMediaTypes">
<list>
<value>application/json</value>
<value>text/html</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
</beans>
applicationContext-profile.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"
xsi:schemaLocation="
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.xsd">
<beans profile="dev">
<context:property-placeholder
ignore-resource-not-found="true" location="classpath:/config/dev.properties" />
<bean id="configProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:/config/dev.properties</value>
</list>
</property>
</bean>
</beans>
<beans profile="test">
<context:property-placeholder
ignore-resource-not-found="true" location="classpath:/config/test.properties" />
<bean id="configProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:/config/test.properties</value>
</list>
</property>
</bean>
</beans>
<beans profile="pro">
<context:property-placeholder
ignore-resource-not-found="true" location="classpath:/config/prod.properties" />
<bean id="configProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:/config/prod.properties</value>
</list>
</property>
</bean>
</beans>
<beans>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="minPoolSize" value="10" />
<property name="maxPoolSize" value="45" />
<property name="initialPoolSize" value="20" />
</bean>
</beans>
</beans>
applicationContext-jpa.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:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="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.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<jpa:repositories base-package="com.feinno.elev.interfaces" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="elev" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="showSql" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="database" value="MYSQL" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.feinno.elev.interfaces.model</value>
</list>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="dataSource" />
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
</property>
</bean>
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />
</beans>
Dao
package com.feinno.elev.interfaces.business.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.feinno.elev.interfaces.model.BusinessUser;
@Repository
public interface BusinessUserDao extends JpaRepository<BusinessUser, String> {
@Modifying
@Query("update BusinessUser set password='123456' where userName=?1")
public void edit(String userName);
@Modifying
@Query(value="delete from sys_accesspro where accessuser = ?1",nativeQuery=true)
public void delete(String userName);
}
Service
package com.feinno.elev.interfaces.business.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.feinno.elev.interfaces.business.dao.BusinessUserDao;
import com.feinno.elev.interfaces.business.service.BusinessUserService;
import com.feinno.elev.interfaces.model.BusinessUser;
import com.feinno.elev.util.CommonUtil;
@Service
public class BusinessUserServiceImpl implements BusinessUserService{
@Autowired
BusinessUserDao businessUserDao;
@Override
public BusinessUser validUser(String userName,String password,String serviceId,String key){
BusinessUser businessUser = businessUserDao.findOne(userName);
if(CommonUtil.isNotEmpty(businessUser)){
if(!businessUser.getPassword().equals(password)||!businessUser.getServiceId().equals(serviceId)||!businessUser.getKey().equals(key)){
return null;
}
}
return businessUser;
}
@Transactional(isolation=Isolation.READ_COMMITTED,readOnly=false,propagation=Propagation.REQUIRED,value="transactionManager")
@Override
public void editUser(String userName) {
BusinessUser bu = new BusinessUser();
bu.setUserName(userName);
businessUserDao.edit(userName);
}
@Override
public void deleteUser(String userName) {
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="false" version="3.0">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/applicationContext-main.xml
</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
<filter>
<filter-name>ParseRequestFilter</filter-name>
<filter-class>com.feinno.elev.interfaces.filter.ParseRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ParseRequestFilter</filter-name>
<url-pattern>/dispatcher</url-pattern>
</filter-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>