hibernate和mysql的缓存问题,没辙了!

    各位大侠好,我的hibernate出了很严重的问题,我用的数据库是mysql,大家请看下面这段代码,我每次已经把值正确插入到数据库后,下面的这个方法查询出来的还是旧数据,等页面刷新好几次后才查询出新的数据,有时候刷新一会是新的数据一会是旧的数据。

public double sumExpense(String userid,String itemid,String yearmonth){
        Session session = SessionBuilder.getSession();
        double sum = 0d;
        String hql = "SELECT SUM(c.expenditrue) FROM  Consumeaccount c WHERE c.usrplanrel.id.userbasicinfo.userid='"+userid+"'  AND c.accountitmecode.itemid='"+itemid+"' AND c.dat LIKE '"+yearmonth+"%'";
        Object obj = session.createQuery(hql).uniqueResult();
        if(obj!=null){
            sum = Double.parseDouble(obj.toString());
        }
        return sum;
    }

 上面的方法改为这个后就没问题,就是每次都重新创建新的session工厂

/**
     *根据消费分类ID、模板ID、年度月份查询该消费分类的实际消费值总和
     * @param itemid
     * @param templateid
     * @param yearmonth
     * @return
     */
    public double sumExpense(String userid,String itemid,String yearmonth){
        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();    
        Session session = sessionFactory.openSession();
        double sum = 0d;
        String hql = "SELECT SUM(c.expenditrue) FROM  Consumeaccount c WHERE c.usrplanrel.id.userbasicinfo.userid='"+userid+"'  AND c.accountitmecode.itemid='"+itemid+"' AND c.dat LIKE '"+yearmonth+"%'";
        Object obj = session.createQuery(hql).uniqueResult();
        if(obj!=null){
            sum = Double.parseDouble(obj.toString());
        }
        return sum;
    }

  请问这个是怎么回事呢,程序中好多处都是这个问题,我的二级缓存已经关了

 

  <property name="cache.use_query_cache">false</property>
    <property name="cache.use_second_level_cache">false</property>

 


问题补充:
我的SessionBuilder.getSession();应该没问题的,我曾经也用了hibernate自动生成的得到session的方法,目前用的这个Thread模式
public static SessionFactory sessionFactory;

static {

try {

sessionFactory = new Configuration().configure()

.buildSessionFactory();

} catch (Throwable ex) {

throw new ExceptionInInitializerError(ex);

}

}

public static final ThreadLocal session =

new ThreadLocal();

public static Session getSession() throws HibernateException {

Session s = (Session) session.get();

if(s == null) {

s = sessionFactory.openSession();

session.set(s);

}

return s;

}

public static void closeSession() throws HibernateException {

Session s = (Session) session.get();

if(s != null) {

s.close();

}

session.set(null);

}

问题补充:
首先感谢大家的回答,我的插入有事物,每次插入完成后都有flush,而且我自己在数据库里面修改一个字段刷新页面好几次才能得到新数据。至于什么数据库隔离级别我不太懂啊,但是应该和那没关系。
我自己的写的测试方法在类的main方法里面执行的时候,一直不会出现过期数据,很奇怪。

6个回答

[code="java"]Session s = (Session) session.get();[/code]
老大,ThreadLocal它是一种服务器端行为,当服务器每生成一个新的线程时,就会维护自己的ThreadLocal,一般的应用服务器都会维护一套线程池,也就是说,对于每次访问,并不一定就新生成一个线程。而是自己有一个线程缓存池。对于访问,先从缓存池里面找到已有的线程,如果已经用光,才去新生成新的线程,所以,由于开发人员自己在测试时,一般只有他自己在测,这样服务器的负担很小,这样导致每次访问可能是共用同样一个线程,这样也就导致了你有可能每次拿的都是同一个Session对象

问题是你的SessionBuilder.getSession(); 是怎么实现的,

那应该就是你这个

SessionBuilder.getSession();//如果获取Session的

的问题了。

LZ这种使用方式太奇怪了,注入SessionFactory后获取一个Session,而不是重新New出来一个SessionFactory。

还有就是LZ插入功能有没有事务,因为LZ提到不能马上得到新数据,所以LZ试着直接往数据库中添加记录然后在测试看是否能马上获取,至少能判断是这里的问题还是插入功能的问题。

兄弟,对你这个问题,我想你在用你的session之前,或者在你插入之后,调用一下session的flush()方法和clear()方法,因为当你插入数据后,你的session没有关闭,此时你的数据并没有真正插入到数据库中,当session关闭或调用flush()方法的时候会自动吧你的数据插入到数据库。另外就是楼上说的事物问题。还有你的数据库隔离级别。看你的隔离级别是什么。

LZ 把showsql打开看一下生成的SQL是不是加了什么东东

用一个客户端使用这些SQL访问还是不是和Hibernate访问的一样

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!