struts2+hibernate改造考勤系统备忘录(一)

注释:/这是一个逐步分析的过程,前半场存在分析定义错误,后半场后对前面
的分析进行颠覆的分析与定义

问题描述:登陆操作发生
Messages:
www.hibernate.org Nested exception: www.hibernate.org
Could not parse configuration: hibernate.cfg.xml
Method “execute” failed for object com.action.LoginAction@137b6789
从字面上看,应该是配置文件加载错误,因为没有联网,导入的DTD是联网形式的
执行动作:将DTD改为本地资源
执行结果:猜想正确,hibernate 和struts 情况不一样struts2可以在本地智能获取,

而hibernate 在网上获取不到,将会报错

问题描述:局部测试hibernate 没有问题,但是和struts2 整合,还是会报错
root/web/apache-tomcat-7.0.70/bin/src/com/dtd/hibernate-configuration-3.0.dtd (
?????????) Nested exception: /root/web/apache-tomcat-7.0.70/bin/src/com/dtd/
hibernate-configuration-3.0.dtd (?????????)
Could not parse configuration: /hibernate.cfg.xml
Method “execute” failed for object com.action.LoginAction@6e544d87
这些都是表层错误
追到底层,UserServiceIpml->UserDaoIpml
发现这个错误
failed to lazily initialize a collection of role: com.po.User.sendclassesById, no session or session was closed
对,就是session 被提前关闭,因为采用的是opension,在DAO层用了开启session
关闭session,而在impl 调用了返回的一级缓存内容,看一下DAO层是如何写的

Session session=Main.getSession();
User user=(User) session.get(User.class,id);
session.close();
return user;
所以关闭以后,在返回一级缓存内的对象,已经没有了

解决方法统一采用当前线程,调用完不关闭,避免多次开启关闭session操作
解决方法一失败:因为当前线程,调用get 方法失败。。似乎使用当前线程
无法调用,get 方法,问题原因,当前线程模式,需要调用事务才能调用get
方法,而且如果不设置二级缓存(get 可以放到二级缓存内),事务提交后
对象将随着事物的提交而消失
解决方法,在sesion 外定义对象 ,关闭sesion 返回对象
上一个解决方法失败,因为对象赋值付给的是引用
所以,仍然会被删除,接下来解决方法也就明亮了,开启二级缓存和查询缓存
最终解决方法:开启二级缓存和查询缓存,查询缓存依赖与二级缓存,
查询缓存与二级缓存的区别与联系,二者结构都是MAP,但是二级缓存中
key 是PO类的id ,而查询语句的key 是hql语句,所以特点是HQL只要有一点不一样,就会
从新在数据库提取数据
解决结果,成功
问题延伸:
user=(User)query.uniqueResult();
System.out.println(user);
session.close();
System.out.println(user);

如果不写第一个输出,第二个输出将会报错,
起初以为是懒加载的问题,但是类本身默认是不进行懒加载,重写了一下,
结果证明,这个“懒加载不是在类映射文件中配置的”
因为查询缓存,是在调用的时候进行加载

接下来说明一个有关,struts2和hibernate 整合的相关问题

问题描述:在解决上述缓存的 问题后,出现一个新的问题,struts2单元测试没问题
hibernate 单元测试也没有问题,但是当通过struts2 的action 调用
hiberante 的Dao的时候,会显示无法解析hibernate的配置文件

Could not parse configuration: /hibernate.cfg.xml
起初我以为,单元测试的时候,导入本地的dtd文件可以用呀,可以查询数据
但是一旦和sturts2 整合,就会爆出不能识别DTD,说明struts2是不接受
hibernate 用绝对路径进行导入dtd的形式,
那么问题来了,看看我之前采用什么方式导入DTD
http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd“>

归结原因是因为hiberante版本问题,在高版本的用上面的可以,
在低版本的用上面的,在不联网的时候就会报错,联网时启动特别慢
对,我的就是低版本我用的hibernate3,而我的hiberanate 的配置文件总喜欢在
高的版本中拷贝。。。。。
后来找到低版本中,可以用这个
http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd
低版本用这个,联网断网都可以用,所以在和struts整合的时候也就没问题了
现在看来问题是完美解决了

可是,发现一个颠覆的事情
当发现更改了hibernate 的DTD的文件后,session关闭后,可以拿到数据了
。。。。
(PS:看到没有,思维定势了把,什么是缓存,关闭session拿不到一级缓存
再看一下:对象的三种状态,临时状态,持久化,游离状态,
对象的状态和缓存的关系
如果一个对象是持久化状态,说明该对象在一级缓存中
如果一个对象是脱管状态的对象,说明该对象已经从一级缓存中清除了

所以,关闭session 后,缓存中的对象,变成游离对象,使可以返回的
不需要利用查询缓存或者二级缓存

再次整合,经过以上的错误,成功整合并调试成功

看来现在似乎差不多了,经历了开始的曲折到现在,再来试试把
总结:80%的BUG是由于粗心导致的,而不是有多难的技术难题
=====================================================================
接下来两天,利用已经搭建好的框架,和用户实现技术,将课程,班级,以及
为班级指派学生,的模块进行实现

工作进度: 课程的DAO 和SERIVCE 已经做好,下一步做CourseAction

问题描述: 在映射文件中配置字段默认值
解决过程,在映射文件中试了一下,不是我想要的效果,在数据库表中对字段
设置了默认值,但是通过表生成的持久化类和映射文件,并没有体现相应的生成
效果,好像看到一种在持久化类中,用注解的方式可以实现这种效果,上述的
表生成,没有产生相应的注解
所以采用在数据库表中设置字段的默认值来解决这个问题

值得一提的在映射文件中,可以配置,只修改持久化对象内有参的属性
误参数的,可以设置默认值或者设置null,可以设置的操作类型是插入或者

更新

问题描述:将添加用户界面中的password 文本域去掉之后,提交过程失败
发现结果: 粗心的在User持久化类的映射文件中的password字段设置了
not-null=”true”
所以报错了

下一步完善 Course 各个模块

问题描述,调用CourseDaoImpl 传参 删不掉Course,但是在方法内部
用get 却可以
解决方法,这个问题,因为UserDao是可以用传User 的方式进行删除
所以我比较了Course 和User 的持久化类 映射文件和数据库的表,发现没有什么不同
所以我认为是参数 Course 和在和delete同一个session 中get 获取的对象状态或者
对象结构有所不同,因为发现传参Course 的内容,和要删除的对象内容一样
所以在删除函数内部,调用session.get方法 传参的对象调用get.id传入获取要删除的

对象 ,这样就可以删除了

下一步工作内容,现在用户和课程管理模块基本已经完成
下一步,改装分班和班级模块

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值