【问题标题】:Hibernate's Criteria query makes Tomcat become not responive after a few request servicesHibernate Criteria查询使Tomcat在几次请求服务后变得没有响应
【发布时间】:2013-04-15 15:21:18
【问题描述】:

我在 Tomcat 7.0.35(Spring 3.1、Hibernate 3.6.1、JPA 2.0)上运行 Spring + Hibernate Web 应用程序。

这个应用程序有一个页面,它通过 Hibernate 的标准从数据库中获取数据(我知道我不必这样做)。服务层只是简单地调用数据层。代码如下:

    Criteria criteria = sessionFactory.openSession().createCriteria(Article.class); 
    criteria.addOrder(Order.desc("updatedTime"));
    criteria.add(Restrictions.eq("account", acc));
    criteria.add(Restrictions.eq("draft", true));
    criteria.setMaxResults(1);
    Article s = (Article) criteria.uniqueResult();
    return s;

Tomcat 只能处理来自该页面的几个请求,然后它变得无响应。我可以看到浏览器一直在等待服务器响应(Firefox 状态栏显示“等待主机”。)

我没有看到 OutOfMemory 等任何错误消息。看来浏览器一直在等待。

如果我将其更改为 JPA,如下所示:

    @NamedQuery(name = "Article.getMostRecentDraftArticle", query = "select x from Article x where x.account = :account and x.draft = 1 order by x.updatedTime desc"),

.....

Query q = getSession().getNamedQuery("Article.getMostRecentDraftArticle");
q.setParameter("account", acc);     
q.setMaxResults(1);
List list = q.list();
if (list.size() == 0) 
    return null;
else 
        return (Article) list.get(0);

然后一切正常。

使用 Hibernate 的 Criteria API 会出现什么问题?

感谢您的任何意见!

干杯。

【问题讨论】:

    标签: java hibernate criteria-api


    【解决方案1】:

    您尚未关闭会话。看到这个答案:https://stackoverflow.com/a/4049758/116509

    并阅读org.hibernate.session的javadoc:

    典型的交易应该使用以下成语:

     Session sess = factory.openSession();
     Transaction tx;
     try {
         tx = sess.beginTransaction();
         //do some work
         ...
         tx.commit();
     }
     catch (Exception e) {
         if (tx!=null) tx.rollback();
         throw e;
     }
     finally {
         sess.close();
     }
    

    【讨论】:

    • 通过添加 sessionFactory.openSession().close(); 尝试了这个解决方案;在返回之前。但它不起作用。
    • 您需要在同一个实例上调用close。再次调用openSession 将创建一个不同的实例。
    【解决方案2】:

    你能看到休眠日志吗?它会生成查询吗?
    无论如何,您可以尝试在Article s = (Article) criteria.uniqueResult();下方放置一个sessionFactory.getCurrentSession().flush();

    【讨论】:

    • 对了,为什么criteria.setMaxResults(1);criteria.uniqueResult();都有呢?只有第二个就足够了。不是吗?
    • 作为一种绝望的尝试,如果在刷新后添加sessionFactory.getCurrentSession().clear(); 可能会有所帮助。但请注意,因为清除会分离所有实例并删除所有挂起的更新,它会清除会话。
    • 丹尼尔,感谢您的意见。我按照 artbrisol 的建议使用了 session.close。它奏效了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 2016-12-26
    • 2013-01-08
    • 1970-01-01
    • 2017-05-20
    相关资源
    最近更新 更多