请高手回答:Hibernate和jdbc修改数据库更新不一致问题

woming66 2008-11-02 07:05:39
我做个项目,持久层技术一部分是拿Hibernate3实现,一部分是拿JDBC实现,当我用JDBC去修改数据库(mysql)中的数据时,可拿Hibernate query.list();
【在query.list();代码之前之后,我都调用了session.flush();session.clear();】浏览数据时却还是没改,但进数据库一看,发现数据已经改了。我知道是Hibernate缓存弄的鬼,不知道各位大虾那位明白帮弄弄! 谢谢了
...全文
614 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
wert3232 2012-05-09
  • 打赏
  • 举报
回复
s=HibernateSessionFactory.getSession();
Transaction transaction = s.beginTransaction();
String hql="from Student as student where student.sname"+com;
Query query=s.createQuery(hql);
List<Student> list=query.list();
for(Student stu:list){
result=result+
stu.getSno()+","+
stu.getSname()+","+
stu.getSage()+"<stu>"
;
//System.out.println(stu.getSage());
}
transaction.commit();
==========================================================
Transaction transaction = s.beginTransaction();
transaction.commit();
我加了这两条就行了
xuchanghao 2011-11-23
  • 打赏
  • 举报
回复
我也遇到这个问题了,有人解决了吗?
我是修改了数据,可是再查询数据居然在原值和修改值之间变来变去(在后台debug看过了,hibernate查询出来的直接就错了)。
spawnyy 2011-11-14
  • 打赏
  • 举报
回复
我也遇到一样的问题。我目前的临时解决办法是修改数据库事务隔离级别为读取已提交。
jia520ying 2010-01-25
  • 打赏
  • 举报
回复
我也遇到同样的问题了,用jdbc添加记录用hibernate查不到,我的解决办法是在hibernate查询的时候也加上事物,一commit就行了,它会自己去同步数据的,楼主试试看
北极熊 2009-12-11
  • 打赏
  • 举报
回复
我也遇见此问题,由于前台别人通过jdbc 插入数据,后台用 hibernate 的list 方法,为什么老显示的是为插入前的数据??????????????
dpd830 2009-05-18
  • 打赏
  • 举报
回复
俺也遇到这个问题。。。不知道怎么解决。哎
Landor2004 2008-11-10
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 panhaichun 的回复:]
不会是你页面缓存了的原因吧
[/Quote]
有可能,不过楼主说他后台debug了,也是旧数据,这就很诡异
panhaichun 2008-11-10
  • 打赏
  • 举报
回复
不会是你页面缓存了的原因吧
yongtree 2008-11-09
  • 打赏
  • 举报
回复
hibernate的缓存的确是一个头疼的问题,有时候我们flash,claer缓存,还是出现数据脏读的情况,我也一直没有比较好的方法。
但是开发的时候在数据实时性要求高的地方还是要加上事务保护,clear缓存,尽量的让数据保持同步,没想起什么彻底的解决方法。
woming66 2008-11-09
  • 打赏
  • 举报
回复
对不起版主,我没有设置查询和二级缓存,您给出的方法我试了,但还是不好使!

<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:mysql://localhost/hithd</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">admin</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.connection.pool_size">5</property>

<mapping resource="com/zzq/exam/struts/User.hbm.xml"/>
<mapping resource="com/zzq/qualification/struts/QualUser.hbm.xml"/>
</session-factory>
</hibernate-configuration>

