各位好,我遇到一个我觉得不可思议的问题,请高人指点。
首先我建了一个操作实体类的DAO对象,其中一个函数代码如下:
内容很简单,就是从数据库中取出表中有多少条记录 public int getCount(){
        Session session = HibernateUtil.getSessionFactory().openSession();
        int count = ((Long)session.createQuery("select count(*) from Announce").uniqueResult()).intValue();
        if(session.isOpen() && session != null)session.close();
        return count;
    }然后我再action的一个方法中调用这个方法。public String addAnnounce(){
        //初始化adminservice对象
      AnnounceService as=new AnnounceService();
      Announce a=new Announce();
      a.setAContent(this.announcecontent);
      a.setATitle(this.announcetitle);
      a.setAAuthor((String)ActionContext.getContext().getSession().get("admin"));
      a.setATime(new Date());
      as.save(a);
      System.out.println(new TechnicDAO().getCount()); //在保存之后,打印出共有多少条记录
      return "addannounce";
    }在这里出了严重问题,无论我怎么添加记录,打印出的都是第一次打印的数据。
比如第一次打印出 10 ,我又添加两条,还是打印10,无论怎么添加,都是10.除非重新部署或者重启容器。但是我在一个jsp页面中做了如下测试
    <%
    out.print(new AnnounceDAO().getCount());
    System.out.println(new AnnounceDAO().getCount());
    %>在这个jsp里,却可以始终与数据库内的记录完全对应。我实在是很费解,struts到底是怎么工作的,会搞成这个样子?有什么解决方法没有?

解决方案 »

  1.   

    as.save(a);这里用的是hibernate的save吧,save之后需要用session.flush();来刷到数据库中如果再不好用,就请加上事务处理
      

  2.   

    又一个说自己没问题的人
    你提到了过滤器,那么可见action方法addAnnounce()是在一个是事务当中的,你想一下,还能得到吗如果想得到,那么需要设置hibernate的autocommit为true,这样用flush()才能好用,否则就请你提交事务后再来获取count
      

  3.   

    save好还没写数据库那,要COMMIT或者FLUSH把
      

  4.   

    Session session=null;
       Transaction tx=null;
       try{
           //从当前线程中获得session
         session=HibernateUtil.getThreadLocalSession();
         //开启事务
         tx=session.beginTransaction();
         //执行请求方法
         chain.doFilter(request,response);
         //提交事务
         tx.commit();
       }catch(Exception e){
          //捕获到错误回滚事务
           if(tx!=null)
                tx.rollback();
          throw new RuntimeException(e.getMessage(),e);      
      }finally{
          //关闭session
          HibernateUtil.closeSession();
      }过滤器是这样子的。确实是在提交之前取得count。
    但是即使是这样,第二次再访问这个方法,是否也应该是获取前一次的count。
    为什么会一直保持一个值不变呢?
      

  5.   

    不知道HibernateUtil怎么写的,如果是用hibernate那个HibernateSessionFactory的话,只需要用
    HibernateSessionFactory.getSession()来获取当前线程中的session,如果没有则创建一个session,再把这个session放入threadlocal
    这样就不需要再进行HibernateUtil.getSessionFactory().openSession();
     if(session.isOpen() && session != null)session.close();
    真不知道session关闭之后,事务怎么提交,呵呵回答完毕
      

  6.   

    HibernateUtil的getThreadLocalSession()方法是从县城中获取session,如果没有则创建一个。
    而getSessionFactory().openSession()我是想再另外通过sessionFactory创建一个session和线程中session的无关,
    请问高人,难道这两方法创建的session仍然是同一个?或者出现什么故障了?
      

  7.   

    而且奇怪的是在jsp的页面中调用同样的 new Announce().getCount()方法,打印的出的数据和数据库里的一致。
    唯独这个action中的,无论添加多少个,打印出的始终是第一次的数据。而这个时候jsp中显示的却可以更新。
      

  8.   

    多谢楼上的几位高人,问题有了新的进展。我这回直接将代码写道action中,如果代码是:
    就没有什么反应,始终不变。    public String addAnnounce(){
            //初始化adminservice对象
          AnnounceService as=new AnnounceService();
          Announce a=new Announce();
          a.setAContent(this.announcecontent);
          a.setATitle(this.announcetitle);
          a.setAAuthor((String)ActionContext.getContext().getSession().get("admin"));
          a.setATime(new Date());
          as.save(a);
            Session session = HibernateUtil.getSessionFactory().openSession();
            int count = ((Long)session.createQuery("select count(*) from Announce").uniqueResult()).intValue();
            if(session.isOpen() && session != null)session.close();
            System.out.println("打印出来: " + count);
          return "addannounce";
        }但是如果是这样,把session的获得改为 getThreadLocalSession()则就可以出现更新的数据。    public String addAnnounce(){
            //初始化adminservice对象
          AnnounceService as=new AnnounceService();
          Announce a=new Announce();
          a.setAContent(this.announcecontent);
          a.setATitle(this.announcetitle);
          a.setAAuthor((String)ActionContext.getContext().getSession().get("admin"));
          a.setATime(new Date());
          as.save(a);
            Session session = HibernateUtil.getThreadLocalSession();
            int count = ((Long)session.createQuery("select count(*) from Announce").uniqueResult()).intValue();
            System.out.println("打印出来: " + count);
          return "addannounce";
        }
    请高人给我讲讲背后的原因,谢谢。
      

  9.   

     static Session getSession()  这个是静态方法,类共享的,想要关闭那有那么容易呀。//这个是线程独占,你那个过滤器在这个线程的生命周期到END的时候就起作用了。sava执行完毕,生命over,过滤器完成commit。
     public static Session getThreadLocalSession() throws HibernateException {
            Session session = (Session) threadLocal.get(); if (session == null || !session.isOpen()) {
    if (sessionFactory == null) {
    rebuildSessionFactory();
    }
    session = (sessionFactory != null) ? sessionFactory.openSession()
    : null;
    threadLocal.set(session);
    }        return session;
        }