Я новичок в 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);
Session
от EntityManager
, так же как SessionFactory.getCurrentSession()
? Я имею в виду, откроется Session
ли оно новым, если оно еще не создано? Как это работает в многопоточной среде?
Я хочу добавить к этому, что вы также можете получить сессию Hibernate, вызвав getDelegate()
метод из EntityManager
.
например:
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()
Использование подхода EntityManagerFactory позволяет нам использовать аннотации методов обратного вызова, такие как @PrePersist, @ PostPersist, @ PreUpdate без дополнительной настройки.
Использование подобных обратных вызовов при использовании SessionFactory потребует дополнительных усилий.
SessionFactory
против EntityManagerFactory
Как я объяснил в Руководстве пользователя Hibernate , Hibernate SessionFactory
расширяет JPA EntityManagerFactory
, как показано на следующей диаграмме:
Таким образом, SessionFactory
это также JPA EntityManagerFactory
.
Оба SessionFactory
и EntityManagerFactory
содержат метаданные отображения сущностей и позволяют вам создавать Hibernate Session
или a EntityManager
.
Session
против EntityManager
Так же как SessionFactory
и EntityManagerFactory
, Hibernate Session
расширяет JPA EntityManager
. Итак, все методы, определенные в EntityManager
, доступны в HibernateSession
.
Session
И `EntityManager переводить переходы между состояниями сущностей в операторы SQL, как SELECT, INSERT, UPDATE и DELETE.
При начальной загрузке приложения JPA или Hibernate у вас есть два варианта:
SessionFactory
помощью BootstrapServiceRegistryBuilder
. Если вы используете 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, например, к извлечению объекта через его естественный идентификатор .
Используя EntityManager, код больше не тесно связан с Hibernate. Но для этого в использовании мы должны использовать:
javax.persistence.EntityManager
вместо того
org.hibernate.ejb.HibernateEntityManager
Аналогично, для EntityManagerFactory используйте интерфейс javax. Таким образом, код слабо связан. Если реализация JPA 2 лучше, чем в спящем режиме, переключение будет простым. В крайнем случае мы можем ввести приведение к HibernateEntityManager.
EntityManagerFactory является стандартной реализацией, она одинакова для всех реализаций. Если вы перенесете ORM на любого другого провайдера, такого как EclipseLink, подход к обработке транзакции не изменится. Напротив, если вы используете фабрику сессий hibernate, она привязана к API hibernate и не может перейти на нового поставщика.
Интерфейс EntityManager похож на sessionFactory в спящем режиме. EntityManager в пакете javax.persistance, но session и sessionFactory в пакете org.hibernate.Session / sessionFactory.
Менеджер сущностей специфичен для JPA, а session / sessionFactory - для режима гибернации.