HibernateDaoSupport将hibernate的操作进行了大量的简化,但在使用HibernateDaoSupport里面自带的getHibernateTemplate()方法时要注意,当前的Session对象问题。
使用getHibernateTemplate()方法进行增与查时基本不会出现什么问题,使用save()和find(hql)就可以了。
今天在做实例更新与删除时,直接使用 getHibernateTemplate里的update和delete方法就出现了问题,总是显示当前对象未被更新,影响行数为0的错误,请教同学,找了半天的资料,终于明白getHibernateTemplate里操作的实例都是要求持久化的,而更新后的对象为脱管对象,没有进行持久化,无法进行更新操作,删除也是同理。
解决方法是创建自己创建Session对象,从Session中得到数据库中的旧实例,在外部进行set更新操作,再在Session中对更新过的旧实例进行更新或删除操作,提交事务就可以了。
事例代码:
public boolean update(Book book) {
Session session = this.getSession();
Book book1 = (Book) session.get(Book.class, book.getBookno());
session.beginTransaction();
book1.setAuthor(book.getAuthor());
book1.setIsbn(book.getIsbn());
book1.setName(book.getName());
book1.setNumber(book.getNumber());
book1.setPress(book.getPress());
book1.setPrice(book.getPrice());
book1.setTime(book.getTime());
book1.setRemark(book.getRemark());
session.update(book1);
session.getTransaction().commit();
session.close();
session.getTransaction().commit();
session.close();
return false;
}
在外部对从数据库中取出的持久化事务进行手动设置更新。
项目过程中还遇到另一个错误:No Hibernate Session bound to thread, and configuration does not allow creat
这个错误是说当前Session未找到与之绑定的线程,不允许进行事务操作。
这就涉及到了openSession和getCurrentSession的区别:
使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
}
在外部对从数据库中取出的持久化事务进行手动设置更新。
项目过程中还遇到另一个错误:No Hibernate Session bound to thread, and configuration does not allow creat
这个错误是说当前Session未找到与之绑定的线程,不允许进行事务操作。
这就涉及到了openSession和getCurrentSession的区别:
1 getCurrentSession创建的session会和绑定到当前线程,而openSession不会。
2 getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭
* 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()
创建的session则不会
* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()
创建的session必须手动关闭
使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
在 SessionFactory 启动的时候, Hibernate 会根据配置创建相应的 CurrentSessionContext ,在 getCurrentSession() 被调用的时候,实际被执行的方法是 CurrentSessionContext.currentSession() 。在 currentSession() 执行时,如果当前 Session 为空, currentSession 会调用 SessionFactory 的 openSession 。所以 getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法。
简单理解就是:
1. openSession 从字面上可以看得出来,是打开一个新的session对象,而且每次使用都是打开一个新的session,假如连续使用多次,则获得的session不是同一个对象,并且使用完需要调用close方法关闭session。
<property name="hibernate.current_session_context_class">jta</property>
在 SessionFactory 启动的时候, Hibernate 会根据配置创建相应的 CurrentSessionContext ,在 getCurrentSession() 被调用的时候,实际被执行的方法是 CurrentSessionContext.currentSession() 。在 currentSession() 执行时,如果当前 Session 为空, currentSession 会调用 SessionFactory 的 openSession 。所以 getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法。
简单理解就是:
1. openSession 从字面上可以看得出来,是打开一个新的session对象,而且每次使用都是打开一个新的session,假如连续使用多次,则获得的session不是同一个对象,并且使用完需要调用close方法关闭session。
2. getCurrentSession ,从字面上可以看得出来,是获取当前上下文一个session对象,当第一次使用此方法时,会自动产生一个session对象,并且连续使用多次时,得到的session都是同一个对象,这就是与openSession的区别之一,简单而言,getCurrentSession 就是:如果有已经使用的,用旧的,如果没有,建新的。