Я новичок в 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 - для режима гибернации.