Ошибка гибернации "база данных заблокирована".Как правильно закрыть сеанс? - PullRequest
3 голосов
/ 09 ноября 2011

В моем приложении я открываю сеанс, создаю критерии, но не закрываю его.Затем в другом методе я снова открываю сессию, обновляю объект и получаю database is locked на tr.commit().

Если я ставлю session.close() в первый раз, я получаю

Не удалось инициализироватьпрокси - без сеанса.

Как правильно закрыть и открыть сеанс?Или мне нужно скопировать прокси объекты на созданные мной и затем close()?

Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tr=session.beginTransaction();

        Criteria criteria = session.createCriteria(MyDocument.class);
        criteria.add(Expression.like("isMainDoc", 1));

        List docs = criteria.list();

        tr.commit();
        session.close();

Я полный новичок.я использую sqlite.Любая помощь будет оценена.Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 09 ноября 2011

Hibernate Session обычно привязан к потоку.

Итак, возможно, вам следует реструктурировать свой код, чтобы получить сеанс в начале вашей обработки (например, в экземпляре ServletFilter веб-приложения).

И затем в каждом методе вы можете использовать один и тот же объект сеанса, чтобы начать новую транзакцию (и затем, конечно, также завершить транзакцию.

public void doWork(){
  Transaction tx = null;
   try{
     tx = session.beginTransaction();  
   }catch(){
   } finally {
     // if tx != null then.. close transaction, or rollback?
   }
}

РЕДАКТИРОВАТЬ: И затем, конечно, закрытьсеанс, когда обработка завершена (в веб-приложении, которое также может быть в том же ServletFilter) Google: шаблон «Открыть сеанс в представлении».

2 голосов
/ 09 ноября 2011

Причина

Возможно, вы получаете сообщение об ошибке при попытке получить доступ к свойствам экземпляров класса MyDocument, возвращаемых запросом.

Hibernate lazy по умолчанию.Он возвращает вам proxy для объекта вместо попадания в базу данных при каждом обращении к ссылочному свойству.Это поведение может быть перезаписано при необходимости.Всегда помните, что не удалось инициализировать прокси-сервер - сеанс не получен, когда код пытается получить доступ к свойствам proxy (путем нажатия на базу данных) и обнаруживает, что сеанс недоступен (сеанс необходим, поскольку Hibernate обращается к базе данных с использованием этого интерфейса)

Решение

Убедитесь, что ваш сеанс открыт всякий раз, когда Hibernate пытается загрузить объект, который еще не был загружен.Как ты это делаешь?

(Простыми словами) В Hibernate есть две школы мысли:

  1. Извлеките все данные, к которым вы можете получить доступ, прежде чем закрыть Сессию ИЛИ
  2. keepСессия открыта на все время работы с объектами.

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

hibernate.current_session_context_class в конфигурации гибернации, которая может принимать значения jta |нить |удалось |custom.Class.Эта переменная определяет единицу работы для Session.

Последнее, но самое главное, попробуйте использовать Контекстные сеансы (вы, должно быть, натолкнулись на .getCurrentSession(), который поможет вам получить тот же сеанс, который всегда открыт в любом месте вашего кода . Hibernate обрабатывает все за кадром.

Надеюсь, этот ответ послужит вам руководством для выбора правильного пути использования Hibernate, а непросто решить эту конкретную проблему.

1 голос
/ 09 ноября 2011

Выполните следующие шаги при использовании транзакций гибернации Прочитайте API здесь .

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

//Or any other operation.
session.save(a);

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