Управление сессиями с использованием Hibernate в приложении Swing - PullRequest
7 голосов
/ 06 ноября 2008

Как вы управляете сессиями Hibernate в приложении Java Desktop Swing? Вы используете один сеанс? Несколько сеансов?

Вот несколько ссылок на эту тему:

Ответы [ 4 ]

10 голосов
/ 06 ноября 2008

Один сеанс. Начните транзакцию, когда вам нужно выполнить ряд операций (например, обновить данные после диалогового окна OK), зафиксировать tx в конце. Хотя соединение постоянно открыто (поскольку это один и тот же сеанс), и поэтому все возможности для кэширования могут использоваться как Hib, так и RDBMS.

Также может быть хорошей идеей реализовать прозрачное повторное открытие сеанса в случае, если соединение оборвалось - пользователи, как правило, оставляют приложения открытыми в течение продолжительных периодов времени, и они должны продолжать работать в понедельник, даже если сервер БД был перезагрузился в выходные.

Обновление

Йенс Шаудер указал причину использования нескольких сеансов: частичное (нежелательное) обновление сеанса. Ну, это сводится к тому, как вы используете Hibernate.

Предположим, у нас открыты два диалоговых окна (как в примере с блогом Йенса). Если пользователь щелкает по радиобоксу, и мы немедленно обновляем сущность Hibernate, связанную с этим радиобоксом, то, когда пользователь нажимает кнопку Отмена, у нас возникают проблемы - сеанс уже обновлен.

Правильный способ, на мой взгляд, состоит в том, чтобы обновлять только переменные диалога (не-спящие объекты). Затем, когда пользователь нажимает кнопку ОК, мы начинаем транзакцию, объединяем обновленные объекты, фиксируем транзакцию. Никакой мусор никогда не сохраняется в сессии.

MyHibernateUtils.begin();
Settings settings = DaoSettings.load();
// update setttings here
DaoSettings.save(settings);
MyHibernateUtils.commit(); 

Если мы реализуем такое четкое разделение интересов, мы можем позже переключиться на несколько сеансов с простым изменением реализации MyHibernateUtils.begin ().

Что касается возможной утечки памяти, хорошо ... Transaction.commit () вызывает Session.flush (), который AFAIK также очищает кеш. Также можно вручную управлять политикой кэширования, вызывая Session.setCacheMode ().

4 голосов
/ 05 марта 2009

Проблема с "'' session per thread ''" - хорошие приложения Swing делают доступ к базе данных вне EDT, обычно во вновь созданных потоках SwingWorker. Таким образом, «» сеанс на поток »быстро становится« сеансом за клик ».

4 голосов
/ 08 ноября 2008

Не используйте ни одного сеанса. Для всего, кроме самых маленьких приложений, он будет расти, собирая устаревшие данные, и становиться все медленнее и медленнее, поскольку грязная проверка должна проверять каждый объект в сеансе.

Если вам не нужна / не требуется ленивая загрузка и отслеживание изменений с помощью Hibernate, вы можете использовать кратковременные сеансы.

Но если вы хотите воспользоваться мощью Hibernate, используйте подход, который я описал в своем блоге: http://blog.schauderhaft.de/2008/09/28/hibernate-sessions-in-two-tier-rich-client-applications/

или в немецкой версии:

http://blog.schauderhaft.de/2007/12/17/hibernate-sessions-in-fat-client-anwendungen/

AFAIK, это действительно тот же подход, который описан в http://in.relation.to/Bloggers/HibernateAndSwingDemoApp, но с рекомендацией, как на самом деле охватить вашу сессию: On Session per Frame, за исключением модальных фреймов, которые используют сессию родительского фрейма.

Просто убедитесь, что никогда не объединяете объекты из разных сессий. Это доставит много хлопот.

В ответ на обновление Владимира:

  • Отмена на самом деле работает очень хорошо с моим подходом: выбросить сессию.
  • session.flush не устраняет проблему постоянно растущего сеанса, когда вы работаете с одним сеансом для приложения. Конечно, при таком подходе вы описываете, что можете работать с кратковременными сессиями, которые должны работать нормально. НО
  • вы многое потеряете: ленивая загрузка работает только с прикрепленными объектами, автоматическое обнаружение грязных объектов. Если вы работаете с отсоединенными объектами (или объектами, которые вообще не являются сущностями), вы должны сделать это самостоятельно.
1 голос
/ 05 декабря 2008

Используйте один сеанс на поток ( doc ) и столбец версии или метки времени, чтобы обеспечить оптимистичный параллелизм и, таким образом, избежать конфликтов сеанса с экземпляром. При необходимости подключайте экземпляры к сеансу, если только вам не нужны длительные транзакции или ограничительный уровень изоляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...