Ответы на вопросы на собеседование Java Persistence API (JPA) (часть 2).
- Что такое EntityManager и какие основные его функции вы можете перечислить?
EntityManager это интерфейс, который описывает API для всех основных операций над Enitity, получение данных и других сущностей JPA. По сути главный API для работы с JPA. Основные операции:
- Для операций над Entity: persist (добавление Entity под управление JPA), merge (обновление), remove (удаления), refresh (обновление данных), detach (удаление из управление JPA), lock (блокирование Enity от изменений в других thread),
- Получение данных: find (поиск и получение Entity), createQuery, createNamedQuery, createNativeQuery, contains, createNamedStoredProcedureQuery, createStoredProcedureQuery
- Получение других сущностей JPA: getTransaction, getEntityManagerFactory, getCriteriaBuilder, getMetamodel, getDelegate
- Работа с EntityGraph: createEntityGraph, getEntityGraph
- Общие операции над EntityManager или всеми Entities: close, isOpen, getProperties, setProperty, clear.
- Какие четыре статуса жизненного цикла Entity объекта (Entity Instance’s Life Cycle) вы можете перечислить?
У Entity объекта существует четыре статуса жизненного цикла: new, managed, detached, или removed. Их описание
- new - объект создан, но при этом ещё не имеет сгенерированных первичных ключей и пока ещё не сохранен в базе данных,
- managed - объект создан, управляется JPA, имеет сгенерированные первичные ключи,
- detached - объект был создан, но не управляется (или больше не управляется) JPA,
- removed - объект создан, управляется JPA, но будет удален после commit’a транзакции.
- Как влияет операция merge на Entity объекты каждого из четырех статусов?
1. Если статус detached, то либо данные будет скопированы в существующей managed entity с тем же первичным ключом, либо создан новый managed в который скопируются данные,
2. Если статус Entity new, то будет создана новый managed entity, в который будут скопированы данные прошлого объекта,
3. Если статус managed, операция игнорируется, однако операция merge сработает на каскадно зависимые Entity, если их статус не managed,
4. Если статус removed, будет выкинут exception сразу или на этапе commit’а транзакции.
- Как влияет операция remove на Entity объекты каждого из четырех статусов?
1. Если статус Entity new, операция игнорируется, однако зависимые Entity могут поменять статус на removed, если у них есть аннотации каскадных изменений и они имели статус managed,
2. Если статус managed, то статус меняется на removed и запись объект в базе данных будет удалена при commit’е транзакции (так же произойдут операции remove для всех каскадно зависимых объектов),
3. Если статус removed, то операция игнорируется,
4. Если статус detached, будет выкинут exception сразу или на этапе commit’а транзакции.
- Как влияет операция persist на Entity объекты каждого из четырех статусов?
1. Если статус Entity new, то он меняется на managed и объект будет сохранен в базу при commit’е транзакции или в результате flush операций,
2. Если статус уже managed, операция игнорируется, однако зависимые Entity могут поменять статус на managed, если у них есть аннотации каскадных изменений,
3. Если статус removed, то он меняется на managed,
4. Если статус detached, будет выкинут exception сразу или на этапе commit’а транзакции.
- Как влияет операция refresh на Entity объекты каждого из четырех статусов?
1. Если статус Entity managed, то в результате операции будут востановленны все изменения из базы данных данного Entity, так же произойдет refresh всех каскадно зависимых объектов,
2. Если статус new, removed или detached, будет выкинут exception.
- Как влияет операция detach на Entity объекты каждого из четырех статусов?
1. Если статус Entity managed или removed, то в результате операции статус Entity (и всех каскадно-зависимых объектов) станет detached.
2. Если статус new или detached, то операция игнорируется.
- Для чего нужна аннотация Access?
Она определяет тип доступа (access type) для класса entity, суперкласса, embeddable или отдельных атрибутов, то есть как JPA будет обращаться к атрибутам entity, как к полям класса (FIELD) или как к свойствам класса (PROPERTY), имеющие гетеры (getter) и сетеры (setter).
- Для чего нужна аннотация Basic?
Basic - указывает на простейший тип маппинга данных на колонку таблицы базы данных. Также в параметрах аннотации можно указать fetch стратегию доступа к полю и является ли это поле обязательным или нет.
- Какой аннотациями можно перекрыть связи (override entity relationship) или атрибуты, унаследованные от суперкласса, или заданные в embeddable классе при использовании этого embeddable класса в одном из entity классов и не перекрывать в остальных?
Для такого перекрывания существует четыре аннотации:
- AttributeOverride чтобы перекрыть поля, свойства и первичные ключи,
- AttributeOverrides аналогично можно перекрыть поля, свойства и первичные ключи со множественными значениями,
- AssociationOverride чтобы перекрывать связи (override entity relationship),
- AssociationOverrides чтобы перекрывать множественные связи (multiple relationship).
- Какие аннотации служит для задания класса преобразования basic атрибута Entity в другой тип при сохранении/получении данных их базы (например, работать с атрибутом Entity boolean типа, но в базу сохранять его как число)?
Convert и Converts - позволяют указать класс для конвертации Basic атрибута Entity в другой тип (Converts - позволяют указать несколько классов конвертации). Классы для конвертации должны реализовать интерфейс AttributeConverter и могут быть отмечены (но это не обязательно) аннотацией Converter.
- Какой аннотацией можно управлять кешированием JPA для данного Entity?
Cacheable - позволяет включить или выключить использование кеша второго уровня (second-level cache) для данного Entity (если провайдер JPA поддерживает работу с кешированием и настройки кеша (second-level cache) стоят как ENABLE_SELECTIVE или DISABLE_SELECTIVE, см вопрос 41). Обратите внимание свойство наследуется и если не будет перекрыто у наследников, то кеширование измениться и для них тоже.
- Какой аннотацией можно задать класс, методы которого должен выполнится при определенных JPA операциях над данным Enitity или Mapped Superclass (такие как удаление, изменение данных и т.п.)?
Аннотация EntityListeners позволяет задать класс Listener, который будет содержать методы обработки событий (сallback methods) определенных Entity или Mapped Superclass.
- Для чего нужны callback методы в JPA? К каким сущностям применяются аннотации callback методов? Перечислите семь callback методов (или что тоже самое аннотаций callback методов).
Callback методы служат для вызова при определенных событиях Entity (то есть добавить обработку например удаления Entity методами JPA), могут быть добавлены к entity классу, к mapped superclass, или к callback listener классу, заданному аннотацией EntityListeners (см предыдущий вопрос). Существует семь callback методов (и аннотаций с теми же именами):
- PrePersist
- PostPersist
- PreRemove
- PostRemove
- PreUpdate
- PostUpdate
- PostLoad
- Какой аннотацей можно исключить поли и свойства Entity из маппинга (property or field is not persistent)?
Для этого служит аннотация Transient.
- Какие аннотации служить для установки порядка выдачи элементов коллекций Entity?
Для этого служит аннотация OrderBy и OrderColumn.
- Какие шесть видов блокировок (lock) описаны в спецификации JPA (или какие есть значения у enum LockModeType в JPA)?
У JPA есть шесть видов блокировок, перечислим их в порядке увеличения надежности (от самого ненадежного и быстрого, до самого надежного и медленного):
- NONE - без блокировки
- OPTIMISTIC (или синоним READ, оставшийся от JPA 1) - оптимистическая блокировка
- OPTIMISTIC_FORCE_INCREMENT (или синоним WRITE, оставшийся от JPA 1) - оптимистическая блокировка с принудительным увеличением поля версионности
- PESSIMISTIC_READ - пессимистичная блокировка на чтение
- PESSIMISTIC_WRITE - пессимистичная блокировка на запись (и чтение)
- PESSIMISTIC_FORCE_INCREMENT - пессимистичная блокировка на запись (и чтение) с принудительным увеличением поля версионности.
- Какие два вида кэшей (cache) вы знаете в JPA и для чего они нужны?
JPA говорит о двух видов кэшей (cache):
- first-level cache (кэш первого уровня) - кэширует данные одной транзакции,
- second-level cache (кэш второго уровня) - кэширует данные дольше чем одна транзакция. Провайдер JPA может, но не обязан реализовывать работу с кэшем второго уровня. Такой вид кэша позволяет сэкономить время доступа и улучшить производительность, однако оборотной стороной является возможность получить устаревшие данные.
- Какие есть варианты настройки second-level cache (кэша второго уровня) в JPA или что аналогично опишите какие значения может принимать элемент shared-cache-mode из persistence.xml?
JPA говорит о пяти значениях shared-cache-mode из persistence.xml, который определяет как будет использоваться second-level cache:
- ALL - все Entity могут кэшироваться в кеше второго уровня
- NONE - кеширование отключено для всех Entity
- ENABLE_SELECTIVE - кэширование работает только для тех Entity, у которых установлена аннотация Cacheable(true) или её xml эквивалент, для всех остальных кэширование отключено
- DISABLE_SELECTIVE - кэширование работает для всех Entity, за исключением тех у которых установлена аннотация Cacheable(false) или её xml эквивалент
- UNSPECIFIED - кеширование не определенно, каждый провайдер JPA использует свою значение по умолчанию для кэширования
- Как можно изменить настройки fetch стратегии любых атрибутов Entity для отдельных запросов (query) или методов поиска (find), то если у Enity есть атрибут с fetchType = LAZY, но для конкретного запроса его требуется сделать EAGER или наоборот?
Для этого существует EntityGraph API, используется он так: с помощью аннотации NamedEntityGraph для Entity, создаются именованные EntityGraph объекты, которые содержат список атрибутов у которых нужно поменять fetchType на EAGER, а потом данное имя указывается в hits запросов или метода find. В результате fetchType атрибутов Entity меняется, но только для этого запроса. Существует две стандартных property для указания EntityGraph в hit:
- javax.persistence.fetchgraph - все атрибуты перечисленные в EntityGraph меняют fetchType на EAGER, все остальные на LAZY
- javax.persistence.loadgraph - все атрибуты перечисленные в EntityGraph меняют fetchType на EAGER, все остальные сохраняют свой fetchType (то есть если у атрибута, не указанного в EntityGraph, fetchType был EAGER, то он и останется EAGER)С помощью NamedSubgraph можно также изменить fetchType вложенных объектов Entity.
- Каким способом можно получить метаданные JPA (сведения о Entity типах, Embeddable и Managed классах и т.п.)?
Для получения такой информации в JPA используется интерфейс Metamodel. Объект этого интерфейса можно получить методом getMetamodel у EntityManagerFactory или EntityManager.
- Каким способом можно в коде работать с кэшем второго уровня (удалять все или определенные Entity из кеша, узнать закэшировался ли данное Entity и т.п.)?
Для работы с кэшем второго уровня (second level cache) в JPA описан Cache интерфейс, содержащий большое количество методов по управлению кэшем второго уровня (second level cache), если он поддерживается провайдером JPA, конечно. Объект данного интерфейса можно получить с помощью метода getCache у EntityManagerFactory.
- В чем разница в требованиях к Entity в Hibernate, от требований к Entity, указанных в спецификации JPA?
1. Конструктор без аргументов не обязан быть public или protected, рекомендуется чтобы он был хотя бы package видимости, однако это только рекомендация, если настройки безопасности Java позволяют доступ к приватным полям, то он может быть приватным,
2. JPA категорически требует не использовать final классы, Hibernate лишь рекомендует не использовать такие классы чтобы он мог создавать прокси для ленивой загрузки, однако позволяет либо выключить прокси Proxy(lazy=false), либо использовать в качестве прокси интерфейс, содержащий все методы маппинга для данного класса (аннотацией Proxy(proxyClass=интерфейс.class) )
- Какая уникальная стратегия наследования есть в Hibernate, но нет в спецификации JPA?
В отличии JPA в Hibernate есть уникальная стратегия наследования, которая называется implicit polymorphism.
- Какие основные новые возможности появились в спецификации JPA 2.1 по сравнению с JPA 2.0 (перечислите хотя бы пять-шесть новых возможностей)?
В спецификации JPA 2.1 появились:
- Entity Graphs - механизм динамического изменения fetchType для каждого запроса
- Converters - механизм определения конвертеров для задания функций конвертации атрибутов Entity в поля базы данных
- DDL генерация - автоматическая генерация таблиц, индексов и схем
- Stored Procedures - механизм вызова хранимых процедур из JPA
- Criteria Update/Delete - механизм вызова bulk updates или deletes, используя Criteria API
- Unsynchronized persistence contexts - появление возможности указать SynchronizationType
- Новые возможности в JPQL/Criteria API: арифметические подзапросы, generic database functions, join ON clause, функция TREAT
- Динамическое создание именованных запросов (named queries)
- Интерфейс EntityManager получил новые методы createStoredProcedureQuery, isJoinedToTransaction и createQuery(CriteriaUpdate или CriteriaDelete)
- Абстрактный класс AbstractQuery стал наследоваться от класса CommonAbstractCriteria, появились новые интерфейсы CriteriaUpdate, CriteriaDelete унаследованные CommonAbstractCriteria,
- PersistenceProvider получил новые функции generateSchema позволяющие генерить схемы,
- EntityManagerFactory получил методы addNamedQuery, unwrap, addNamedEntityGraph, createEntityManager (с указанием SynchronizationType)
- Появился новый enum SynchronizationType, Entity Graphs, StoredProcedureQuery и AttributeConverter интерфейсы.
Много интересной информации. Доступно написано.
ОтветитьУдалить