各位大侠好,我的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>
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);
}
[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访问的一样