先直接看起初写的代码:
public List findAll(Integer start, Integer limit) {
log.debug("finding all SipNews instances");
try {
String queryString = "from SipNews";
Query query = this.getSession().createQuery(queryString);
query.setFirstResult(start);
query.setMaxResults(limit);
return query.list();
} catch (RuntimeException re) {
log.error("find all failed", re);
throw re;
}
}
打眼一看好像是没啥问题,但是这个方法被连续调用3次以上后,程序就卡住了,成假死态。 阅读全文>>
最近在跟老狼做一个项目,框架用的是Spring MVC+Hibernate,大多使用注解方式(如:[Annotation方式实现AOP])进行的配置。 阅读全文>>
这几天使用Hibernate用的都是对HibernateSessionFacotry再次简单封装后的抽象类,前面两次出现的问题也都是出现在这个封装后的抽象类中。而我分析的时候没有给出这个抽象类的源码,以至于有些人可能看不明白。今天把这个封装后的完整代码贴出来,同时回答一下访客水漾的留言。
首先看看这位署名为水漾的朋友的留言。
看了你1月7号写的hibernate执行update()抛异常 有几个问题。
1:你从UserInfo表里查询出结果通过JSP显示,然后修改address之后你是把数据重新保存的还是覆盖从DB里拿出来的数据??
如果是覆盖的话,在映射文件的类标签上加上 dynamic-update=”true”可以提高效率。
2:在hibernate里事务的commit()或者rollback()不是都会关闭session吗?需要自己手动关闭吗?
答复:
1.是重新保存到一个对象中,并非覆盖之前的。dynamic-update=”true”这个属性我还没用过,多谢指教,我又学到点东西,嘿嘿。
2.Hibernate有时会自动关闭,有时不会。而我习惯上喜欢自己手工显示的将其关闭。从哪拿来的,用完就放到哪去,这是个好习惯,自夸一下,O(∩_∩)O哈哈~。
最后给出完整的代码。
package cn.ineeke.hibernate.dao;
import java.io.Serializable;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
/**
* 进一步封装HibernateSessionFacotry,减少代码书写量,提高效率。
*/
public abstract class BaseHibernateDAO {
private Session session = null;
public Session getSession() {
this.session = HibernateSessionFactory.getSession();
return session;
}
public void setSession(Session session) {
this.session = session;
}
public void closeSession(){
this.session = null;
HibernateSessionFactory.closeSession();
}
public Object get(Class clz,Serializable id){
Object obj = null;
Session session = this.getSession();
try {
obj = session.get(clz, id);
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
public void save(Object item){
Session session = this.getSession();
Transaction ts = null;
try {
ts = session.beginTransaction();
session.save(item);
ts.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
if(ts != null){
ts.rollback();
}
e.printStackTrace();
} finally{
this.closeSession();
}
}
public void update(Object item){
Session session = this.getSession();
Transaction ts = null;
try {
ts = session.beginTransaction();
session.clear();
session.update(item);
ts.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
if(ts != null){
ts.rollback();
}
e.printStackTrace();
} finally{
this.closeSession();
}
}
public void delete(Class clz,Serializable id){
Session session = this.getSession();
Transaction ts = null;
try {
ts = session.beginTransaction();
session.delete(this.get(clz, id));
ts.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
if(ts != null){
ts.rollback();
}
e.printStackTrace();
} finally{
this.closeSession();
}
}
}
这样一来我的DAO层具体实现类只需继承自该抽象类并实现相应的接口,具体的数据操作只需使用super.get()这样的方式即可,省了很多获取session,开启事物等操作。
在使用Hibernate执行delete()操作的时候又报出了org.hibernate.SessionException: Session is closed异常。有时候改程序中的错误也是很有意思的。先来看看delete()方法具体是如何写的。
public void delete(Class clz,Serializable id){
Session session = this.getSession();
Transaction ts = null;
try {
ts = session.beginTransaction();
session.delete(this.get(clz, id));
ts.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
if(ts != null){
ts.rollback();
}
e.printStackTrace();
} finally{
this.closeSession();
}
}
这里没错的呀!开始还好好的呀!想想我之前做过什么了…我之前为了解决[Hibernate执行update()抛异常] 对get()方法做了修改,执行完之后关闭了session,而这里的selete()方法也调用了它。于是把get()方法又改了回去,此时在进行delete()就又好了,但是update()就又出现之前的异常了。之后再次对update()方法进行修改,在其执行之前先进行session.clear(),这下才真的是一点问题都没了。看来人家前人的总结才是对的!我当时却还自以为是!聪明反被聪明误?