Hibernate. Update. Популярные грабли


hibernate
Сейчас многие любят реализовывать Data Access Object (DAO) на базе Hibernate.
Хотелось уделить особое внимание работе с объектами в различных состояниях.
Пример из документации :

   DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
   cat.setName("PK");
   sess.flush();  // changes to cat are automatically detected and persisted

Некоторые думают, что нужно делать так:

   DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
   cat.setName("PK");
   sess.update(cat); // НЕ НАДО, ОНО САМО СОХРАНИТСЯ !!!! REMOVE THIS LINE
   sess.flush();  // changes to cat are automatically detected and persisted


Это является следствием непонимания работы Hibernate и различий между PERSISTENT, TRANSIENT или DETACHED состоянием объектов.

В популярной статье на хабре Основы Hibernate приводится такой способ реализации DAO:

public  class BusDAOImpl implements BusDAO {
   ...
   public  void updateBus(Long bus_id, Bus bus) throws SQLException {
    Session session = null;
    try {
      session = HibernateUtil.getSessionFactory().openSession();
      session.beginTransaction();
      session.update(bus);
      session.getTransaction().commit();
    } catch (Exception e) {
      JOptionPane.showMessageDialog(null, e.getMessage(), "Ошибка при вставке", JOptionPane.OK_OPTION);
    } finally {
      if (session != null && session.isOpen()) {
        session.close();
      }
    }
  }
   ...
}

Все хорошо, но какой мы должны передавать объект bus – PERSISTENT, TRANSIENT или DETACHED?
Возможно именно эти неудобства приводят к использованию антипаттерна session-per-operation, когда мы открываем новую сессию на каждый чих. Подробнее можно прочитать в документации:
“Do not use the session-per-operation antipattern: do not open and close a Session for every simple database call in a single thread. “

Любое использование либо копирование материалов или подборки материалов сайта, элементов дизайна и оформления допускается лишь с разрешения правообладателя и только со ссылкой на источник: programador.ru

Телеграм канал: @prgrmdr
Почта для связи: vit [at] programmisty.com