繁体   English   中英

Hibernate在查询时没有响应

[英]Hibernate is not responding while querying

如果Hibernate查询花费的时间太长而无法返回结果,该如何处理。 我已经配置了一个查询超时,但是在调试时它表明数据库正在通过返回数据进行响应,但是休眠无法映射给定的数据。

我不希望这种情况在生产中发生,因为由于休眠状态未响应,所以查询可能会失败。

我需要一个解决方案来解决这种情况。

setProperty("javax.persistence.query.timeout", 180000);

JPAQuery query = queryFactory.select(....)
do{
   List<Tuple> data = query.fetch().limit(5000);
   //--------
} while(flag)

上面的代码适用于较小的数据,但对于某些数据集/条件,数据量很大,最终休眠时无响应。

如果可能,请尝试按照以下步骤操作

  • 使用Lazy Fetching而不是像@ManyToMany(mappedBy="authors", fetch=FetchType.LAZY)这样的Eager Fetching。

  • 或者可以检查是否有任何这些错误

  • 您正在使用HibernateDaoSupport.getSession() ,而从未使用releaseSession()返回它们(如javadocs中所述)。

a)使用HibernateDaoSupport.getHibernateTemplate()干净地创建/销毁会话b)在最后一块中使用getSession()/releaseSession() c)忘记HibernateDaoSupport ,定义事务并使用sessionFactory.getCurrentSession()

  • 使用时, session.refresh(entity) or entityManager.refresh(entity) (如果使用JPA)将为您提供来自数据库的新数据。
1) For setting the timeout in Hibernate query you can set hint "javax.persistence.query.timeout"


Code snippet ::

List<Test> test= em.createQuery("SELECT * FROM Test t")
    .setHint("javax.persistence.query.timeout", 1)
    .getResultList();

2) In case 2 columns are containing large data ,you can use CLOB and BLOB types for huge dataset.

根据您的最新评论,您正在寻找一种管理某些查询超时的方法。

您可以在使用Hibernate创建org.hibernate.Query时实现此目的:

Query queryObject = //initialize your query as you need;
queryObject.setTimeout(10); //that int represents the seconds of timeouts.

希望这可以帮助

最后,我找不到任何直接方式来控制休眠查询调用。 超时对我来说不起作用,因为Postgres已经返回了结果集,但是由于数据大小,休眠状态在映射上花了一些时间(如果我错了,请纠正我)。

以下代码拯救了我。

ExecutorService executor = Executors.newSingleThreadExecutor();
List<Future<List<Tuple>>> futureData = executor.invokeAll(Arrays.asList(new QueryService(params...)), 2, TimeUnit.MINUTES);
executor.shutdown();
for (Future future : futureData) {
    try {
         data = (List<Tuple>) future.get();
         } catch (CancellationException e) {
                 if (EXPORT_LIMIT > 1000) {
                            EXPORT_LIMIT = 1000;
                        } else if (EXPORT_LIMIT > 500) {
                            EXPORT_LIMIT = 500;
                        } else if (EXPORT_LIMIT > 100) {
                            EXPORT_LIMIT = 100;
                        } else {
                            throw e;
                        }
                        isValid = false;
                        break;
                    }
                }

因此,基本上我的默认读取限制为5000(如果不起作用),那么我会一直尝试到100。如果100的读取大小也失败,则会引发异常。

谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM