ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 01.12.2023

Просмотров: 477

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

2. Стратегия «соединения» (JOINED_TABLE) – в этой стратегии каждый класс entity сохраняет данные в свою таблицу, но только уникальные поля (не унаследованные от классов-предков) и первичный ключ, а все унаследованные колонки записываются в таблицы класса-предка, дополнительно устанавливается связь (relationships) между этими таблицами, например, в случае классов Animals будут три таблицы: animals, cats, dogs.
Причем в cats будет записан только ключ и скорость лазанья, в dogs – ключ и умеет ли пес приносить палку, а в animals все остальные данные cats и dogs c ссылкой на соответствующие таблицы. Минусом является потеря производительности от объединения таблиц (join) для любых операций.
3. Таблица для каждого класса (TABLE_PER_CLASS) – каждый отдельный класс- наследник имеет свою таблицу, т. е. для cats и dogs все данные будут записываться просто в таблицы cats и dogs как если бы они вообще не имели общего суперкласса. Минусом является плохая поддержка полиморфизма (polymorphic relationships) и то, что для выборки всех классов иерархии потребуются большое количество отдельных sql-запросов или использование UNION-запроса.
Для задания стратегии наследования используется аннотация Inheritance (или соответствующие блоки).
Как мапятся Enum'ы?
@Enumerated(EnumType.STRING) означает, что в базе будут храниться имена Enum.
@Enumerated(EnumType.ORDINAL) – в базе будут храниться порядковые номера Enum.
Другой вариант – можно смапить enum в БД и обратно в методах с аннотациями @PostLoad и @PrePersist. @EntityListener над классом Entity, где указать класс, в котором создать два метода, помеченных этими аннотациями.
Идея в том, чтобы в сущности иметь не только поле с Enum, но и вспомогательное поле.
Поле с Enum аннотируем @Transient, а в БД будет храниться значение из вспомогательного поля.
В JPA с версии 2.1 можно использовать Converter для конвертации Enum’а в некое его значение для сохранения в БД и получения из БД. Нужно лишь создать новый класс,
который реализует javax.persistence.AttributeConverter и аннотировать его с помощью
@Converter и поле в сущности аннотацией @Convert.
Как мапятся даты (до Java 8 и после)?
Аннотация @Temporal до Java 8, в которой надо было указать, какой тип даты хотим использовать.
В Java 8 и далее аннотацию ставить не нужно.
Как «смапить» коллекцию примитивов?
@ElementCollection
@OrderBy
Если у сущности есть поле с коллекцией, то обычно ставят над ним аннотации @OneToMany либо @ManyToMany. Но данные аннотации применяются, когда это коллекция других сущностей (entities). Если у сущности коллекция не других сущностей, а базовых или встраиваемых (embeddable) типов, то для этих случаев в JPA имеется специальная аннотация @ElementCollection, которая указывается в классе сущности над полем

коллекции. Все записи коллекции хранятся в отдельной таблице, то есть в итоге получаем две таблицы: одну для сущности, вторую для коллекции элементов.
При добавлении новой строки в коллекцию она полностью очищается и заполняется заново,
так как у элементов нет id. Можно решить с помощью @OrderColumn.
@CollectionTable позволяет редактировать таблицу с коллекцией.
Какие есть виды связей?
Существуют 4 типа связей:
1. OneToOne – когда один экземпляр Entity может быть связан не больше чем с одним экземпляром другого Entity.
Необходимо ставить forieghnKey на родительскую таблицу и аннотацию JoinColomun, в атрибуте name объяснить, к какой колонке ссылаться на родительской сущности.
Что стоит в поле, где все связано? Стоит тип другой сущности.
2. OneToMany – когда один экземпляр Entity может быть связан с несколькими экземплярами других Entity. Когда одна сущность может ссылаться ко многим сущностям.
Храним коллекцию.
3. ManyToOne – обратная связь для OneToMany. Несколько экземпляров Entity могут быть связаны с одним экземпляром другого Entity. Несколько машин может быть у нескольких юзеров.
Одна сущность хранится.
4. ManyToMany – экземпляры Entity могут быть связаны с несколькими экземплярами друг друга. Каждый из двух Entity может быть по несколько других Entity. Много сущностей могут относиться к многим сущностями.
Сводная таблица с айдишниками, коллекции коллекций хранятся.
Каждую из которых можно разделить ещё на два вида:
1. Bidirectional с использованием @MappedBy на стороне, где указывается @OneToMany
2. Unidirectional.
Bidirectional – ссылка на связь устанавливается у всех Entity, то есть в случае OneToOne A-B
в Entity A есть ссылка на Entity B, в Entity B есть ссылка на Entity A. Entity A считается владельцем этой связи (это важно для случаев каскадного удаления данных, тогда при удалении A также будет удалено B, но не наоборот).
Undirectional – ссылка на связь устанавливается только с одной стороны, то есть в случае
OneToOne A-B только у Entity A будет ссылка на Entity B, у Entity B ссылки на A не будет.
Что такое владелец связи?
В отношениях между двумя сущностями всегда есть одна владеющая сторона, а зависимой может и не быть, если это однонаправленные отношения.
По сути, у кого есть внешний ключ на другую сущность, тот и владелец связи. То есть, если в таблице одной сущности есть колонка, содержащая внешние ключи от другой сущности, то первая сущность признается владельцем связи, вторая сущность – зависимой.


