hibernate缓存 2016-07-11

照例,先啰嗦下。今天还是测试资料中写的表单提交前校验的功能。一开始是按照资料写的,但是始终不成功,怎么说呢,前几次好好的,后来就不行了,doSubmit调用doVerify方法,但是就是进不去doVerify方法中。我尝试过把资料的内容复制到自己那里,看是不是自己写的不对导致的,结果即使把资料复制进去还是不行。只能用form的onsubmit属性,在表单提交前校验。

规则应该是这样的:在添加页面,只传account值到action,而在修改页面,要传account和id的值到action。这两个页面的表单校验共用一个方法,也就要求这个方法内部的逻辑是先判断有没有id这个值,有的话执行 FROM User WHERE account = ? AND id != ?  没有的话执行FROM User WHERE account = ?,最后统一返回List<>,在action中判断List若有内容,则重复了,就阻止表单提交。

所以,我要测试的是,在修改页面,如果我什么都不改,点击保存后可以保存,但它却提醒我存在重复账户名。按理说,数据库中当然有这个id对应的同名账户名,但我后台的逻辑就是要id!=? 来查询。试过将!=改为<>也不行。

想到有人说过调试先看前端的数据是否正确的传递到后台的说法。我就在action中打印传入的id和account。结果也显示没问题控制台打印显示如下:

402882e555c9e6810155c9e837b10001
admin
FROM User WHERE account = ? AND id != ?
Hibernate: select user0_.id as id0_, user0_.name as name0_, user0_.dept as dept0_, user0_.account as account0_, user0_.password as password0_, user0_.headImg as headImg0_, user0_.gender as gender0_, user0_.email as email0_, user0_.mobile as mobile0_, user0_.birthday as birthday0_, user0_.state as state0_, user0_.memo as memo0_ from user user0_ where user0_.account=? and user0_.id<>?

一看打印的hql语句和执行的查询语句都没问题啊,id和account都是正确的。

但打印出来List的size是1,也就是查询到了数据,就很奇怪了。

搜索了下“hibernate查询与数据库查询不同”,找到的说法是手动修改数据库,会导致hibernate查询与在数据库查询不一致。

关键点就是hibernate的缓存机制。大体思想就是:我们通过Hibernate查询,它为了提高效率,将每次操作的结果会缓存到session中,也就是hibernae的一级缓存,以后操作数据库,会先从缓存中查找,不行再去数据库,所以如果在数据库手工插入等操作后,由于hibernate会先从缓存找,所以就会出现同样的语句,与在数据库查询结果不一致。这是可以得到session然后session.flush() 这是刷新一级缓存,也可以先session.clear()先清除缓存。但对缓存的清除和刷新都得在createQuery()前完成。

具体的参考会附在文末。

继续我的故事:我在学习到这些之后,恍然大悟。我为了测试,手工在数据库添加了一条记录,这条记录的account和前一条相同但id不同。当我在页面进入点击这条新记录的编辑按钮时,进入修改页面,什么都不修改,点击保存,应该会查询出只有一条数据,然后提示有同名account,但控制台打印的list却有两条。

所以我才恍然大悟,恰好我确实手工修改了数据库,以为是hibernate的缓存问题。我在dao中的方法内写上缓存的清空与刷新。但很不幸结果还是一样。

我确实纳闷了,我开始想要不要重新想个逻辑重写这个方法,反正只要功能一样就行。

我就开始思考在入参不变的情况下,id和account该怎么写。突然看见

if(StringUtils.isNotBlank(id)){
query.setParameter(1, account);
}

突然惊醒!我还真是够傻,当时if体内的语句可能是复制粘贴的,只记得修改参数索引改为1,忘了修改后面引用值,应该是将id赋给第二个参数-_-||

虽然犯了一个很白痴的问题,但是能找到问题所在,把问题解决也很开心。而且还看了好多hibernate缓存的知识。

最后,把if内语句修改后,果然成功了。然后,记得在查hibernate缓存问题的时候,看到过缓存在事物提交后会自动flush,而我的hibernate事物是配置到spring中了,而且我的dao是继承的HibernateDaoSupport,在spring配置好声明式事务后会自动提交,所以,为了实验,我把写上的flush与clear都注释掉,在数据库手动修改,结果是可以查询到的。


参考:

http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html

http://blog.csdn.net/rogerjava/article/details/8513565

http://www.iteye.com/problems/87489

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值