2009-11-28
昨天发现了一个问题:我的项目:
sturts1.2 hibernate3 spring2.5
使用注解
问题描述:先调用查询的方法,然后更新数据的时候报错:
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition. org.springframework.orm.hibernate3.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1186) org.springframework.orm.hibernate3.HibernateTemplate$14.doInHibernate(HibernateTemplate.java:718) org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419) org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374) org.springframework.orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:716) org.springframework.orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:712) dao.base.GenericDaoImpl.update(GenericDaoImpl.java:30) dao.Imp.WorkLogDaoImp.updateWorkLog(WorkLogDaoImp.java:44) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) java.lang.reflect.Method.invoke(Unknown Source) org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307) org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182) org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149) org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106) org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) $Proxy6.updateWorkLog(Unknown Source) service.Imp.WorkLogServiceImp.updateWorklog(WorkLogServiceImp.java:37) struts.action.DayWorklog.updateWorkLog(DayWorklog.java:175) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) java.lang.reflect.Method.invoke(Unknown Source) org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:270) org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:187) org.springframework.web.struts.DelegatingActionProxy.execute(DelegatingActionProxy.java:110) org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431) org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236) org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196) org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) javax.servlet.http.HttpServlet.service(HttpServlet.java:710) javax.servlet.http.HttpServlet.service(HttpServlet.java:803) org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
我想这个问题很多人都遇到了
看看源程序:
web.xml中
-----------------------------------------------------------------------
<!-- 使用spring解决hibernate因session关闭导致的延迟加载例外问题。 -->
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>filter.OpenSessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
-----------------------------------------------------------------------
action 中
------------------------------------------
public ActionForward updateWorkLog(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
PoolForm poolform = (PoolForm)form;
String time = poolform.getTime();
String fun = poolform.getFunction();
Integer id = poolform.getId();
//这里有查询 调用了dao类的方法
Worklog wl = workLogService.findByid(id);
if(fun.equals("turn"))
{
request.setAttribute("log", wl);
request.setAttribute("nowtime", time);
return mapping.findForward("update");
}else
{
String begin = poolform.getBegin();
String end = poolform.getEnd();
String content = poolform.getWorkcontent();
String object = poolform.getObject();
String scjd = request.getParameter("scjd"+id);
wl.setBegin(begin);
wl.setEnd(end);
wl.setObject(object);
wl.setScjd(Integer.parseInt(scjd));
wl.setWorkcontent(content);
wl.setDay(time);
//这里有更新方法 调用了dao的方法;
workLogService.updateWorklog(wl);
request.setAttribute("nowtime", time);
return mapping.findForward("addsus");
}
}
-------------------------------------------------
daoimp中
-------------------------------------
//查询方法
public Worklog findbyid(int id) {
this.getHibernateTemplate().setCacheQueries(true);
Object object = this.getObjectByCondition(" u.id="+id);
if(object !=null)
{
Worklog log = (Worklog)object;
return log;
}else
{
throw new IllegalArgumentException("没有日志 worklogdaoimp -->findbyid方法");
}
}
//更新的方法 使用了注解;
@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
public void updateWorkLog(Worklog wl) {
this.update(wl);
}
-------------------------------
报错:分析原因:
参考;http://www.iteye.com/topic/32001
http://www.iteye.com/topic/33507
解决方法:
web.xml中
<!-- 使用spring解决hibernate因session关闭导致的延迟加载例外问题。 -->
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
//自己写了一个过滤器 继承了opensessioninviewfilter覆盖了他的方法;
<filter-class>filter.OpenSessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
过滤器中:
package filter;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;
public class OpenSessionFilter extends OpenSessionInViewFilter{
protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
FlushMode flushMode = getFlushMode();
if (flushMode != null) {
//将flshmode的方法改为auto
session.setFlushMode(flushMode.AUTO);
}
return session;
}
}
问题解决;
end