Hibernate SessionFactory против JPA EntityManagerFactory

Я новичок в Hibernate и не уверен, использовать ли Hibernate SessionFactory или JPA EntityManagerFactory для создания Hibernate Session.

В чем разница между этими двумя? Каковы плюсы и минусы использования каждого из них?


person elpisu    schedule 12.04.2011    source источник
comment
Этот ответ на повторяющийся вопрос действительно хорош. stackoverflow.com/questions/23445830/ < / а>   -  person Sanghyun Lee    schedule 02.05.2015


Ответы (8)


Предпочитаю EntityManagerFactory и EntityManager. Они определены стандартом JPA.

SessionFactory и Session зависят от режима гибернации. EntityManager вызывает сеанс гибернации под капотом. А если вам нужны какие-то особые функции, которых нет в EntityManager, вы можете получить сеанс, позвонив:

Session session = entityManager.unwrap(Session.class);
person Bozho    schedule 12.04.2011
comment
Вы обладаете огромными знаниями! Я только начинаю работать с Hibernate и хотел бы использовать Hibernate с JPA-аннотациями - не могли бы вы порекомендовать какие-либо хорошие ресурсы для новичка (помимо документации Hibernate)? - person elpisu; 14.04.2011
comment
@elpisu - вообще-то не могу рекомендовать. Я использую только официальную документацию в качестве учебного ресурса (по крайней мере, в последние 2 года), поэтому я не знаю ничего надежного. Но документы достаточно хороши. - person Bozho; 14.04.2011
comment
@Bozho Я знаю, что уже поздно, но каковы недостатки использования SessionFactory и Session? Почему предпочтительнее использовать JPA? Спасибо - person Mickael Marrache; 11.11.2011
comment
@Bozho, пожалуйста, не могли бы вы уточнить, я также хочу знать, почему, особенно когда весна, вроде как собирается entitymanager с его новым spring-data-jpa, который использует.Каковы недостатки sessionFactory. THanks - person black sensei; 09.01.2012
comment
Ой, извините, я имею в виду, что data spring-data-jpa переходит к способу entityManager, когда дело доходит до поставщика сохраняемости гибернации. Я хотел знать, является ли это важным ключом к пониманию того, как перейти к способу entityManager, а не к способу сеанса.Спасибо. - person black sensei; 20.01.2012
comment
@MickaelMarrache использование JPA предпочтительнее, чем Hibernate API, потому что это стандарт Java Enterprise. Использование JPA (и ограничение себя этим без использования специфичных для Hibernate функций) улучшает переносимость приложения, то есть у вас есть возможность переключиться на другую структуру персистентности с минимальными изменениями в вашем приложении, если эта структура также соответствует стандарту JPA. . - person László van den Hoek; 21.09.2012
comment
Можно ли программно создавать HQL-запросы, используя только функциональные возможности, покрытые JPA? - person user1050755; 09.03.2013
comment
Лучше ли это просто потому, что это корпоративный стандарт? Я сомневаюсь, что. Стандарты обычно медленно развиваются и усложняются. А как насчет некоторых реальных преимуществ? JPA лучше, потому что в нем есть TypedQuery, он не дает вам повсюду приводить типы. - person Bastian Voigt; 04.03.2015
comment
Это подход, чтобы получить Session от EntityManager, то же самое, что и SessionFactory.getCurrentSession()? Я имею в виду, он откроет новый Session, если он еще не создан? Как это работает в многопоточной среде? - person Sarvesh; 17.09.2018

SessionFactory vs. EntityManagerFactory

Как я объяснил в Руководстве пользователя Hibernate, Hibernate SessionFactory расширяет JPA EntityManagerFactory, как показано на следующей диаграмме:

Отношения JPA и Hibernate

Итак, SessionFactory также является JPA EntityManagerFactory.

И SessionFactory, и EntityManagerFactory содержат метаданные сопоставления сущностей и позволяют создавать Hibernate Session или EntityManager.

Session vs. EntityManager

Так же, как SessionFactory и EntityManagerFactory, Hibernate Session расширяет JPA EntityManager. Итак, все методы, определенные EntityManager, доступны в Hibernate Session.

Session и EntityManager переводят переходы состояний сущностей в операторы SQL, такие как SELECT, INSERT, UPDATE и DELETE.

Гибернация против начальной загрузки JPA

При загрузке приложения JPA или Hibernate у вас есть два варианта:

  1. Вы можете выполнить загрузку с помощью собственного механизма Hibernate и создать SessionFactory с помощью _ 21_. Если вы используете Spring, загрузка Hibernate выполняется через LocalSessionFactoryBean, как показано на этот пример GitHub.
  2. Или вы можете создать JPA EntityManagerFactory с помощью Persistence класс или EntityManagerFactoryBuilder. Если вы используете Spring, загрузка JPA выполняется через LocalContainerEntityManagerFactoryBean, как показано на этот пример GitHub.

