2013-04-15 3 views
1

Я запускаю веб-приложение Spring + Hibernate на Tomcat 7.0.35 (Spring 3.1, Hibernate 3.6.1, JPA 2.0).Запрос Критерии Hibernate заставляет Tomcat не реагировать после нескольких запросов.

У этого приложения есть страница, которая получает данные из базы данных с помощью критериев 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); 

Тогда все работает правильно.

Что может пойти не так с моим использованием API критериев Hibernate?

Спасибо за любой ввод!

Cheers.

ответ

2

Вы не закрыли сеанс. Смотрите этот ответ: https://stackoverflow.com/a/4049758/116509

и читать Javadoc из org.hibernate.session:

Типичная сделка должна использовать следующую идиому:

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(); 
} 
+0

Пробовал это решение, добавив sessionFactory.openSession(). Close(); перед возвращением. Но это не работает. – curious1

+0

Вам нужно вызвать 'close' в том же экземпляре. Вызов 'openSession' снова создаст другой экземпляр. – artbristol

+0

@arbristol, спасибо за ваше упоминание о том же сеансе. Это сработало!!! – curious1

1

Вы можете видеть журналы спящего режима? генерирует ли запрос?
В любом случае, вы можете попробовать поставить sessionFactory.getCurrentSession().flush(); ниже Article s = (Article) criteria.uniqueResult();

+0

Добавлено флеша как это было предложено, но он не работает. – curious1

+0

Кстати, почему у вас есть оба параметра: criteria.setMaxResults (1); 'и' criteria.uniqueResult(); '? достаточно только второго. Не так ли? – daniele

+1

как отчаянная попытка, если после флеша вы добавите 'sessionFactory.getCurrentSession(). Clear();' он может помочь. Но обратите внимание, потому что ящик отделяет все экземпляры и удаляет все ожидающие обновления, он очищает сеанс. – daniele

Смежные вопросы