使用 getSession().createSQLQuery(hql)后出现的奇怪BUG

来源:互联网 发布:淘宝情趣内衣评价大全 编辑:程序博客网 时间:2024/06/05 18:31

   最近在做一个项目,在开发过程中,遇到了各种奇葩问题。今天的问题其实昨天也遇到过,是个BUG,不过昨天发现了之后,做了点修改,以为能解决,没想到今天上午测试了下,还是一样的存在问题。

 现在说下BUG吧,某个页面我连续点击查找按钮7次后,第八次系统必定进入死锁状态,这时候tomcat工作是正常的,就是所有与数据操作有关的动作一律死锁,服务器端无任何输出错误信息和日志记录。我原以为是我写的SQL语句不够精简,导致连续访问数据库时出现死锁,所以我就优化了下我写的SQL语句,没想到还是存在BUG,就只能毫无头绪的BD了下,没想到皇天不负有心人,大海捞针也给我捞着了。有前辈和我遇到过同样的问题,这前辈还将解决的办法给贴出来了。

通过搜索资料才发现,getSession()得到的session不能自动关闭数据库连接,多次连接导致数据库连接池溢出,所有与数据库操作有关的动作都进入死锁状态,也不知道多长时间能恢复正常,最好的办法就是尽量不使用getSession(),用getHibernateTemplate().find()代替。

如果一定要使用getSession()这种原生态的session(这样获得的原生态session比getHibernateTemplate().find()功能多,比如分页查询),一定要手工调用close方法关闭。或者使用回调机制,让spring帮你关闭,代码如下:

public List findBySql(final String hql) {
List list = this.getHibernateTemplate().executeFind(new HibernateCallback() {

public Object doInHibernate(Session arg0) throws HibernateException,
SQLException {
Query quer = arg0.createSQLQuery(hql).addEntity("tscourse",StuTeacherCourseRela.class)
       .addJoin("cour", "tscourse.course"); 
List result = quer.list();
return result;
}
});
    return list;
}

如上面代码中表达的一样,在你要使用getSession().createSQL的方法,使用 this.getHibernateTemplate().executeFind,并将getSession().createSQL放在回调函数里执行。这时候我们就不需要手动关闭session了,spring会自动处理。当然,二货的我在这么改了之后居然有问题,在注释了web.xml中重写的错误页面转换之后,总算看到了错误的提示

Caused by: java.lang.ClassCastException: java.lang.Long
org.hibernate.type.IntegerType.set(IntegerType.java:64)
这个错误简单啊,很容易就找到了,原来是映射文件中的类型和实体类的类型不一致,再次感叹,敲代码要认真啊。
资料的来源:
点击打开链接

0 0