Предпочтительнее использовать загрузку через JPA. Это потому, что JPA FlushModeType.AUTO - намного лучший выбор, чем устаревший FlushMode.AUTO, который нарушает согласованность чтения и записи для собственных запросов SQL.

Распаковка JPA в спящий режим

Кроме того, если вы выполняете загрузку через JPA и ввели EntityManagerFactory через аннотацию @PersistenceUnit:

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

Вы можете легко получить доступ к базовому Sessionfactory, используя метод unwrap:

SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);

То же самое можно сделать с JPA EntityManager. Если вы вводите EntityManager через аннотацию @PersistenceContext:

@PersistenceContext
private EntityManager entityManager;

Вы можете легко получить доступ к базовому Session, используя метод unwrap:

Session session = entityManager.unwrap(Session.class);

Заключение

Итак, вам следует выполнить загрузку через JPA, использовать EntityManagerFactory и EntityManager и разворачивать их только в связанные с ними интерфейсы Hibernate, когда вы хотите получить доступ к некоторым специфичным для Hibernate методам, которые недоступны в JPA, например, получение объекта через его естественный идентификатор .

person Vlad Mihalcea    schedule 22.02.2020

Я хочу добавить к этому, что вы также можете получить сеанс Hibernate, вызвав метод getDelegate() из EntityManager.

ex:

Session session = (Session) entityManager.getDelegate();
person toytoy    schedule 19.01.2013
comment
обратите внимание, что unwrap() предпочтительнее, чем getDelegate() согласно java docs: javaee 6 и javaee 7. - person ryenus; 10.09.2014

Я предпочитаю JPA2 EntityManager API SessionFactory, потому что он кажется более современным. Один простой пример:

JPA:

@PersistenceContext
EntityManager entityManager;

public List<MyEntity> findSomeApples() {
  return entityManager
     .createQuery("from MyEntity where apples=7", MyEntity.class)
     .getResultList();
}

SessionFactory:

@Autowired
SessionFactory sessionFactory;

public List<MyEntity> findSomeApples() {
  Session session = sessionFactory.getCurrentSession();
  List<?> result = session.createQuery("from MyEntity where apples=7")
      .list();
  @SuppressWarnings("unchecked")
  List<MyEntity> resultCasted = (List<MyEntity>) result;
  return resultCasted;
}

Я думаю, очевидно, что первый выглядит чище и его легче тестировать, потому что EntityManager можно легко смоделировать.

person Bastian Voigt    schedule 04.03.2015
comment
Вы можете усложнить любой код, если хотите. return sessionFactory.getCurrentSession().createQuery("from User where id=1").list() - person wst; 09.10.2015
comment
Как напрямую у вас есть entityManager, и вы показываете, что вам нужно использовать sessionfactory для получения сеанса ..: D - person JavaLearner; 25.04.2018

Использование подхода EntityManagerFactory позволяет нам использовать аннотации методов обратного вызова, такие как @PrePersist, @ PostPersist, @ PreUpdate, без дополнительной настройки.

Использование аналогичных обратных вызовов при использовании SessionFactory потребует дополнительных усилий.

Связанные документы Hibernate можно найти здесь и здесь .

Связанный вопрос SOF и Обсуждение на весеннем форуме

person Kumar Sambhav    schedule 09.09.2013

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

javax.persistence.EntityManager

вместо того

org.hibernate.ejb.HibernateEntityManager

Точно так же для EntityManagerFactory используйте интерфейс javax. Таким образом, код слабо связан. Если есть лучшая реализация JPA 2, чем спящий режим, переключение будет простым. В крайнем случае, мы можем ввести приведение к HibernateEntityManager.

person Sairam Krish    schedule 26.09.2014

EntityManagerFactory - это стандартная реализация, она одинакова для всех реализаций. Если вы перенесете ORM для любого другого провайдера, такого как EclipseLink, подход к обработке транзакции не изменится. Напротив, если вы используете фабрику сеансов спящего режима, она привязана к API спящего режима и не может перейти к новому поставщику.

person ABODE    schedule 07.07.2019

Интерфейс EntityManager похож на sessionFactory в спящем режиме. EntityManager в пакете javax.persistance, но session и sessionFactory в пакете org.hibernate.Session / sessionFactory.

Менеджер сущностей зависит от JPA, а session / sessionFactory зависит от спящего режима.

person Avvappa Hegadyal    schedule 24.07.2018
comment
Ваш ответ правильный, но по сути он совпадает с ответом, о котором говорит Сангюн Ли в своих комментариях ... так что дубликат. - person RWC; 24.07.2018