OA模块管理实现中出现的问题
前几天停下来整理了一下OA的部分代码,主要是struts部分,尤其是页面jsp和xml配置文件部分.
之前实现的:
(1)搭建SSH环境: jar包拷贝和冲突解决; 配置文件准备; Spring+Struts整合,在web应用启动时,创建spring的ApplicationContext实例; 编码问题CharacterEncodingFilter; Spring+Hibernate: OpenSessionInViewFilter, 配置sessionFactory, 配置事务, 配置数据库连接参数.
(2)实体层编写-->Hibernate映射文件的编写或生成-->Dao层接口抽象和实现-->Manager层接口抽象和实现-->ApplicationContext-daos.xml和ApplicationContext-managers.xml的编写
--之前进行到这里,我的剩余工作:
(3)ActionForm的编写-->Action的编写-->jsp页面的修改(在模板的基础上进行修改)
-->配置文件的编写: struts-config.xml和applicationContext-actions
要实现的模块: 组织机构(机构管理,人员管理),权限管理(模块管理,角色管理,用户管理)
大部分都是相似的代码:
Dao部分无非是增删改查: add*(), 删一个或删多个del*(), update*(), 查特定find*(), 分页查全部search*(), 以及各种查询.
Action主要是: 打开主页面,打开添加页面,添加,删除,有的还有打开更新页面,更新.
只有用户管理多一些分配角色的操作(打开角色列表页,打开分配角色页,分配角色,删除用户的角色).
代码测试过程中,遇到两大bug,很让人无语但绝对实用的bug:
(1)报Action里面MethodNotFoundException
--> 最后发现是Action里面的方法,我复制的unspecified(),它的修饰符为protected, 所以我其他的方法也都是protected, 然后就MethodNotFound了.
--> 解决:除override的unspecified()方法外,其他方法应为public
(2)让我从昨天晚上纠结到今天晚上的错误:
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.
-->尝试:在getHibernateTemplate().save(module);之前加上
getSession().setFlushMode(FlushMode.COMMIT);
有说在web.xml文件中加上init-param,如下:
<filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <init-param><param-name>FlushMode</param-name><param-value>COMMIT</param-value></init-param></filter><filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern></filter-mapping>
但是仍然报上面的错误, 可见, 这个设置对于我的保存操作/写操作并没有生效. 后来改用在getHibernateTemplate().save(module);之前加上 getSession().setFlushMode(FlushMode.COMMIT);
保存成功!
-->最终解决:applicationContext-common.xml中pointcut的配置"execution (* com.ys.oa.managers.*.*(..))",包名写错了.
因此,不属于这个pointcut范围内的方法,FlushMode被设置为Never/Manual;
pointcut范围内的方法,FlushMode为Commit/Auto.
-->还好,顺带理解一下session的FlushMode吧:
因为OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。故进行insert、 update和delete操作时会产生异常: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. 因此需要采用spring的事务声明,使方法受transaction控制:
<!-- 配置事务管理器 --><bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory"><ref local="sessionFactory"/></property></bean> <!-- 配置事务特性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="del*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="*" propagation="REQUIRED" read-only="true"/> </tx:attributes> </tx:advice> <!-- 配置那些类的方法进行事务管理 --> <aop:config> <aop:pointcut id="allManagerMethod" expression="execution (* com.ys.oa.managers.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/> </aop:config>
参考文档:http://blog.sina.com.cn/s/blog_59bc146c0100emn2.html
- 3楼lfmilaoshi昨天 13:28
- 这篇文章还是有深度的
- 2楼lfsf802昨天 23:35
- 写配置文件的时候一些内容还是要拷贝的比较好,避免一些手写的错误
- 1楼lb85858585昨天 21:15
- 事务的高度,交给了SpringAOP。理解很到位~