Я новачок у сплячому режимі, і я не впевнений, чи використовувати сплячку 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();
Я віддаю перевагу 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 можна легко знущатися.
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 - специфіка в сплячому режимі.