我做了一个hibernate分页及添加删除更新操作的模块。在使用hibernate插入数据后,数据库表里面已经增加了该记录,但是当我多次按刷新分页页面后,这条刚插入的记录有时候出现,有时候又消失了。
  在使用hibernate删除数据后,数据库表里面也已经删除了该记录,当我多次按刷新分页页面后,这条刚删除的记录有时候又会出现。
  我用((Integer) session.createSQLQuery(query).iterate().next()).intValue();,或者jdbc的方法获取并打印总的记录数,(按刷新后打印出来的数据)有时候是正确的,有时候是删除/添加以前的总的记录数。
  郁闷...  还请各位老师帮忙指点迷津,感激不尽。

解决方案 »

  1.   

    不知道你是用什么方法得到记录显示在页面的,hibernate有时候在查询时,是先查询在缓存中的数据的。
    也就是说,即使你在数据表中删除了,但缓存里是原来的数据的话,它是先从缓存中取数据而不是从数据库。
    没有代码,只能说说大概意思,自己去查查看。
      

  2.   

    这一定是因为hibernate缓存引起的。hibernate会把你的hql语句缓存起来。如果你以后的操作中有和缓存过的hql语句相同。而且之前没有做过数据库修改,那么hibernate会直接把上次的结果返回给用户。我觉得可能是因为hibernate在判断数据库是否修改的时候出现了什么问题。具体什么问题,我就不清楚了。当你连续刷新的时候你可能调用了另一个session这个session没有判断出你的数据库已经被修改过。(只是可能。)hibernate的缓存技术挺复杂的。我具体也不太清楚了。你再测试一下看看把。还有就是看看后台有没有报错
      

  3.   

    session.createSQLQuery(query).iterate().next()).intValue
      

  4.   

    我看了一下资料。
    sql缓存默认是关闭的。而且当发现数据库修改,hibernate会自动把sql缓存的数据删除。
    所以应该不是缓存问题。还是看看你的代码把。
    仔细看看你在点击分页的时候有没有代码是对数据进行修改的。
    应该还是你的代码出现问题了。
      

  5.   

    谢谢各位的指点!
    我把代码贴一下,请各位指点。
    另:我用session.flush()清空缓存,但结果还是一样。相关代码如下:
    ----------------------------------------------------------------------------------------------点击刷新时的url地址是:http://localhost:8082/hspager/Displayall.do?action=9&tableId=4&tName=ModuleregDisplayall转到com.pager.struts.Action.DisplayAllActionDisplayAllAction中的相关代码:
      
    //设置页面不缓存
    response.setHeader("Pragma","No-cache");
    response.setHeader("Cache-Control","no-cache");
    response.setDateHeader("Expires", 0);HttpSession session = request.getSession();
    String tableName = request.getParameter("tName");totalRows = hibernateDAO.getRows(tableName,"id","","");
    hibernateDAO中的getRows方法"
    ----------------------------------------------------------------------------------------
    public int getRows(String tableName, String key, String whereStr,
    String orderBy) throws HibernateException {
    int totalRows = 0; try {
    Session session = HibernateSessionFactory.getSession();
    if (!whereStr.equals("")) {
    whereStr = " " + whereStr;
    }
    if (!orderBy.equals("")) {
    orderBy = " " + orderBy;
    }
    String query = "select count(*) from " + tableName + whereStr
    + orderBy;


    totalRows = ((Integer) session.createSQLQuery(query).iterate().next())
    .intValue();
    System.out.println("totalRows="+totalRows);//这里打印出来的数据,就有问题,刷新后有时是正确的,有时是 
                                                                       //添加/删除以前的totalRows
    } catch (HibernateException he) {
    errMsg.append("HibernateDAO.getRows--HibernateException: ");
    errMsg.append(he.getMessage());
    } finally { } return totalRows;
    }
      

  6.   

    最好不要用本地SQL查询,对于程序的移植是不利的,而且对于查询优化也是不好的。另外,你的插入或者删除时,应该flash,commit
      

  7.   

    DisplayAllAction中另一些相关的代码// 初始化页面信息******************************************
    if(session.getAttribute("pager") == null){
           pager = new Pager();
           pager.init(totalRows);
    }else{
          pager = (Pager)session.getAttribute("pager");//当添加/删除记录后,我已经把session中page的 
                                                              //totalRows属性做了相应的修改
    }
    int action = (Integer.parseInt(request.getParameter("action")));// 根据传递进来的参数控制页面的前进后退        if (action== -1) {            pager.previous();        } else if (action == 1) {            pager.next();        } else if (action == 0) {            pager.first();        } else if (action == 9) {            pager.last();        }
    ---------------------------------------------------------------------------------------------
    package com.pager.struts;import java.math.*;public class Pager {
    private int totalRows; // 总行数 private int pageSize = 20; // 每页显示的行数 private int currentPage; // 当前页号 private int totalPages; // 总页数 private int startRow; // 当前页在数据库中的起始行

    private boolean hasPrevious;

    private boolean hasNext; public Pager() {

    }

    public void init(int _totalRows){// 总行数作为传入参数
    totalRows = _totalRows;
    totalPages = totalRows / pageSize;
    int mod = totalRows % pageSize;
    if (mod > 0) {
    totalPages++;
    }// 计算总页数
    currentPage = 1;
    startRow = 0;
    hasPrevious = false;
    hasNext = false;
    } public int getStartRow() {
    return startRow;
    } public int getTotalPages() {
    return totalPages;
    } public int getCurrentPage() {
    return currentPage;
    } public int getPageSize() {
    return pageSize;
    } public void setTotalRows(int totalRows) {
    this.totalRows = totalRows;
    } public void setStartRow(int startRow) {
    this.startRow = startRow;
    } public void setTotalPages(int totalPages) {
    this.totalPages = totalPages;
    } public void setCurrentPage(int currentPage) {
    this.currentPage = currentPage;
    } public void setPageSize(int pageSize) {
    this.pageSize = pageSize;
    } public int getTotalRows() {
    return totalRows;
    }

    public boolean getHasPrevious(){
    return hasPrevious;
    }

    public void setHasPrevious(boolean hasPrevious){
    this.hasPrevious = hasPrevious;
    }

    public boolean getHasNext(){
    return hasNext;
    }

    public void setHasNext(boolean hasNext){
    this.hasNext = hasNext;
    } public void first() { // 回首页
    currentPage = 1;
    startRow = 0;
    hasPrevious = false;
    hasNext = true;
    } public void previous() {// 上一页
    if (currentPage == 2) {
    hasPrevious = false;
    }
    if(currentPage!=1){
         currentPage--;
         startRow = (currentPage - 1) * pageSize;
         hasNext = true;
    }
    } public void next() {// 下一页
    if (currentPage < totalPages) {
    currentPage++;
    }

    startRow = (currentPage - 1) * pageSize;

    if(currentPage==totalPages){
    hasNext = false;
    }else{
    hasPrevious = true;
    }
    } public void last() {// 最后一页
    currentPage = totalPages;
    startRow = (currentPage - 1) * pageSize;
    hasPrevious = true;
    hasNext = false;
    } public void refresh(int _currentPage) {
    currentPage = _currentPage;
    if (currentPage > totalPages) {
    last();
    }
    if(currentPage<=0){
    first();
    }
    }

    public void jump(int currentPage){
    this.currentPage = currentPage;
    startRow = (currentPage - 1) * pageSize; 

    if(currentPage==totalPages&&currentPage==1){
    hasNext = false;
    hasPrevious = false;
    }else if(currentPage==totalPages){
    hasNext = false;
    hasPrevious = true;
    }else if(currentPage==1){
    hasNext = true;
    hasPrevious = false;
    } }}
      

  8.   

    一次HIBERNATE操作完后,要关闭HIBERNATE SESSION,看看时不是这个问题
      

  9.   

    我用 MyEclipse自动生成的HibernateSessionFactory,来管理session的,它会自动关闭session的
      

  10.   

    我不知道问题所在,但是HibernateSessionFactory是得你调用closeSession()方法关闭session的
      

  11.   

    你是不是在一次web访问是,先删除数据,然后在查询的数量,这是你发现,数量是没有删除的数量? 而第二次直接访问查询是删除后的数量,如果是这样,那就是你没有commit的原因。
    因为你是直接用的sql查询的数量,所以和一级、二级缓存没有什么关系。否则,你就去问神仙吧
      

  12.   

    没有方法能自动关闭session,除非你调用了close方法,或者你调用的函数封装了这个方法