Подходящий способ взаимодействия с сессиями Hibernate в многопоточной среде - PullRequest
0 голосов
/ 31 мая 2018

Контекст многопотоковой среды, такой как веб-приложение, когда требуется использовать сеансы с использованием Hibernate, что будет лучшим способом получить сеанс getcurrentsession () или opensession ()?

Как здесь opensession vs getcurrentsession упоминалось, что getcurrentsession не должен использоваться в веб-приложениях.

Хотя сессия не безопасна для протектора, по этой причине она не подходит для использования getcurrentsession?Нужно ли использовать opensesion и фиксировать и закрывать вручную?

Мне нужно четкое разъяснение.Спасибо всем.

PS: я использовал hibernate с приложением Spring Boot для тестирования.

1 Ответ

0 голосов
/ 01 июня 2018

Если у вас есть spring-boot-autocofigure в вашем classpath, скорее всего, он уже настраивает EntityManagerFactory для вас.Если у вас этого нет на вашем пути к классам, то очень просто преобразовать конфигурацию вашего компонента для SessionFactory в EntityManagerFactory.Сделав это, вы можете получить экземпляр super, просто выполнив в своем Spring bean-компоненте следующее:

@Service
public class MyBookServiceImpl implements BookService {
  @PersistenceContext
  private EntityManager entityManager;

  @Transactional
  public void doSomeFancyHibernateThing() {
    List<Book> allBooks = entityManager.createQuery( "FROM Book", Book.class )
       .getResultList();
  }
}

. Теперь вы можете добавить любые методы к классу обслуживания, которые вам нужны, для выполнения любых задач, которые требуются для этого.этот бин, чтобы выполнить и работать с экземпляром EntityManager.Вам не нужно беспокоиться о нескольких потоках и т. Д., Поскольку Spring автоматически предоставляет вам экземпляр EntityManager, который можно безопасно использовать в этом потоке, не заботясь о других потоках.

Примечание Я говорюздесь безопасно использовать в этот поток .Не пытайтесь использовать этот экземпляр в другом потоке и не ожидайте никаких осложнений или проблем .

Если вы чувствуете, что должны использовать SessionFactory по любой причине, вы можете использовать любой из двух методовв зависимости от того, насколько вы хотите управлять жизненным циклом сеанса.

Если вы хотите использовать #getCurrentSession(), важно также предоставить гибернацию следующей конфигурации, чтобы она связывалапоиск в текущем сеансе для локальной переменной потока, обеспечивающей, чтобы каждый поток выдавал свой собственный объект сеанса:

hibernate.current_session_context_class = thread

Преимущество использования вышеуказанногочто вам не нужно беспокоиться об управлении жизненным циклом Session, он будет автоматически закрыт и отпущен после завершения транзакции.

Например:

@Transactional
public void doSomeFancyHibernateThing() {
  Session session = sessionFactory.getCurrentSession();
  // do something here, when the method exits, the session is closed & destroyed.
}

Если вы хотитедля использования #openSession(), тогда жизненный цикл и время жизни возвращенного объекта Session находятся на вас, чтобы гарантировать, что вы справитесь с закрытием его ресурса.это соответственно.Другими словами, приведенный выше простой метод становится следующим:

public void doSomeFancyHibernateThing() {
  Session session = sessionFactory.openSession();
  try {
     // do something here
  }
  catch ( Exception e ) {
     // do whatever
  }
  finally {
    if ( session != null && session.isOpen() ) {
      session.close();
    }
  }
}

Как вы можете видеть, эквивалент JPA в верхней части ответа очень похож на использование getCurrentSession() в паре с этим спящимконфигурации.

Сильным преимуществом здесь является то, что использование JPA (пример вверху) удаляет все зависимости от Hibernate напрямую.И если вы обнаружите, что столкнулись с вариантом использования, где вам нужны специфичные для Hibernate функции, которые не раскрывает JPA, вы все равно можете легко получить Session, развернув EntityManager следующим образом:

Session session = entityManager.unwrap( Session.class );
// do whatever you need with a session easily.
...