Spring Hibernate Session问题
整合Spring,Hibernate在进行DAO操作时,
有一个POJO类Image存放图片。
有一个ImageDAO.insert方法把数据保存至数据库。
如果ImageDAOImpl类继承HibernateDaoSupport类public class ImageDAOImpl extends HibernateDaoSupport implements ImageDAO {
public void insert(Image transientInstance) {
getHibernateTemplate().save(transientInstance);
}
}在进行保存时没有发生异常。正确虽然代码简介,但dao类与spring框架api发生了耦合,一旦脱离Spring框架这些dao代码就得不到重用。
所以把dao类全部基于Hibernate实现,不加入Spring的代码public class ImageHibernateDAO implements ImageDAO { private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
} public void insert(Image image) {
// Session session = sessionFactory.getCurrentSession();
Session session = sessionFactory.openSession();
System.out.println(session);
Transaction transaction = session.beginTransaction();
session.save(image);
transaction.commit();
}
}对每次操作都得建立一个session,操作完毕又销毁session,性能方法也有一定的开销。
SessionFactory.getCurrentSession是不是一个线程对应一个Session呢?如果这样效率就高一点。但是碰到的问题是抛出了异常Exception in thread "main" org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean$TransactionAwareInvocationHandler.invoke(AbstractSessionFactoryBean.java:300)
at $Proxy0.getCurrentSession(Unknown Source)在网上找了半天,也没解决问题的办法。请您帮忙解答一下。
谢谢

解决方案 »

  1.   

    好像是一个事务对应一个session,
    用的时候需要打开,不用的时候要关闭;
    也可以用过滤器来实现session的开关。
      

  2.   

    那该如何配置呢?
    初学Spring和hibernate
      

  3.   

    如果想这么使用,就要利用ThreadLocal来管理Session,
    public static final SessionFactory sessionFactory;
    static {
    try {
    sessionFactory = new Configuration().configure().buildSessionFactory();
    } catch (Throwable ex) {
    throw new ExceptionInInitializerError(ex);
    }
    }
    public static Session getSession() {
    return (Session) _session.get();
    } public static void setSession(Session session) {
    if (session == null) {
    sessionIsActive.set(null);
    } else
    sessionIsActive.set(new Boolean(true));
    _session.set(session);
    }
    public static Transaction getTransaction() {
    return (Transaction) _transaction.get();
    } public static void setTransaction(Transaction trans) {
    _transaction.set(trans);
    } public static void closeSession() throws HibernateException {
    Transaction tr = (Transaction) getTransaction();
    try {
    if (tr != null && !tr.wasCommitted() && !tr.wasRolledBack()) {
    tr.commit();
    }
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    setTransaction(null);
    getSession().close();
    setSession(null);
    }
    }
      

  4.   

    那和Spring框架整合,SessionFactory是Spring提供的
    不好利用你上面那段代码啊
    org.springframework.orm.hibernate3.LocalSessionFactoryBean
    不知道该怎么办?
      

  5.   

    将SessionFactory从IDAO中分离出来。
    只在实现方法的时候才去调用它。 
    事务开启后要跟Session开启一样,一定要关闭。
      

  6.   

    既然用了spring,就不要想不和它耦合,其实你有接口,已经可以了,在不想用spring的时候可以再重新写另外一个实现方法。也就是说一个DAO接口,可以有多个实现类,想用那个用那个。public class SpringHibernateImageDAOImpl extends HibernateDaoSupport implements ImageDAO 
    public class HibernateImageDAOImpl implements ImageDAO 
    public calss JDBCImageDAOImpl implements ImageDAO如果过分想着不耦合,那么就什么框架都用不成了。感觉这个问题有点over design。
      

  7.   


    同意!
    封装一个统一的泛类型dao,其他的dao都继承它!
      

  8.   

    hi xushun  could you tell me how did you solve this problem?  i met the same problem
    thanks in advance