struts2+hibernate 遇到了崩溃的问题

aoliwen521 2009-04-18 09:42:18
各位好,我遇到一个我觉得不可思议的问题,请高人指点。
首先我建了一个操作实体类的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到底是怎么工作的,会搞成这个样子?有什么解决方法没有?
...全文
115 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
APOLLO_TS 2009-04-18
  • 打赏
  • 举报
回复
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;
}
hujun_zero 2009-04-18
  • 打赏
  • 举报
回复
新手上路,学习,接分,顶
aoliwen521 2009-04-18
  • 打赏
  • 举报
回复
多谢楼上的几位高人,问题有了新的进展。

我这回直接将代码写道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";
}


请高人给我讲讲背后的原因,谢谢。
aoliwen521 2009-04-18
  • 打赏
  • 举报
回复
而且奇怪的是在jsp的页面中调用同样的 new Announce().getCount()方法,打印的出的数据和数据库里的一致。
唯独这个action中的,无论添加多少个,打印出的始终是第一次的数据。而这个时候jsp中显示的却可以更新。
aoliwen521 2009-04-18
  • 打赏
  • 举报
回复
HibernateUtil的getThreadLocalSession()方法是从县城中获取session,如果没有则创建一个。
而getSessionFactory().openSession()我是想再另外通过sessionFactory创建一个session和线程中session的无关,
请问高人,难道这两方法创建的session仍然是同一个?或者出现什么故障了?
Landor2004 2009-04-18
  • 打赏
  • 举报
回复
不知道HibernateUtil怎么写的,如果是用hibernate那个HibernateSessionFactory的话,只需要用
HibernateSessionFactory.getSession()来获取当前线程中的session,如果没有则创建一个session,再把这个session放入threadlocal
这样就不需要再进行HibernateUtil.getSessionFactory().openSession();


if(session.isOpen() && session != null)session.close();
真不知道session关闭之后,事务怎么提交,呵呵

回答完毕
aoliwen521 2009-04-18
  • 打赏
  • 举报
回复
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。
为什么会一直保持一个值不变呢?
Dantin 2009-04-18
  • 打赏
  • 举报
回复
save好还没写数据库那,要COMMIT或者FLUSH把
Landor2004 2009-04-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 aoliwen521 的回复:]
事务处理在一个过滤器中都已经进行了,储存方面没有问题。
[/Quote]
又一个说自己没问题的人
你提到了过滤器,那么可见action方法addAnnounce()是在一个是事务当中的,你想一下,还能得到吗

如果想得到,那么需要设置hibernate的autocommit为true,这样用flush()才能好用,否则就请你提交事务后再来获取count
aoliwen521 2009-04-18
  • 打赏
  • 举报
回复
事务处理在一个过滤器中都已经进行了,储存方面没有问题。
Landor2004 2009-04-18
  • 打赏
  • 举报
回复
as.save(a);这里用的是hibernate的save吧,save之后需要用session.flush();来刷到数据库中

如果再不好用,就请加上事务处理

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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