异常信息如下:
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL):
Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
at org.springframework.orm.hibernate4.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1135)
这种情况下是spring配置文件和springmvc配置文件分开进行配置的(下面还有在一个文件中进行配置的情况)。异常信息比较简单,保存的时候没有添加事务,所以添加时事务是处于read only状态的,无法进行保存,就报了这个异常,但是仔细查看了代码以及配置,事务相关的东西似乎都是完好的,没有问题,对这个问题比较纠结。
后经高人指点。有些眉目
第一种解决方案:
我在spring和springmvc中的配置文件中都有这么一句配置
<context:component-scan base-package="com.h3c.itac" />
在spring中该配置需要改为:
<context:component-scan base-package="com.h3c.itac" >
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
意思为在spring配置启动的时候不去扫描Controller
在springmvc中该配置改为:
<context:component-scan base-package="com.h3c.itac" >
<context:exclude-filter type="annotation" expression="......"/>
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
springmvc中的这个配置exculde的记不清是什么了,exculde和inculde是有先后顺序的,具体谁先谁后可以去实验一下。
第二种解决方案:
在dao层调用HibernateTemplate的execute方法,不要使用save,如下
public void saveSyslogAlarm(SyslogAlarm s){
this.getHibernateTemplate().execute(new HibernateCallback<T>() {
})
}
第三种解决方案:
只使用一种配置文件,也就是说只使用springmvc的配置文件(如果只使用spring配置文件是不行的,因为在配置springmvc前端控制器DispatcherServlet的时候,会去默认的路径下寻找名为action-servlet.xml的文件,/WEB-INF/action-servlet.xml)。
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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>SpringHibernateJsfTest</display-name>
<!-- 加载顺序 content-param -> listener -> filter -> servlet -->
<!-- <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/spring/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> -->
<filter>
<filter-name>encode</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>
</filter>
<filter-mapping>
<filter-name>encode</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
springmvc配置文件
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<import resource="/beans.xml" />
<!-- springmvc注解,必须配置 -->
<mvc:annotation-driven />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="jdbcUrl">
<value>jdbc:mysql://localhost:3306/itac</value>
</property>
<property name="user">
<value>root</value>
</property>
<property name="password">
<value>root</value>
</property>
<!--连接池中保留的最小连接数。 -->
<property name="minPoolSize" value="10" />
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="100" />
<!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="1800" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="5" />
<property name="maxStatements" value="1000" />
<property name="initialPoolSize" value="10" />
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60" />
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="30" />
<property name="breakAfterAcquireFailure" value="true" />
<property name="testConnectionOnCheckout" value="false" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.h3c.itac" />
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.hbm2ddl.auto=update
hibernate.connection.autocommit=true
hibernate.show_sql=false
hibernate.format_sql=false
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=false
hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
</value>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
<property name="nestedTransactionAllowed" value="true" />
</bean>
<bean class="com.h3c.itac.HibernateBaseDao"> </bean>
<tx:annotation-driven transaction-manager="txManager"
proxy-target-class="true" mode="proxy" />
<!-- 静态资源处理配置 -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources
in the /WEB-INF/views directory -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/" />
<property name="suffix" value=".jsp" />
</bean>
<import resource="/controllers.xml" />
</beans>
外部引用的controllers.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-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!--默认访问主页配置 -->
<mvc:view-controller path="/" view-name="home"/>
<context:component-scan base-package="com.h3c.itac" />
</beans>
本例使用的jar包有:
antlr-2.7.7.jar
aopalliance.jar
aspectj-1.8.3.jar
aspectjweaver-1.6.9.jar
c3p0-0.9.2.1.jar
commons-logging-1.0.4.jar
dom4j-1.6.1.jar
gson-2.2.4.jar
hibernate-c3p0-4.3.7.Final.jar
hibernate-commons-annotations-4.0.5.Final.jar
hibernate-core-4.3.7.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
javassist-3.18.1-GA.jar
jboss-logging-3.1.3.GA.jar
jboss-logging-annotations-1.2.0.Beta1.jar
jboss-transaction-api_1.2_spec-1.0.0.Final.jar
log4j-1.2.17.jar
mchange-commons-java-0.2.3.4.jar
mysql-connector-java-5.1.18-bin.jar
slf4j-api-1.6.1.jar
spring-aop-4.1.2.RELEASE.jar
spring-aspects-4.1.2.RELEASE.jar
spring-beans-4.1.2.RELEASE.jar
spring-context-4.1.2.RELEASE.jar
spring-core-4.1.2.RELEASE.jar
spring-expression-4.1.2.RELEASE.jar
spring-jdbc-4.1.2.RELEASE.jar
spring-orm-4.1.2.RELEASE.jar
spring-security-config-3.2.5.RELEASE.jar
spring-security-core-3.2.5.RELEASE-javadoc.jar
spring-security-core-3.2.5.RELEASE.jar
spring-security-web-3.2.5.RELEASE.jar
spring-tx-4.1.2.RELEASE.jar
spring-web-4.1.2.RELEASE.jar
spring-webmvc-4.1.2.RELEASE.jar
standard.jar