---------------------------Hibernate查询---------------------------------------
public List queryUserList() throws Exception {

Session session = HibernateSessionManager.getSession();
Transaction tx = session.beginTransaction();

List users = null;
try {
session.setCacheMode(CacheMode.REFRESH);
session.flush();
session.clear();

Query query = session.createQuery("from User order by id desc");
query.setCacheMode(CacheMode.REFRESH);
users = query.list();
session.flush();
session.clear();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
throw e;
} finally {
if(session != null) {
if(session.isOpen()) {
session.close();
}
}
}

return users;
}
---------------------JDBC去修改数据(这是原来的版本(不是我写的),在jsp页面中嵌入的代码)-------------------------------------
//定义Connection Statment ...
String personId = request.getParameter("personid");
if(personId != null && !personId.trim().equals("")) {
if(personId.matches("([\\d]{17}[\\dxX])|[\\d]{15}")) {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hithd?user=root&password=admin");
stmt = conn.createStatement();
i = stmt.executeUpdate("update t_examuser set money = 1 where personId ='" + personId + "'");
} finally {
if(stmt != null) {
stmt.close();
stmt = null;
}
if(conn != null) {
conn.close();
conn = null;
}
}
if(i >= 1) {
out.println("更新成功!");
} else {
out.println("更新失败,您输入的学号可能没有对应的人");
}
} else {
out.println("您输入的身份证号不正确!");
}
return;
} else {
out.println("您没有输入身份证号");
return;
}


woming66 2008-11-09
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 Landor2004 的回复:]
引用 10 楼 woming66 的回复:
读的是旧数据,通过什么设置怎么能让Hibernate读新数据?

匪夷所思,list就是读取的数据库最新数据,没办法了!
[/Quote]
我也觉的这也太怪了,过个五六分钟之后,我一刷又读出新数据了,真是怪了,就这样吧,我再想办法。
在这里我谢谢回复过我帖子的人,谢谢你了板主!
Landor2004 2008-11-09
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 woming66 的回复:]
读的是旧数据,通过什么设置怎么能让Hibernate读新数据?
[/Quote]
匪夷所思,list就是读取的数据库最新数据,没办法了!
woming66 2008-11-09
  • 打赏
  • 举报
回复
读的是旧数据,通过什么设置怎么能让Hibernate读新数据?
Landor2004 2008-11-09
  • 打赏
  • 举报
回复
其实这样就行
public List queryUserList() throws Exception {
Session session = HibernateSessionManager.getSession();
Transaction tx = session.beginTransaction();
List users = null;
try {
Query query = session.createQuery("from User order by id desc");
users = query.list();
tx。commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
throw e;
} finally {
if(session != null) {
if(session.isOpen()) {
session.close();
}
}
}
return users;
}

如果还有问题,那就不是这里的问题了,list是查询的数据库
你用debug跟一下这个函数的list里面到底是新数据还是旧数据
Landor2004 2008-11-08
  • 打赏
  • 举报
回复
如果不关闭查询缓存,

如果查询需要强行刷新其查询缓存区域,那么你应该调用Query.setCacheMode(CacheMode.REFRESH)方法。 这对在其他进程中修改底层数据(例如,不通过Hibernate修改数据),或对那些需要选择性更新特定查询结果集的情况特别有用。 这是对SessionFactory.evictQueries()的更为有效的替代方案,同样可以清除查询缓存区域。
Landor2004 2008-11-08
  • 打赏
  • 举报
回复
在没有二级缓存的情况下,hibernate的list方法,是直接从数据库中获取数据,不会出现楼主的问题

在配置了二级缓存的查询缓存的情况下,就会出现不一致的问题,如无特殊需要,建议取消二级查询缓存的配置
woming66 2008-11-08
  • 打赏
  • 举报
回复
怎么没有人回答啊,是不会还是没看到帖子,我很急的,摆脱大哥大姐有会的帮帮我,在这里我谢谢大家了!!!!!
woming66 2008-11-08
  • 打赏
  • 举报
回复
怎么没有人回答啊,是不会还是没看到帖子,我很急的,摆脱大哥大姐有会的帮帮我,在这里我谢谢大家了!!!!!
woming66 2008-11-07
  • 打赏
  • 举报
回复
我使用的是MySQl5.5数据库,MySQL默认的隔离级别是可重复读,我没有动默认设置.你说的方法我试了,还是不好使.
ol_soft 2008-11-04
  • 打赏
  • 举报
回复
我觉得不是Hibernate的缓存问题,是数据库的隔离级别问题,数据库的隔离级别有未提交读,已提交读,可重复读,快照,可序列化,不知道你用的时什么数据库,不同的数据库的隔离级别不同。
Hibernate session在clear,fluse后已经发出sql语句了
要不你Commit再试试

50,528

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