В однонаправленных отношениях сторона, которая имеет поле с типом другой сущности,
является владельцем этой связи по умолчанию.
Что такое каскады?
Каскадирование – это какое-то действие с целевой Entity, то же самое действие будет применено к связанной Entity.
JPA CascadeType:

ALL гарантирует, что все персистентные события, которые происходят на родительском объекте, будут переданы дочернему объекту;

PERSIST означает, что операции save() или persist() каскадно передаются связанным объектам;

MERGE означает, что связанные entity объединяются, когда объединяется entity- владелец;

REMOVE удаляет все entity, связанные с удаляемой entity;

DETACH отключает все связанные entity, если происходит «ручное отключение»;

REFRESH повторно считывает значение данного экземпляра и связанных сущностей из базы данных при вызове refresh().
Разница между PERSIST и MERGE?
persist(entity) следует использовать с новыми объектами, чтобы добавить их в БД (если объект уже существует в БД, будет выброшено исключение EntityExistsException).
Если использовать merge(entity), то сущность, которая уже управляется в контексте персистентности, будет заменена новой сущностью (обновленной), и копия этой обновленной сущности вернется обратно. Рекомендуется использовать для уже сохраненных сущностей.
Какие два типа fetch-стратегии в JPA вы знаете?
1. LAZY – Hibernate может загружать данные не сразу, а при первом обращении к ним, но так как это необязательное требование, то Hibernate имеет право изменить это поведение и загружать их сразу. Это поведение по умолчанию для полей, аннотированных @OneToMany,
@ManyToMany и @ElementCollection. В объект загружается прокси lazy-поля. Если там стоит коллекция, то это будет коллекция Hibernate, именуемая типом коллекции bag().
Подгрузка должна происходить в одной транзакции или пока не закроем ЕнтитуМенеджер.
Если обратимся за персистетнымКонтекстом, то LazyEnitialization.
Если используем Бэк, то он использует Лист и Сет и т. д.
2. EAGER – данные поля будут загружены немедленно. Это поведение по умолчанию для полей, аннотированных @Basic, @ManyToOne и @OneToOne.
Все, что заканчивается на One – Eager, Many – Lazy.
Для кого можем использовать ManyToOne? Для владельца связи.

Какие четыре статуса жизненного цикла Entity-объекта (Entity Instance’s Life
Cycle) вы можете перечислить?

transient (new) – свежесозданная оператором new() сущность не имеет связи с базой данных, не имеет данных в базе данных и не имеет сгенерированных первичных ключей и не имеет контекста Персистентности. При сохранении переходит в managed.

managed – объект уже создан и получает первичный ключ, управляется контекстом персистентности.( сохранен в БД, имеет primary key), переходит под управляется JPA,
если вызываем detached, то полностью отвязываем от контекста.

detached – не управляется JPA, но может существовать в БД, объект создан, но не управляется JPA. В этом состоянии сущность не связана со своим контекстом
(отделена от него) и нет экземпляра Session, который бы ей управлял.

removed – объект создан, управляется JPA, будет удален из БД, при commit-е транзакции статус станет опять detached.
Как влияет операция persist на Entity-объекты каждого из четырех
статусов?

new → managed, объект будет сохранен в базу при commit-е транзакции или в результате flush-операций;

managed → операция игнорируется, однако зависимые Entity могут поменять статус на managed, если у них есть аннотации каскадных изменений;

detached → exception сразу или на этапе commit-а транзакции;

removed → managed, но только в рамках одной транзакции.
Как влияет операция remove на Entity-объекты каждого из четырех
статусов?

new → операция игнорируется, однако зависимые Entity могут поменять статус на removed, если у них есть аннотации каскадных изменений и они имели статус managed;

managed → removed, запись объекта в базе данных будет удалена при commit-е транзакции (также произойдут операции remove для всех каскаднозависимых объектов);

