в чем разница между jpa и hibernate
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 6
Библиотеки и стандарты
52. Что такое Hibernate? В чём разница между JPA и Hibernate?
53. Что такое каскадность? Как она используется в Hibernate?
PERSIST — операции сохранения будут происходить каскадно (для методов save() и persist() ). То есть, если мы сохраняем сущность, связанную с другими сущностями, они также сохраняются в БД (если их ещё там нет)
MERGE — операции обновления будут происходить каскадно (для метода merge() )
REMOVE — операции удаления происходят каскадно (метод remove() )
DETACH — связанные сущности не будут управляться сессией (метод detach() ). То есть, при их изменении не будет автоматического изменения их данных в БД — они переводятся из состояния persistence в detached (сущность, не управляемая JPA)
REFRESH — при каждом обновлении сущности данными из БД ( refresh() — обновляет detached объекты) связанные сущности обновляются так же. Например, вы изменили как-то данные, взятые из БД, и хотите вернуть их изначальные значения. В таком случае вам и пригодится данная операция.
REPLICATE — используется, когда у нас есть более одного источника данных и мы хотим, чтобы данные синхронизировались (метод Hibernate — replicate). У всех сущностей должны быть идентификаторы (id), чтобы не было проблем с их генерацией (чтобы для разных БД одна и та же сущность не имела разных id)
SAVE_UPDATE — каскадное сохранение/удаление (для метода Hibernate — saveOrUpdate )
Если не выбран тип каскадирования, никакая операция с сущностью не будет иметь эффекта для связанных с ней других entity.
54. Может ли Entity класс быть абстрактным?
55. Что такое entity manager? За что отвечает?
56. Что такое класс Assert? Зачем его использовать?
assertTrue( ) — ожидаемое значение, полученное в качестве аргумента, должно быть true
assertFalse( ) — ожидаемое значение, полученное в качестве аргумента, должно быть false
ORM (Object-Relational Mapping, объектно-реляционное отображение) — технология программирования, которая связывает базы данных с концепциями объектно-ориентированных языков программирования. В объектно-ориентированном программировании объекты приложения представляют объекты реального мира. ORM предназначена для преобразования объектов в форму для их сохранения в файлах или базах данных, а также их дальнейшего извлечения в программе с сохранением свойств объектов и отношений между ними. Такие объекты называют «хранимыми» (persistent). ORM освобождает программиста от работы с SQL-скриптами и позволяет сосредоточиться на ООП.
Для сохранения Java-объектов в базе данных и чтения из БД следует использовать JPA. JPA (Java Persistence API) — программный интерфейс API, входящий с версии Java 5 в состав платформ Java SE и Java EE. Существует несколько реализаций интерфейса JPA, среди которых наиболее популярным является Hibernate.
Непосредственно JPA представлен в пакете javax.persistence и включает платформо-независимый объектно-ориентированный язык запросов JPQL.
JPA оперирует таким понятием, как сущность Entity, которая является POJO-классом и связана с БД с помощью аннотации @Entity или через файл конфигурации XML. К такому классу предъявляются следующие требования :
При этом сущность может иметь непустые конструкторы, наследоваться или быть наследованной, содержать методы, не связанные со свойствами (методы get/set), и реализовывать интерфейсы. Entities могут быть связаны друг с другом (один-к-одному, один-ко-многим, многие-к-одному и многие-ко-многим).
Примеры сущностей Entity
В самом простом виде (без методов определения и получения значения свойств) JPA сущности можно представить следующим образом :
При описании сущностей были использованы аннотации. Пример использования аннотаций при описании сущности представлено здесь.
Java Persistence Query Language (JPQL) — платформо-независимый объектно-ориентированный язык запросов являющийся частью спецификации JPA.
JPQL используется для написания запросов к сущностям, хранящимся в реляционной базе данных. JPQL во многом похож на SQL, но в отличие от последнего, оперирует запросами, составленными по отношению к сущностям JPA, в отличие от прямых запросов к таблицам базы данных. В дополнение к получению объектов (запросы SELECT), JPQL поддерживает запросы, основанные на операторах UPDATE и DELETE. JPA реализует концепцию ORM.
JPQL основан на Hibernate Query Language (HQL), более раннем не стандартизованном языке запросов, включённом в библиотеку объектно-реляционного отображения Hibernate. Hibernate и HQL были созданы до появления спецификации JPA. JPQL является подмножеством языка запросов HQL.
Примеры JPQL
JPQL запрос получения списка авторов сущности «Author», упорядоченных в алфавитном порядке, имеет вид :
Запрос получения списка авторов, когда-либо опубликованных издательством «Publisher Press» :
В чем разница между Hibernate и Spring Data JPA
Каковы основные различия между Hibernate и Spring Data JPA? Когда не следует использовать Hibernate или Spring Data JPA? Кроме того, когда шаблон Spring JDBC может работать лучше, чем JPA Hibernate / Spring Data?
Spring Data предлагает решение для шаблона DDD Repository или устаревших GenericDao пользовательских реализаций. Он также может генерировать JPA-запросы от вашего имени с помощью соглашений имен методов.
Spring JDBC намного легче и предназначен для собственных запросов, и если вы собираетесь использовать только JDBC, то лучше использовать Spring JDBC для обработки многословности JDBC.
Поэтому Hibernate и Spring Data дополняют друг друга, а не являются конкурентами.
Здесь мы используем 3 разные вещи:
Spring Data JPA:
Допустим, вы используете Spring + Hibernate для вашего приложения. Теперь вам нужно иметь дао-интерфейс и реализацию, где вы будете писать операции crud, используя SessionFactory из hibernate. Допустим, вы пишете класс dao для класса Employee, завтра в вашем приложении может потребоваться написать аналогичную операцию crud для любой другой сущности. Таким образом, есть много шаблонного кода, который мы можем увидеть здесь.
Теперь данные Spring jpa позволяют нам определять интерфейсы dao, расширяя его репозитории (crudrepository, jparepository), чтобы обеспечить реализацию dao во время выполнения. Вам больше не нужно писать реализацию dao. Вот как Spring data jpa облегчает вашу жизнь.
Я не согласен, SpringJPA облегчает жизнь. Да, он предоставляет некоторые классы, и вы можете быстро создать простой DAO, но на самом деле это все, что вы можете сделать. Если вы хотите сделать что-то большее, чем findById () или сохранить, вы должны пройти через ад:
Почему собственное управление транзакциями является недостатком? Поскольку Java 1.8 допускает методы по умолчанию в интерфейсах, транзакции, основанные на аннотациях Spring, simple не работают.
Каковы основные различия между Hibernate и Spring Data JPA?
Когда не следует использовать Hibernate или Spring Data JPA? Кроме того, когда шаблон Spring JDBC может работать лучше, чем JPA Hibernate / Spring Data?
Используйте Spring JDBC только тогда, когда вам нужно использовать много объединений или когда вам нужно использовать Spring с несколькими подключениями к источникам данных. Как правило, избегайте JPA для Joins.
Spring Data это удобная библиотека, JPA которая абстрагируется от многих вещей и приносит волшебство Spring (нравится это или нет) в доступ к хранилищу сохраняемости. Он в основном используется для работы с реляционными базами данных. Короче говоря, он позволяет вам объявлять интерфейсы с такими методами, findByNameOrderByAge(String name); которые будут анализироваться во время выполнения и преобразовываться в соответствующие JPA запросы.
Его размещение на вершине JPA делает его использование заманчивым для:
Разработчики новичков, которые не знают SQL или знают это плохо. Это рецепт катастрофы, но они могут сойти с него, если проект тривиален.
Опытные инженеры, которые знают, что они делают, и хотят быстро их освоить. Это может быть жизнеспособной стратегией (но читайте дальше).
Связь между JPA, Spring data jpa и Hibernate
2 ответа 2
Hibernate это библиотека используемая для выполнения преобразования объектов к структурам данных реляционных БД и наоборот, что в оригинале называется ORM (Object/Relational Mapping). Обычно одному классу объектов сопоставляется одна таблица в БД, поля объекта сопоставляются к колонкам таблицы, связь между объектами в базе данных сохраняется посредством использования ключей (Primary Key/Foreign Key). Многие правила преобразования применяются автоматически библиотеками ORM, а другие необходимо описать программисту, чтобы ORM «знал» как осуществлять преобразование. В Hibernate раньше такую информацию описывали в XML, позднее появился Java Persistence API (JPA). JPA это стандартизированный программный интерфейс (API) позволяющий задать информацию необходимую для осуществления преобразования объектов к модели реляционных БД посредством аннотаций языка Java, а также там описаны интерфейсы объектов предназначенных для выполнения Create, Read, Update, Delete (CRUD) операций с БД. То есть, раньше каждая ORM библиотека предлагала свои собственные способы описания сопоставления объектов таблицам, а также механизмы для выполнения CRUD операций, а JPA привнес унификацию. Мне известны две реализации JPA, это Hibernate и EclipseLink.
Spring Data содержит логику позволяющую абстрагироваться от конкретных БД, например для типичных CRUD операций там есть CrudRepository позволяющий выполнять большинство типовых операций с практически любыми базами данных(реляционными и не реляционными).
А теперь конкретно ответы на твои вопросы:
В чем разница между JPA и Hibernate?
У меня есть опыт использования iBatis, и теперь я пытаюсь изучить Hibernate или JPA2. Я взял книгу Pro JPA2 и продолжает ссылаться на «поставщика JPA». Например:
Если вы считаете, что функция должна быть стандартизирована, вы должны высказаться и запросить его у вашего поставщика JPA.
Это меня смущает, поэтому у меня есть несколько вопросов:
22 ответа
Когда вы используете Hibernate с JPA, вы фактически используете реализацию JPA Hibernate. Преимущество этого заключается в том, что вы можете поменять реализацию Hibernate JPA для другой реализации спецификации JPA. Когда вы используете прямой Hibernate, вы блокируете реализацию, потому что другие ORM могут использовать разные методы/конфигурации и аннотации, поэтому вы не можете просто переключиться на другую ORM.
Некоторые вещи слишком трудно понять без исторической перспективы языка и понимания JCP.
Часто существуют сторонние компании, которые разрабатывают пакеты, которые выполняют функцию или заполняют пробел, который не является частью официального JDK. По различным причинам эта функция может стать частью Java JDK через JCP (Java Community Process)
Hibernate (в 2003 году) предоставил возможность абстрактного SQL и позволить разработчикам больше думать о сохраняющихся объектах (ORM). Вы уведомляете спящий режим о своих объектах Entity и автоматически генерируете стратегию для их сохранения. Hibernate предоставил реализацию для этого и API для реализации реализации либо через конфигурацию XML, либо аннотации.
В настоящее время основная проблема заключается в том, что ваш код тесно связан с конкретным вендором (Hibernate) для того, что, по мнению многих, должно быть более общим. Отсюда вытекает необходимость в универсальном API-интерфейсе persistence.
В то же время JCP с большим количеством данных от Hibernate и других поставщиков инструментов ORM разрабатывал JSR 220 (Java Specification Request), в результате чего JPA 1.0 (2006) и в конечном итоге JSR 317, который является JPA 2.0 (2009). Это спецификации общего API Java Persistence. API предоставляется в JDK как набор интерфейсов, так что ваши классы могут зависеть от javax.persistence и не беспокоиться о конкретном поставщике, который выполняет работу по сохранению ваших объектов. Это только API, а не реализация. Hibernate теперь становится одним из многих поставщиков, которые реализуют спецификацию JPA 2.0. Вы можете скопировать код JPA и выбрать любой совместимый поставщик ORM, который вам подходит.
Есть случаи, когда Hibernate может предоставить вам функции, которые не кодируются в JPA. В этом случае вы можете вставить конкретную аннотацию Hibernate непосредственно в свой класс, поскольку JPA не предоставляет интерфейс для выполнения этой задачи.