Я новачок у сплячому режимі, і я не впевнений, чи використовувати сплячку SessionFactory
або JPA EntityManagerFactory
для створення сплячки Session
.
Яка різниця між цими двома? Які плюси і мінуси використання кожного з них?
Я новачок у сплячому режимі, і я не впевнений, чи використовувати сплячку SessionFactory
або JPA EntityManagerFactory
для створення сплячки Session
.
Яка різниця між цими двома? Які плюси і мінуси використання кожного з них?
Відповіді:
Віддавайте перевагу EntityManagerFactory
і EntityManager
. Вони визначаються стандартом JPA.
SessionFactory
і Session
є специфічними для сплячки. EntityManager
Викликає сеанс сплячого режиму під капотом. І якщо вам потрібні певні функції, які недоступні у програмі EntityManager
, ви можете отримати сеанс, зателефонувавши:
Session session = entityManager.unwrap(Session.class);
Session
від EntityManager
, так само як SessionFactory.getCurrentSession()
? Я маю на увазі, чи відкриється вона нова, Session
якщо вона ще не створена? Як це працює у багатопотоковому середовищі?
Я хочу додати, що ви також можете отримати сеанс сплячки за допомогою getDelegate()
методу виклику EntityManager
.
колишній:
Session session = (Session) entityManager.getDelegate();
Я віддаю перевагу EntityManager
API 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 можна легко знущатися.
return sessionFactory.getCurrentSession().createQuery("from User where id=1").list()
Використання підходу EntityManagerFactory дозволяє нам використовувати анотації методу зворотного виклику, такі як @PrePersist, @ PostPersist, @ PreUpdate без додаткової конфігурації.
Використання аналогічних зворотних дзвінків під час використання SessionFactory зажадає додаткових зусиль.
SessionFactory
vs. EntityManagerFactory
Як я пояснив у Посібнику зі сплячого режиму, сплячий режим SessionFactory
розширює JPA EntityManagerFactory
, як показано на наступній схемі:
Отже, SessionFactory
також є СПА EntityManagerFactory
.
Як SessionFactory
і EntityManagerFactory
містять метадані, що відображають сутність, так і дозволяють створити сплячку Session
або сну EntityManager
.
Session
vs. EntityManager
Так само, як SessionFactory
і EntityManagerFactory
, Зимова сплячка Session
розширює СПР EntityManager
. Отже, усі методи, визначені методом EntityManager
, доступні в режимі глибокого сну Session
.
І Session
`EntityManager переводить переходи стану сутності в оператори SQL, такі як SELECT, INSERT, UPDATE та DELETE.
Під час завантаження програми JPA або Hibernate у вас є два варіанти:
SessionFactory
допомогоюBootstrapServiceRegistryBuilder
. Якщо ви використовуєте Spring, режим завантаження в режимі глибокого сну робиться через LocalSessionFactoryBean
, як показано в цьому прикладі GitHub .EntityManagerFactory
за допомогою Persistence
класу або EntityManagerFactoryBuilder
. Якщо ви використовуєте Spring, завантажувальний засіб JPA виконується черезLocalContainerEntityManagerFactoryBean
, як показано в цьому прикладі GitHub .Віддавати перевагу завантажуванню через 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
і розкручувати лише їх до пов’язаних із ними сплячих інтерфейсів, коли ви хочете отримати доступ до якихось специфічних для спячі методів, недоступних у JPA, як, наприклад, отримання сутності через її природний ідентифікатор .
Використовуючи EntityManager, код більше не щільно поєднується зі сплячим режимом. Але для цього у використанні ми повинні використовувати:
javax.persistence.EntityManager
замість
org.hibernate.ejb.HibernateEntityManager
Аналогічно, для EntityManagerFactory використовуйте інтерфейс javax. Таким чином, код вільно пов'язаний. Якщо є краща реалізація JPA 2, ніж у сплячому режимі, переключення буде легко. У крайньому випадку, ми можемо набрати cast на HibernateEntityManager.
EntityManagerFactory - це стандартна реалізація, вона однакова для всіх реалізацій. Якщо ви перемістите ORM для будь-якого іншого постачальника, наприклад, EclipseLink, підхід до обробки транзакції не зміниться. На противагу цьому, якщо ви використовуєте заводський сеанс роботи в режимі сплячого режиму, він прив’язаний до сплячого API та не може перейти до нового постачальника.
Інтерфейс EntityManager схожий на sessionFactory в сплячому режимі. EntityManager під пакетом javax.persistance, але сеанс і сесіяFactory під org.hibernate.Session / sessionFactory пакет.
Менеджер суб'єктів - специфічний JPA, а сеанс / сесіяFactory - специфіка в сплячому режимі.