Я новичок в Hibernate и не уверен, использовать ли Hibernate SessionFactory
или JPA EntityManagerFactory
для создания Hibernate Session
.
В чем разница между этими двумя? Каковы плюсы и минусы использования каждого из них?
Я новичок в Hibernate и не уверен, использовать ли Hibernate SessionFactory
или JPA EntityManagerFactory
для создания Hibernate Session
.
В чем разница между этими двумя? Каковы плюсы и минусы использования каждого из них?
Предпочитаю EntityManagerFactory
и EntityManager
. Они определены стандартом JPA.
SessionFactory
и Session
зависят от режима гибернации. EntityManager
вызывает сеанс гибернации под капотом. А если вам нужны какие-то особые функции, которых нет в EntityManager
, вы можете получить сеанс, позвонив:
Session session = entityManager.unwrap(Session.class);
spring-data-jpa
, который использует.Каковы недостатки sessionFactory. THanks
- person black sensei; 09.01.2012
Session
от EntityManager
, то же самое, что и SessionFactory.getCurrentSession()
? Я имею в виду, он откроет новый Session
, если он еще не создан? Как это работает в многопоточной среде?
- person Sarvesh; 17.09.2018
SessionFactory
vs. EntityManagerFactory
Как я объяснил в Руководстве пользователя Hibernate, Hibernate SessionFactory
расширяет JPA EntityManagerFactory
, как показано на следующей диаграмме:
Итак, 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 или Hibernate у вас есть два варианта:
SessionFactory
с помощью _ 21_. Если вы используете Spring, загрузка Hibernate выполняется через LocalSessionFactoryBean
, как показано на этот пример GitHub.EntityManagerFactory
с помощью Persistence
класс или EntityManagerFactoryBuilder
. Если вы используете Spring, загрузка JPA выполняется через LocalContainerEntityManagerFactoryBean
, как показано на этот пример GitHub.Предпочтительнее использовать загрузку через JPA. Это потому, что JPA FlushModeType.AUTO
- намного лучший выбор, чем устаревший FlushMode.AUTO
, который нарушает согласованность чтения и записи для собственных запросов SQL.
Кроме того, если вы выполняете загрузку через 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, например, получение объекта через его естественный идентификатор .
Я хочу добавить к этому, что вы также можете получить сеанс Hibernate, вызвав метод getDelegate()
из EntityManager
.
ex:
Session session = (Session) entityManager.getDelegate();
Я предпочитаю 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 можно легко смоделировать.
return sessionFactory.getCurrentSession().createQuery("from User where id=1").list()
- person wst; 09.10.2015
Использование подхода EntityManagerFactory позволяет нам использовать аннотации методов обратного вызова, такие как @PrePersist, @ PostPersist, @ PreUpdate, без дополнительной настройки.
Использование аналогичных обратных вызовов при использовании SessionFactory потребует дополнительных усилий.
Связанные документы Hibernate можно найти здесь и здесь а>.
Связанный вопрос SOF и Обсуждение на весеннем форуме
Используя EntityManager, код больше не связан со спящим режимом. Но для этого в использовании мы должны использовать:
javax.persistence.EntityManager
вместо того
org.hibernate.ejb.HibernateEntityManager
Точно так же для EntityManagerFactory используйте интерфейс javax. Таким образом, код слабо связан. Если есть лучшая реализация JPA 2, чем спящий режим, переключение будет простым. В крайнем случае, мы можем ввести приведение к HibernateEntityManager.
EntityManagerFactory - это стандартная реализация, она одинакова для всех реализаций. Если вы перенесете ORM для любого другого провайдера, такого как EclipseLink, подход к обработке транзакции не изменится. Напротив, если вы используете фабрику сеансов спящего режима, она привязана к API спящего режима и не может перейти к новому поставщику.
Интерфейс EntityManager похож на sessionFactory в спящем режиме. EntityManager в пакете javax.persistance, но session и sessionFactory в пакете org.hibernate.Session / sessionFactory.
Менеджер сущностей зависит от JPA, а session / sessionFactory зависит от спящего режима.