Hibernate SessionFactory проти JPA EntityManagerFactory


251

Я новачок у сплячому режимі, і я не впевнений, чи використовувати сплячку SessionFactoryабо JPA EntityManagerFactoryдля створення сплячки Session.

Яка різниця між цими двома? Які плюси і мінуси використання кожного з них?


6
Ця відповідь на повторне запитання справді гарна. stackoverflow.com/questions/23445830 / ...
Sanghyun Lee

Відповіді:


365

Віддавайте перевагу EntityManagerFactoryі EntityManager. Вони визначаються стандартом JPA.

SessionFactoryі Sessionє специфічними для сплячки. EntityManagerВикликає сеанс сплячого режиму під капотом. І якщо вам потрібні певні функції, які недоступні у програмі EntityManager, ви можете отримати сеанс, зателефонувавши:

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

2
@elpisu - насправді не можу рекомендувати. Я використовую лише офіційну документацію як навчальний ресурс (принаймні за останні 2 роки), тому нічого іншого надійного не знаю. Але документи досить хороші.
Божо

7
@Bozho Я знаю, що пізно, але які недоліки використання SessionFactory та Session? Чому перевагу використовувати JPA? Спасибі
Мікаель Марраш

12
@MickaelMarrache слід використовувати перевагу використання JPA над API Hibernate, оскільки це стандарт Java Enterprise. Використання JPA (і обмеження себе нею, не використовуючи специфічних для сплячого режиму) функцій покращує мобільність додатків, тобто у вас є можливість перейти на іншу систему збереження з мінімальними змінами у вашій програмі, якщо ця рамка також відповідає стандарту JPA .
László van den Hoek

2
Це краще лише тому, що це стандарт підприємства? Сумніваюсь у цьому. Стандарти зазвичай розвиваються повільно і складні. А як щодо деяких реальних благ життя? JPA кращий, оскільки він має TypedQuery, не дозволяє вам набирати текст в усьому місці.
Бастіан Войтт

1
Є чи цей підхід , щоб отримати Sessionвід EntityManager, так само як SessionFactory.getCurrentSession()? Я маю на увазі, чи відкриється вона нова, Sessionякщо вона ще не створена? Як це працює у багатопотоковому середовищі?
Сарвеш

32

Я хочу додати, що ви також можете отримати сеанс сплячки за допомогою getDelegate()методу виклику EntityManager.

колишній:

Session session = (Session) entityManager.getDelegate();

28
Слід зазначити , що unwrap()це краще більш ніж в getDelegate()відповідно до Java - документи: JavaEE 6 і JavaEE 7 .
ryenus

22

Я віддаю перевагу EntityManagerAPI JPA2 більшеSessionFactory , тому що він відчуває себе більш сучасним. Один простий приклад:

JPA:

@PersistenceContext
EntityManager entityManager;

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

СесіяФактори:

@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 можна легко знущатися.


30
Ви можете зробити будь-який код складним, якщо хочете. return sessionFactory.getCurrentSession().createQuery("from User where id=1").list()
wst

Як безпосередньо ви отримали entitManager, і ви показуєте, що вам потрібно використовувати sessionfactory для отримання сеансу ..: D
JavaLearner

21

Використання підходу EntityManagerFactory дозволяє нам використовувати анотації методу зворотного виклику, такі як @PrePersist, @ PostPersist, @ PreUpdate без додаткової конфігурації.

Використання аналогічних зворотних дзвінків під час використання SessionFactory зажадає додаткових зусиль.

Пов’язані документи зі сплячки можна знайти тут і тут .

Питання щодо SOF та обговорення весняного форуму


21

SessionFactory vs. EntityManagerFactory

Як я пояснив у Посібнику зі сплячого режиму, сплячий режим SessionFactoryрозширює JPA EntityManagerFactory, як показано на наступній схемі:

JPA та сплячі відносини

Отже, SessionFactoryтакож є СПА EntityManagerFactory.

Як SessionFactoryі EntityManagerFactoryмістять метадані, що відображають сутність, так і дозволяють створити сплячку Sessionабо сну EntityManager.

Session vs. EntityManager

Так само, як SessionFactoryі EntityManagerFactory, Зимова сплячка Sessionрозширює СПР EntityManager. Отже, усі методи, визначені методом EntityManager, доступні в режимі глибокого сну Session.

І Session`EntityManager переводить переходи стану сутності в оператори SQL, такі як SELECT, INSERT, UPDATE та DELETE.

Hibernate vs. JPA bootstrap

Під час завантаження програми JPA або Hibernate у вас є два варіанти:

  1. Ви можете завантажувати завантажувальний механізм за допомогою власного механізму сплячки та створити за SessionFactoryдопомогоюBootstrapServiceRegistryBuilder . Якщо ви використовуєте Spring, режим завантаження в режимі глибокого сну робиться через LocalSessionFactoryBean, як показано в цьому прикладі GitHub .
  2. Або ви можете створити JPA EntityManagerFactoryза допомогою Persistenceкласу або EntityManagerFactoryBuilder. Якщо ви використовуєте Spring, завантажувальний засіб JPA виконується черезLocalContainerEntityManagerFactoryBean , як показано в цьому прикладі GitHub .

Віддавати перевагу завантажуванню через 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і розкручувати лише їх до пов’язаних із ними сплячих інтерфейсів, коли ви хочете отримати доступ до якихось специфічних для спячі методів, недоступних у JPA, як, наприклад, отримання сутності через її природний ідентифікатор .


2

Використовуючи EntityManager, код більше не щільно поєднується зі сплячим режимом. Але для цього у використанні ми повинні використовувати:

javax.persistence.EntityManager

замість

org.hibernate.ejb.HibernateEntityManager

Аналогічно, для EntityManagerFactory використовуйте інтерфейс javax. Таким чином, код вільно пов'язаний. Якщо є краща реалізація JPA 2, ніж у сплячому режимі, переключення буде легко. У крайньому випадку, ми можемо набрати cast на HibernateEntityManager.


2

EntityManagerFactory - це стандартна реалізація, вона однакова для всіх реалізацій. Якщо ви перемістите ORM для будь-якого іншого постачальника, наприклад, EclipseLink, підхід до обробки транзакції не зміниться. На противагу цьому, якщо ви використовуєте заводський сеанс роботи в режимі сплячого режиму, він прив’язаний до сплячого API та не може перейти до нового постачальника.


1

Інтерфейс EntityManager схожий на sessionFactory в сплячому режимі. EntityManager під пакетом javax.persistance, але сеанс і сесіяFactory під org.hibernate.Session / sessionFactory пакет.

Менеджер суб'єктів - специфічний JPA, а сеанс / сесіяFactory - специфіка в сплячому режимі.


Ваша відповідь правильна, але по суті така ж, як відповідь, на яку посилається Сандьюн Лі у своїх коментарях ... так що дублікат.
RWC
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.