detached → exception сразу или на этапе commit-а транзакции;

removed → операция игнорируется.
Как влияет операция merge на Entity-объекты каждого из четырех
статусов?

new → будет создан новый managed entity, в который будут скопированы данные прошлого объекта;

managed → операция игнорируется, однако операция merge сработает на каскаднозависимые Entity, если их статус не managed;

detached → либо данные будут скопированы в существующий managed entity с тем же первичным ключом, либо создан новый managed, в который скопируются данные;

removed → exception сразу или на этапе commit-а транзакции.


Как влияет операция refresh на Entity-объекты каждого из четырех
статусов?

managed → будут восстановлены все изменения из базы данных данного Entity, также произойдет refresh всех каскаднозависимых объектов;

new, removed, detached → exception.
Как влияет операция detach на Entity-объекты каждого из четырех
статусов?

managed, removed → detached;

new, detached → операция игнорируется.
Для чего нужна аннотация Basic?
@Basic указывает на простейший тип маппинга данных на колонку таблицы базы данных. В
параметрах аннотации можно указать fetch стратегию доступа к полю и является ли это поле обязательным или нет. Может быть применена к полю любого из следующих типов:

примитивы и их обертки;

java.lang.String;

java.math.BigInteger;

java.math.BigDecimal;

java.util.Date;

java.util.Calendar;

java.sql.Date;

java.sql.Time;

java.sql.Timestamp;

byte[] or Byte[];

char[] or Character[];

enums;

любые другие типы, которые реализуют Serializable.
Аннотацию @Basic можно не ставить, как это и происходит по умолчанию.
Аннотация @Basic определяет 2 атрибута:
1.
1   ...   15   16   17   18   19   20   21   22   ...   25

optional – boolean (по умолчанию true) – определяет, может ли значение поля или свойства быть null. Игнорируется для примитивных типов. Но если тип поля не примитивного типа, то при попытке сохранения сущности будет выброшено исключение.
2. fetch – FetchType (по умолчанию EAGER) – определяет, должен ли этот атрибут извлекаться незамедлительно (EAGER) или лениво (LAZY). Это необязательное требование
JPA, и провайдерам разрешено незамедлительно загружать данные, даже для которых установлена ленивая загрузка.
Без аннотации @Basic при получении сущности из БД по умолчанию ее поля базового типа загружаются принудительно (EAGER) и значения этих полей могут быть null.

Для чего нужна аннотация Column?
@Column сопоставляет поле класса столбцу таблицы, а ее атрибуты определяют поведение в этом столбце, используется для генерации схемы базы данных.
@Basic vs @Column:
1. Атрибуты @Basic применяются к сущностям JPA, тогда как атрибуты @Column применяются к столбцам базы данных.
2. @Basic имеет атрибут optional, который говорит о том, может ли поле объекта быть null
или нет; с другой стороны атрибут nullable аннотации @Column указывает, может ли соответствующий столбец в таблице быть null.
3. Можно использовать @Basic, чтобы указать, что поле должно быть загружено лениво.
4. Аннотация @Column позволяет указать имя столбца в таблице и ряд других свойств:

insertable/updatable – можно ли добавлять/изменять данные в колонке, по умолчанию true;

length – длина, для строковых типов данных, по умолчанию 255.
Коротко, в @Column задаем constraints, а в @Basic – FetchTypes.
Для чего нужна аннотация Access?
Определяет тип доступа к полям сущности. Для чтения и записи этих полей есть два подхода:
1. Field access (доступ по полям). При таком способе аннотации маппинга (Id, Column,...)
размещаются над полями, и Hibernate напрямую работает с полями сущности, читая и записывая их.
2. Property access (доступ по свойствам). При таком способе аннотации размещаются над методами-геттерами, но не над сеттерами.
По умолчанию тип доступа определяется местом, в котором находится аннотация @Id. Если она будет над полем – это будет AccessType.FIELD, если над геттером – это
AccessType.PROPERTY.
Чтобы явно определить тип доступа у сущности, нужно использовать аннотацию @Access,
которая может быть указана у сущности, Mapped Superclass и Embeddable class, а также над полями или методами.
Поля, унаследованные от суперкласса, имеют тип доступа этого суперкласса.
Если у одной сущности определены разные типы доступа, то нужно использовать аннотацию
@Transient для избежания дублирования маппинга.
Для чего нужна аннотация @Cacheable?
@Cacheable – необязательная аннотация JPA, используется для указания того, должна ли сущность храниться в кеше второго уровня.
В JPA говорится о пяти значениях shared-cache-mode из persistence.xml, который определяет как будет использоваться second-level cache: