我有一段使用hibernate的代码,表现出意外;在尝试了许多不同的调试策略之后,我想知道我对Hibernate会话/映射对象更新的理解是否不正确。以下是简化方案:
我有一个映射对象(MO),它使用id(长整数)和日期(日期/时间)定义。 有一个主程序每60秒运行一次,根据日期/时间检查需要处理的任何MO。主例程在单个线程中运行。这是伪代码:
main ()
// open session
// get current date/time
// query all mapped objects where date/time field < current date/time
// for each mapped object which matches {
// updateObject (session, current date/time, mapped object)
// }
// flush session
// close session
updateObject( Session s, Date currentTime, MappedObject mo )
// changes to mo object
// add 1 day to currentTime and update date/time field in mo
// transaction begin
// update mo object
// transaction committed
未显示:会话工厂初始化,异常处理例程
会话工厂配置的最大连接池大小为20(c3p0)。 默认设置用于任何缓存。
问题
查询返回日期值为未来的MO(即日期/时间字段&gt; 当前日期/时间)。根据对象监视,MO中日期/时间字段的值是旧的先前值(不是重新计算的更新值),这会强制查询获取它并执行updateObject例程。
我认为通过直接监视DB来验证更新是否成功;此外,根据日志不会触发任何事务异常。
这个问题间歇性地发生 - 有时候,它每天发生几次,有时则根本不会发生。
平台详细信息
Hibernate版本:3.3.2.GA
c3p0版本:0.9.1
JRE版本:1.6.0_16
我的想法
我的第一个想法是编码错误,但它似乎不是基础。我想知道是否某个旧版本的对象缓存在连接池中的一个Session对象中,并且出于某种原因,它会不时地被拾取。
如果更新出现问题,我担心会产生更大的影响。
我目前正在使用旧版本的Hibernate - 迁移到新版本可能具有挑战性,但我想看看在走这条路线之前我是否误解了一些东西。
对结果的任何建议或指示都将非常感谢 - 提前感谢!
更新
迁移到Apache DBCP似乎已经解决了这个问题。如果再次发现问题,将更新。
答案 0 :(得分:0)
你可以尝试两件事......
1)设置以下Hibernate属性以关闭语句缓存: -
<property name="hibernate.c3p0.max_statements">0</property>
如果那不起作用......
2)尝试Apache DBCP而不是使用C3P0,看看你是否有同样的问题。它应该很容易换掉。