Skip to content

Latest commit

 

History

History
1110 lines (774 loc) · 109 KB

Вопрос 2681-2729. Cобеседование по Java. Разбор вопросов и ответов.md

File metadata and controls

1110 lines (774 loc) · 109 KB

Cобеседование по Java. Разбор вопросов и ответов.

     

с 2681 вопрос по 2729 вопрос

Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.

Если вам интересно мое резюме: https://github.com/DEBAGanov

Собеседование по Java EE — Java Persistence API (JPA)

2681. Что такое JPA?

JPA (Java Persistence API) - это спецификация Java для управления постоянными объектами в реляционных базах данных. JPA предоставляет разработчикам удобный способ работать с базами данных, абстрагируясь от деталей реализации. Он позволяет сохранять, извлекать, обновлять и удалять объекты в базе данных, используя объектно-ориентированный подход.

JPA является частью Java EE (Enterprise Edition) и предоставляет стандартный способ работы с базами данных в Java-приложениях. Он определяет аннотации и интерфейсы, которые разработчики могут использовать для описания сущностей (Entity) и их отношений в базе данных. JPA также предоставляет API для выполнения операций с базой данных, таких как сохранение, извлечение и обновление данных.

JPA может использоваться с различными реализациями, такими как Hibernate, EclipseLink и другими. Hibernate является одной из самых популярных реализаций JPA и предоставляет дополнительные функции и возможности, такие как кэширование, ленивая загрузка и поддержка различных стратегий сопоставления объектов и таблиц.

Некоторые ключевые термины, связанные с JPA:

  • Entity (сущность): это класс Java, который представляет объект, который будет сохранен в базе данных. Класс сущности обычно аннотируется с помощью аннотации @Entity.
  • POJO (Plain Old Java Object): это обычный класс Java, который не зависит от какой-либо специфической платформы или фреймворка. В контексте JPA, классы сущностей являются POJO-классами.
  • ORM (Object-Relational Mapping): это технология, которая позволяет сопоставлять объекты в приложении с таблицами в базе данных. JPA предоставляет ORM-функциональность, позволяя разработчикам работать с объектами, а не с SQL-запросами.

2682. В чем её отличие JPA от Hibernate?

JPA (Java Persistence API) и Hibernate - это два различных, но связанных понятия в контексте работы с базами данных в Java.

JPA является стандартным интерфейсом программирования для работы с объектно-реляционным отображением (ORM) в Java. Он предоставляет API для управления объектами в базе данных, а также для выполнения операций чтения и записи данных. JPA определяет набор аннотаций и интерфейсов, которые разработчик может использовать для описания сущностей базы данных и их отношений.

Hibernate является одной из реализаций JPA. Он предоставляет конкретную реализацию JPA API и дополнительные функции для работы с базами данных. Hibernate выполняет маппинг объектов Java на таблицы базы данных и обеспечивает автоматическую генерацию SQL-запросов для выполнения операций с данными.

Таким образом, отличие между JPA и Hibernate заключается в следующем:

  • JPA является стандартным интерфейсом программирования для работы с ORM в Java.
  • Hibernate является одной из реализаций JPA и предоставляет конкретную реализацию JPA API и дополнительные функции для работы с базами данных.

2683. Можно ли использовать JPA c noSQl базами?

Да, можно использовать JPA с NoSQL базами данных. JPA (Java Persistence API) - это стандартный интерфейс для работы с объектно-реляционным отображением (ORM) в Java. Он предоставляет возможность взаимодействия с различными базами данных, включая SQL и NoSQL базы данных.

JPA обычно ассоциируется с ORM-фреймворками, такими как Hibernate, который предоставляет реализацию JPA. Hibernate позволяет использовать JPA для работы с NoSQL базами данных, такими как MongoDB и Apache Cassandra.

Однако, важно отметить, что поддержка NoSQL баз данных может различаться в зависимости от конкретной реализации JPA и ORM-фреймворка. Некоторые ORM-фреймворки, такие как Hibernate OGM, специально разработаны для работы с NoSQL базами данных.

Таким образом, JPA может быть использован с NoSQL базами данных, но необходимо учитывать особенности конкретной реализации JPA и ORM-фреймворка, а также поддержку NoSQL баз данных в выбранной реализации

2684. В чем её отличие JPA от JDO?

JPA (Java Persistence API) и JDO (Java Data Objects) - это два различных подхода к сохранению и извлечению данных в Java приложениях.

JPA является частью Java EE (Enterprise Edition) и предоставляет стандартный способ работы с реляционными базами данных в Java приложениях. JPA определяет API для управления объектно-реляционным отображением (ORM) и предоставляет возможность работать с базами данных, используя объектно-ориентированный подход. Одним из самых популярных реализаций JPA является Hibernate.

JDO также является стандартом для работы с объектно-ориентированными базами данных в Java приложениях. JDO предоставляет API для сохранения и извлечения объектов из базы данных, не завися от конкретной реализации базы данных или ORM. JDO поддерживает различные реализации, такие как DataNucleus и ObjectDB.

Вот основные отличия между JPA и JDO:

  • JPA является частью Java EE, в то время как JDO является отдельным стандартом.
  • JPA предоставляет стандартный способ работы с реляционными базами данных, в то время как JDO предоставляет более общий подход к работе с объектно-ориентированными базами данных.
  • JPA имеет широкую поддержку и популярность, особенно с использованием Hibernate, в то время как JDO имеет более ограниченную поддержку и использование.

2685. Что такое Entity?

Entity в контексте JPA (Java Persistence API) представляет собой класс, который отображается на таблицу в базе данных. Он представляет сущность, с которой мы работаем в приложении и которую мы хотим сохранить, обновить или удалить в базе данных.

Пример использования Entity в JPA:

@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    // Другие поля и методы
}

В приведенном выше примере Employee является Entity классом, который отображается на таблицу employees в базе данных. Он имеет аннотацию @Entity, которая указывает JPA, что этот класс является сущностью. Аннотация @Table указывает имя таблицы, на которую отображается этот класс.

Entity классы могут иметь поля, которые отображаются на столбцы таблицы, а также аннотации для определения отношений между сущностями, ограничений и других аспектов.

2686. Может ли Entity класс наследоваться от не Entity классов (non-entity classes)?

Да, в JPA классы сущностей (Entity) могут наследоваться от классов, которые не являются сущностями (non-entity classes) Это означает, что вы можете создавать иерархию классов, где классы сущностей наследуют свойства и методы от других классов, которые не являются сущностями.

Например, у вас может быть класс Person, который является сущностью и представляет информацию о человеке. Вы также можете создать класс Employee, который наследует класс Person и представляет информацию о сотруднике. Класс Employee будет также являться сущностью и будет иметь свои собственные атрибуты и методы, а также унаследованные от класса Person.

Вот пример кода на языке Java, демонстрирующий наследование класса сущности от класса, который не является сущностью:

@Entity
public class Person {
    // Атрибуты и методы класса Person
}

@Entity
public class Employee extends Person {
    // Дополнительные атрибуты и методы класса Employee
}

В этом примере класс Employee наследует атрибуты и методы класса Person, а также имеет свои собственные атрибуты и методы.

Таким образом, JPA позволяет создавать иерархию классов сущностей, где классы сущностей могут наследоваться от классов, которые не являются сущностями.

2687. Может ли Entity класс наследоваться от других Entity классов?

Да, в JPA классы сущностей (Entity) могут наследоваться от других классов сущностей или от обычных классов (non-entity classes). Это позволяет создавать иерархию классов и наследовать общие свойства и методы от родительских классов. Наследование в JPA осуществляется с помощью ключевого слова extends. Например, если у вас есть класс сущности Person, вы можете создать класс Employee, который наследует свойства и методы класса Person с помощью наследования в JPA:

@Entity
public class Person {
    // свойства и методы класса Person
}

@Entity
public class Employee extends Person {
    // свойства и методы класса Employee
}

Таким образом, класс Employee будет иметь все свойства и методы класса Person, а также свои собственные свойства и методы.

Важно отметить, что при наследовании классов сущностей в JPA существуют некоторые ограничения и правила, которые нужно учитывать. Например, классы сущностей должны иметь аннотацию @Entity, а также должны иметь уникальное имя в пределах персистентного контекста. Более подробную информацию о наследовании классов сущностей в JPA можно найти в документации Java Persistence API.

2688. Может ли не Entity класс наследоваться от Entity класса?

Да, в JPA не-Entity классы могут наследоваться от Entity классов. JPA позволяет использовать наследование для создания иерархии классов, где родительский класс является Entity, а дочерний класс наследует его свойства и атрибуты. Это позволяет создавать более гибкую структуру данных и управлять наследованием в контексте хранения данных в базе данных.

Пример:

@Entity
public class BaseEntity {
    @Id
    private Long id;
    // other properties and methods
}

@Entity
public class ChildEntity extends BaseEntity {
    // additional properties and methods specific to ChildEntity
}

В этом примере класс ChildEntity наследуется от класса BaseEntity, который является Entity классом. ChildEntity будет иметь все свойства и атрибуты BaseEntity, а также может добавлять свои собственные свойства и методы.

2689. Может ли Entity быть абстрактным классом?

Да, в JPA абстрактный класс может быть сущностью (entity). Абстрактная сущность отличается от конкретной сущности только тем, что она не может быть напрямую создана. Абстрактная сущность также может быть отображена как сущность и может быть целью запросов (которые будут работать с экземплярами ее конкретных подклассов).

Пример:

import javax.persistence.Entity;

@Entity
public abstract class AbstractEntity {
    // поля и методы абстрактной сущности
}

Важно отметить, что абстрактные сущности не могут быть напрямую сохранены в базе данных, но их конкретные подклассы могут быть сохранены и использованы в запросах.

2690. Какие требования JPA к Entity классам вы можете перечислить (не менее шести требований)?

JPA (Java Persistence API) устанавливает некоторые требования к классам сущностей. Вот несколько из них:

  • Класс сущности должен быть аннотирован аннотацией @Entity.
  • Класс сущности должен иметь публичный конструктор без аргументов.
  • Класс сущности должен иметь уникальный идентификатор, который может быть определен с помощью аннотации @Id.
  • Класс сущности должен иметь аннотацию @Table, если требуется настройка имени таблицы.
  • Класс сущности может иметь аннотацию @Column, чтобы настроить свойства столбцов.
  • Класс сущности может иметь аннотацию @GeneratedValue, чтобы настроить автоматическую генерацию значений первичного ключа.

Это лишь некоторые из требований JPA к классам сущностей. Существуют и другие требования, которые можно изучить в документации JPA.

Пример кода:

@Entity
@Table(name = "my_entity")
public class MyEntity {
    @Id
    @GeneratedValue
    private Long id;

    // Другие поля и методы класса
}

Обратите внимание: Это лишь пример кода, и требования JPA к классам сущностей могут быть более сложными и разнообразными в зависимости от конкретных требований вашего приложения и используемого поставщика JPA, такого как Hibernate

2691. Какие два типа элементов есть у Entity классов. Или другими словами перечислите два типа доступа (access) к элементам Entity классов.

Entity классы в JPA имеют два типа доступа к элементам:

Property Access (Доступ через свойства): При использовании этого типа доступа, элементы Entity класса доступны через геттеры и сеттеры свойств. Это означает, что для доступа к полям Entity класса используются методы доступа, а не непосредственно обращение к полям класса.

Field Access (Доступ через поля): При использовании этого типа доступа, элементы Entity класса доступны напрямую через поля класса, без использования геттеров и сеттеров. Это означает, что для доступа к полям Entity класса можно обращаться непосредственно к полям класса.

Таким образом, в JPA существуют два типа доступа к элементам Entity классов: Property Access (доступ через свойства) и Field Access (доступ через поля)

2692. Что такое атрибут Entity класса в терминологии JPA?

Атрибут Entity класса в терминологии JPA относится к Java Persistence API (JPA) и представляет собой свойство или поле класса, которое используется для доступа к постоянному состоянию сущности. Постоянное состояние сущности может быть доступно через методы доступа к свойствам JavaBeans (property access) или через переменные экземпляра (field access).

JPA предоставляет возможность выбора между использованием свойств или полей для доступа к постоянному состоянию класса или иерархии сущностей Этот выбор определяется с помощью аннотации @Access или другими средствами, описанными в разделе 2.3 спецификации JPA.

Например, если у вас есть класс с аннотацией @Entity, то атрибуты этого класса могут быть определены как свойства с помощью методов доступа к свойствам JavaBeans или как поля класса.

Пример использования свойств (property access): @Entity public class Person { private String name;

@Id
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

} Пример использования полей (field access): @Entity @Access(AccessType.FIELD) public class Person { @Id private Long id;

private String name;

// геттеры и сеттеры опущены для краткости

} В обоих примерах атрибуты id и name являются атрибутами сущности (Entity) и могут быть доступными для постоянного хранения и извлечения данных с помощью JPA.

2693. Какие типы данных допустимы в атрибутах Entity класса (полях или свойствах)?

PA (Java Persistence API) позволяет использовать различные типы данных в атрибутах Entity класса. Атрибуты могут быть определены как поля (fields) или свойства (properties).

Атрибуты класса могут быть примитивными типами данных, такими как целые числа (int, long), числа с плавающей точкой (float, double), логические значения (boolean), символы (char) и строки (String). Они также могут быть объектами других классов, включая пользовательские классы.

Кроме того, JPA поддерживает использование коллекций, таких как списки (List), множества (Set) и карты (Map), в атрибутах Entity класса. Это позволяет представлять связи между сущностями и обеспечивает возможность хранения и извлечения связанных данных.

Важно отметить, что типы данных, поддерживаемые JPA, зависят от используемого поставщика JPA (например, Hibernate). Различные поставщики могут предоставлять дополнительные типы данных или расширенные возможности для работы с типами данных.

Примеры типов данных, допустимых в атрибутах Entity класса:

  • Примитивные типы данных: int, long, float, double, boolean, char
  • Строки: String
  • Другие классы: пользовательские классы, классы из стандартной библиотеки Java
  • Коллекции: List, Set, Map

Примечание: Перечисленные типы данных являются лишь примерами и не исчерпывают все возможности JPA. Реальные типы данных, которые можно использовать в атрибутах Entity класса, зависят от конкретной реализации JPA и используемого поставщика

2694. Какие типы данных можно использовать в атрибутах, входящих в первичный ключ Entity класса (составной или простой), чтобы полученный первичный ключ мог использоваться для любой базы данных? А в случае автогенерируемого первичного ключа (generated primary keys)?

Для того чтобы полученный первичный ключ мог использоваться для любой базы данных, можно использовать различные типы данных в атрибутах, входящих в первичный ключ Entity класса.

  1. Простой первичный ключ:
  • Целочисленные типы данных, такие как INT, BIGINT, SMALLINT.
  • Символьные типы данных, такие как CHAR, VARCHAR.
  • Уникальные идентификаторы, такие как GUID (глобально уникальный идентификатор).
  • Другие типы данных, такие как DOUBLE, FLOAT.
  1. Составной первичный ключ:
  • Можно использовать комбинацию различных типов данных, таких как INT и VARCHAR.
  • Также можно использовать уникальные идентификаторы, такие как GUID.
  1. Автогенерируемый первичный ключ В случае автогенерируемого первичного ключа, тип данных может зависеть от конкретной базы данных, которую вы используете.

Некоторые базы данных предоставляют специальные типы данных для автогенерируемых первичных ключей, такие как:

  • В MS SQL Server используется тип данных IDENTITY.
  • В MySQL используются типы данных INT, DOUBLE, FLOAT.
  • В PostgreSQL можно использовать тип данных SERIAL.

Также можно использовать другие типы данных, такие как целочисленные типы данных, чтобы автоматически генерировать значения для первичного ключа.

Примеры Пример создания таблицы с простым первичным ключом в MySQL:

CREATE TABLE CUSTOMERS (
  ID INT NOT NULL,
  NAME VARCHAR(20) NOT NULL,
  AGE INT NOT NULL,
  ADDRESS CHAR(25),
  SALARY DECIMAL(18, 2),
  PRIMARY KEY (ID)
);

Пример создания таблицы с автогенерируемым первичным ключом в MS SQL Server:

CREATE TABLE TableName (
  id INT IDENTITY(1, 1),
  column1 VARCHAR(50),
  column2 MONEY,
  column3 NUMERIC(10, 2),
  CONSTRAINT PK_id PRIMARY KEY (id)
);

Примечание: При выборе типа данных для первичного ключа, рекомендуется учитывать требования и особенности конкретной базы данных, с которой вы работаете.

2695. Что такое встраиваемый (Embeddable) класс?

Встраиваемый (Embeddable) класс в JPA (Java Persistence API) представляет собой класс, который может быть встроен в другой класс в качестве его составной части. Он используется для моделирования сложных структур данных, когда необходимо объединить несколько полей в одно логическое целое.

Встраиваемый класс помечается аннотацией @Embeddable, а поле, содержащее этот класс, помечается аннотацией @Embedded. Это позволяет JPA автоматически сохранять и извлекать данные из встраиваемого класса вместе с основным классом.

Пример использования встраиваемого класса в JPA:

@Embeddable
public class Address {
    private String street;
    private String city;
    private String zipCode;
    // геттеры и сеттеры
}

@Entity
public class Employee {
    @Id
    private Long id;
    private String name;
    @Embedded
    private Address address;
    // геттеры и сеттеры
}

В приведенном примере класс Address является встраиваемым классом, который содержит поля street, city и zipCode. Класс Employee содержит поле address, которое является экземпляром класса Address и помечено аннотацией @Embedded.

Таким образом, встраиваемый класс позволяет объединить несколько полей в одну логическую единицу и использовать его в других классах для упрощения моделирования данных.

2696. Может ли встраиваемый (Embeddable) класс содержать другой встраиваемый (Embeddable) класс?

Да, встраиваемый (Embeddable) класс в JPA может содержать другой встраиваемый (Embeddable) класс. Встраиваемые классы позволяют вам создавать структурированные объекты данных, которые могут быть вложены в другие классы или сущности. Вы можете определить встраиваемые классы внутри других встраиваемых классов, чтобы создать иерархию встраиваемых объектов. Это позволяет вам создавать более сложные структуры данных, которые хранятся в одном поле или столбце базы данных.

2697. Может ли встраиваемый (Embeddable) класс содержать связи (relationship) с другими Entity или коллекциями Entity? Если может, то существуют ли какие-то ограничение на такие связи (relationship)?

Да, встраиваемый (Embeddable) класс в Java может содержать связи (relationship) с другими Entity или коллекциями Entity. Однако, существуют некоторые ограничения на такие связи. Например, встраиваемый класс не может содержать связь типа "ManyToOne" или "OneToMany". Также, встраиваемый класс не может быть корневым сущностным классом, то есть он должен быть вложенным в другой сущностный класс.

Пример:

@Embeddable
public class Address {
    private String street;
    private String city;
    private String state;
    private String country;

    // Конструкторы, геттеры и сеттеры
}

@Entity
public class Person {
    @Id
    private Long id;
    private String name;

    @Embedded
    private Address address;

    // Конструкторы, геттеры и сеттеры
}

В приведенном примере класс Address является встраиваемым классом, который содержит связи с классом Person. В классе Person используется аннотация @Embedded, чтобы указать, что поле address является встраиваемым классом.

Ограничения на связи (relationship) в встраиваемых классах:

Встраиваемый класс не может содержать связь типа "ManyToOne" или "OneToMany". Встраиваемый класс не может быть корневым сущностным классом и должен быть вложенным в другой сущностный класс.

2698. Какие требования JPA устанавливает к встраиваемым (Embeddable) классам?

JPA устанавливает следующие требования к встраиваемым (Embeddable) классам:

  • Встраиваемый класс может содержать отношение к сущности или коллекции сущностей.
  • Так как экземпляры встраиваемых классов сами по себе не имеют постоянной идентичности, отношение от ссылочной сущности указывает на сущность, которая содержит встраиваемый экземпляр(ы), а не на сам встраиваемый класс.
  • Встраиваемый класс, который используется в качестве встроенного идентификатора или в качестве ключа карты, не должен содержать такого отношения.

2699. Какие типы связей (relationship) между Entity вы знаете (перечислите восемь типов, либо укажите четыре типа связей, каждую из которых можно разделить ещё на два вида)?

В JPA (Java Persistence API) существует несколько типов связей между Entity. Вот четыре основных типа связей, каждый из которых можно разделить на два вида:

  • Однонаправленная связь "Один-к-Одному" (One-to-One):

Вид 1: Одна сущность связана с другой сущностью через атрибут-ссылку. Вид 2: Одна сущность связана с другой сущностью через атрибут-коллекцию.

  • Двунаправленная связь "Один-ко-Многим" (One-to-Many):

Вид 1: Одна сущность связана с несколькими сущностями через атрибут-коллекцию. Вид 2: Несколько сущностей связаны с одной сущностью через атрибут-ссылку.

  • Двунаправленная связь "Многие-ко-Многим" (Many-to-Many):

Вид 1: Несколько сущностей связаны с несколькими сущностями через атрибут-коллекцию. Вид 2: Несколько сущностей связаны с несколькими сущностями через атрибут-коллекцию с дополнительной сущностью-связью.

  • Связь "Вложенные коллекции" (Embedded Collections):

Вид 1: Одна сущность содержит вложенную коллекцию других сущностей. Вид 2: Одна сущность содержит вложенную коллекцию других сущностей с дополнительными атрибутами.

Примечание: В JPA также существуют другие типы связей, такие как "Многие-к-Одному" (Many-to-One) и "Один-ко-Одному с общей таблицей" (One-to-One with Shared Primary Key), но они не были упомянуты в данном списке.

2700. Что такое Mapped Superclass?

Mapped Superclass (отображаемый суперкласс) - это аннотация в Java Persistence API (JPA), которая позволяет создавать иерархию классов, где суперкласс содержит общую информацию о сопоставлении с базой данных, но сам не является сущностью.

Основная цель использования аннотации @MappedSuperclass состоит в том, чтобы избежать дублирования кода и сопоставления при работе с несколькими сущностями, которые имеют общие поля и отношения с базой данных.

Когда класс отмечен аннотацией @MappedSuperclass, его сопоставление применяется только к его подклассам, поскольку для самого суперкласса не существует таблицы в базе данных Таким образом, все подклассы наследуют сопоставление и состояние от суперкласса.

Преимущества использования @MappedSuperclass включают:

Избежание дублирования кода и сопоставления при работе с несколькими сущностями. Возможность определить общую информацию о сопоставлении с базой данных в одном месте. Поддержка наследования иерархии классов. Однако, есть некоторые ограничения при использовании @MappedSuperclass:

  • Суперкласс не может быть самостоятельно сущностью и не может быть целью постоянного отношения.
  • Суперкласс не может быть запрошен или передан в операции сущности или запроса.

Пример использования аннотации @MappedSuperclass:

@MappedSuperclass
public abstract class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    // Общие поля и методы
}

@Entity
public class Employee extends BaseEntity {
    // Дополнительные поля и методы для класса Employee
}

@Entity
public class Customer extends BaseEntity {
    // Дополнительные поля и методы для класса Customer
}

В этом примере класс BaseEntity отмечен аннотацией @MappedSuperclass и содержит общее поле id, которое будет унаследовано подклассами Employee и Customer. Классы Employee и Customer также могут иметь свои собственные дополнительные поля и методы.

2701. Какие три типа стратегии наследования мапинга (Inheritance Mapping Strategies) описаны в JPA?

В JPA описаны три типа стратегии наследования мапинга (Inheritance Mapping Strategies):

Одна таблица на иерархию (Single Table): В этой стратегии все классы наследники отображаются в одной таблице. Для различения типов объектов используется специальный столбец, который указывает на конкретный тип объекта. Эта стратегия обеспечивает простоту и производительность, но может привести к большому количеству NULL значений в таблице.

Таблица на класс (Table per Class): В этой стратегии каждый класс наследник отображается в отдельной таблице. Каждая таблица содержит только поля, специфичные для данного класса, а также поля, унаследованные от родительского класса. Эта стратегия обеспечивает более нормализованную структуру базы данных, но может привести к проблемам с производительностью при выполнении запросов, которые требуют объединения таблиц.

Таблица на конкретный класс (Table per Concrete Class): В этой стратегии каждый класс наследник отображается в отдельной таблице, включая все поля, унаследованные от родительского класса. Эта стратегия обеспечивает наиболее нормализованную структуру базы данных, но может привести к дублированию данных и сложностям при поддержке.

Это основные стратегии наследования мапинга в JPA. Каждая из них имеет свои преимущества и недостатки, и выбор конкретной стратегии зависит от требований и особенностей приложения

2702. Какие два типа fetch стратегии в JPA вы знаете?

В Java Persistence API (JPA) существуют две стратегии загрузки (fetch strategies): EAGER и LAZY.

EAGER (жадная) стратегия подразумевает, что связанные сущности будут загружены сразу же при загрузке основной сущности. Это означает, что все связанные сущности будут извлечены из базы данных и загружены в память вместе с основной сущностью. Использование EAGER загрузки может привести к избыточной загрузке данных, особенно если связанные сущности содержат большое количество данных или если связь имеет глубокую иерархию.

LAZY (ленивая) стратегия подразумевает, что связанные сущности будут загружены только при первом доступе к ним. Это означает, что связанные сущности не будут извлечены из базы данных и загружены в память, пока не будет выполнен доступ к ним. Использование LAZY загрузки позволяет уменьшить количество загружаемых данных и повысить производительность при работе с большими объемами данных.

Выбор между EAGER и LAZY стратегиями загрузки зависит от конкретных требований приложения и особенностей работы сущностей. Если необходимо всегда загружать связанные сущности вместе с основной сущностью, то можно использовать EAGER загрузку. Если же требуется отложенная загрузка связанных сущностей для оптимизации производительности или уменьшения объема загружаемых данных, то следует использовать LAZY загрузку.

Например, в JPA можно указать стратегию загрузки для связи OneToMany следующим образом:

@OneToMany(fetch = FetchType.LAZY)

В данном примере используется LAZY загрузка, что означает, что связанные сущности будут загружены только при первом доступе к ним.

Обратите внимание, что выбор стратегии загрузки зависит от конкретной ситуации и требований приложения. Необходимо тщательно оценить производительность и объем загружаемых данных при выборе стратегии загрузки в JPA.

2703. Что такое EntityManager и какие основные его функции вы можете перечислить?

EntityManager - это интерфейс в Java Persistence API (JPA), который предоставляет методы для управления жизненным циклом сущностей в базе данных. Он является основным инструментом для работы с JPA и предоставляет функции для выполнения операций CRUD (создание, чтение, обновление, удаление) с сущностями.

Основные функции EntityManager включают:

Создание и удаление сущностей: EntityManager предоставляет методы для создания новых сущностей и удаления существующих. Например, метод persist(entity) используется для создания новой сущности, а метод remove(entity) - для удаления существующей.

  • Обновление сущностей: EntityManager позволяет обновлять существующие сущности в базе данных. Изменения, внесенные в сущность, могут быть автоматически синхронизированы с базой данных при вызове метода merge(entity).
  • Поиск сущностей: EntityManager предоставляет методы для выполнения запросов к базе данных и поиска сущностей. Например, метод find(entityClass, primaryKey) используется для поиска сущности по ее первичному ключу.
  • Управление транзакциями: EntityManager позволяет управлять транзакциями при выполнении операций с базой данных. Он предоставляет методы для начала, фиксации и отката транзакции.
  • Кэширование: EntityManager поддерживает кэширование сущностей и запросов для улучшения производительности. Он предоставляет методы для управления кэшем сущностей и запросов.
  • Отслеживание изменений: EntityManager отслеживает изменения, внесенные в сущности, и автоматически синхронизирует их с базой данных при фиксации транзакции. Это позволяет обновлять базу данных только при необходимости и уменьшает количество запросов к базе данных.

EntityManager является важной частью JPA и предоставляет удобный способ работы с базой данных в Java-приложениях. Он абстрагирует различные детали взаимодействия с базой данных и предоставляет удобный API для работы с сущностями и выполнения операций с базой данных

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

Entity объекты имеют четыре основных статуса в своем жизненном цикле. Вот они:

  • Transient (Переходный): В этом статусе Entity объект только что был создан и еще не связан с каким-либо постоянным хранилищем данных. Он не имеет идентификатора и не отображается в базе данных.
  • Persistent (Постоянный): Когда Entity объект сохраняется в базе данных, он переходит в статус постоянного объекта. В этом статусе объект имеет идентификатор и отображается в базе данных.
  • Detached (Отсоединенный): Если Entity объект был отсоединен от постоянного хранилища данных, например, после закрытия сессии или завершения транзакции, он переходит в статус отсоединенного объекта. В этом статусе объект не отслеживается фреймворком и не синхронизируется с базой данных.
  • Removed (Удаленный): Когда Entity объект явно помечается для удаления из базы данных, он переходит в статус удаленного объекта. В этом статусе объект будет удален из базы данных при следующей синхронизации с базой данных.

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

Операция persist влияет на объекты сущностей каждого из четырех статусов следующим образом:

  • Transient (новый) статус: Если объект сущности находится в состоянии transient (новый), то операция persist приведет к переходу объекта в состояние managed (управляемый). Объект будет сохранен в базе данных при следующей транзакции.
  • Managed (управляемый) статус: Если объект сущности находится в состоянии managed (управляемый), то операция persist не будет иметь никакого эффекта. Объект уже находится в управляемом состоянии и будет сохранен в базе данных при следующей транзакции.
  • Detached (отсоединенный) статус: Если объект сущности находится в состоянии detached (отсоединенный), то операция persist приведет к переходу объекта в состояние managed (управляемый). Объект будет снова связан с контекстом персистентности и сохранен в базе данных при следующей транзакции.
  • Removed (удаленный) статус: Если объект сущности находится в состоянии removed (удаленный), то операция persist не будет иметь никакого эффекта. Объект уже помечен для удаления и будет удален из базы данных при следующей транзакции.

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

Операция remove влияет на объекты сущностей каждого из четырех статусов следующим образом:

  • Новый (New): Если объект сущности находится в статусе "New" и вызывается операция remove, то объект будет удален из контекста персистентности и базы данных. После удаления, объект сущности будет переведен в состояние "Detached" (отсоединенный).
  • Управляемый (Managed): Если объект сущности находится в статусе "Managed" и вызывается операция remove, то объект будет удален из контекста персистентности и базы данных. После удаления, объект сущности будет переведен в состояние "Removed" (удаленный).
  • Удаленный (Removed): Если объект сущности находится в статусе "Removed" и вызывается операция remove, то операция будет проигнорирована, так как объект уже был помечен для удаления.
  • Отсоединенный (Detached): Если объект сущности находится в статусе "Detached" и вызывается операция remove, то операция будет проигнорирована, так как объект не находится в контексте персистентности.

Источник содержит информацию о жизненном цикле сущностей в Java Persistence API (JPA), включая операцию remove.

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

Операция merge в JPA влияет на объекты Entity в каждом из четырех статусов следующим образом:

Управляемые (managed) объекты Entity: Если объект Entity находится в управляемом состоянии, операция merge не оказывает никакого влияния на этот объект.

Удаленные (removed) объекты Entity: Если объект Entity находится в удаленном состоянии, операция merge пытается восстановить его в управляемое состояние. Если в базе данных существует запись с тем же идентификатором, что и удаляемый объект, то эта запись будет обновлена значениями из удаленного объекта. Если же такой записи нет, то будет создан новый объект.

Новые (new) объекты Entity: Если объект Entity находится в новом состоянии, операция merge пытается сохранить его в базу данных. Если в базе данных уже существует запись с тем же идентификатором, что и новый объект, то эта запись будет обновлена значениями из нового объекта. Если же такой записи нет, то будет создан новый объект.

Отсоединенные (detached) объекты Entity: Если объект Entity находится в отсоединенном состоянии, операция merge пытается восстановить его в управляемое состояние. Если в базе данных существует запись с тем же идентификатором, что и отсоединенный объект, то эта запись будет обновлена значениями из отсоединенного объекта. Если же такой записи нет, то будет создан новый объект.

Примечание: Операция merge не изменяет сам объект Entity, а создает новый объект или обновляет существующий в базе данных.

Пример использования операции merge в JPA:

EntityManager entityManager = // инициализация EntityManager
Entity entity = // создание или получение объекта Entity

// Выполняем операцию merge
Entity mergedEntity = entityManager.merge(entity);

// Обновленный или созданный объект Entity доступен в mergedEntity

Важно: При использовании операции merge в JPA, необходимо быть внимательным и учитывать особенности каждого объекта Entity и его состояния .

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

Операция refresh в JPA влияет на объекты сущностей в каждом из четырех статусов следующим образом:

  • Управляемые (managed) сущности: Если сущность находится в управляемом состоянии, то операция refresh обновляет состояние сущности из базы данных, перезаписывая все изменения, сделанные в сущности Если у сущности есть связи с другими сущностями и эти связи помечены аннотацией cascade=REFRESH или cascade=ALL, то операция refresh также будет распространяться на связанные сущности.
  • Новые (new) сущности: Если сущность является новой (new), отсоединенной (detached) или удаленной (removed), то при вызове операции refresh будет выброшено исключение IllegalArgumentException.
  • Отсоединенные (detached) сущности: Операция refresh не влияет на отсоединенные сущности.
  • Удаленные (removed) сущности: Операция refresh не влияет на удаленные сущности.

Таким образом, операция refresh в JPA позволяет обновить состояние управляемой сущности из базы данных, но не влияет на новые, отсоединенные или удаленные сущности.

Пример использования операции refresh в JPA:

// Получение EntityManager
EntityManager entityManager = entityManagerFactory.createEntityManager();

// Начало транзакции
entityManager.getTransaction().begin();

// Получение сущности из базы данных
MyEntity entity = entityManager.find(MyEntity.class, id);

// Изменение состояния сущности
entity.setName("Новое имя");

// Вызов операции refresh для обновления состояния из базы данных
entityManager.refresh(entity);

// Состояние сущности будет перезаписано значениями из базы данных
System.out.println(entity.getName()); // Выведет исходное имя сущности

// Фиксация изменений
entityManager.getTransaction().commit();

// Закрытие EntityManager
entityManager.close();

Обратите внимание: Операция refresh может быть полезна, когда необходимо обновить состояние сущности из базы данных, отменить все изменения, сделанные в сущности, и получить актуальные значения полей из базы данных.

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

Операция detach влияет на объекты сущностей в каждом из четырех статусов следующим образом:

  • Управляемые (managed) объекты сущностей: При вызове операции detach на управляемом объекте сущности, он переходит в состояние "отсоединенный" (detached). Это означает, что объект больше не находится под управлением менеджера сущностей и не отслеживается для автоматического обновления в базе данных. Изменения, внесенные в отсоединенный объект, не будут автоматически синхронизироваться с базой данных при вызове метода flush или commit менеджера сущностей.
  • Новые (new) объекты сущностей: Операция detach не имеет эффекта на новые объекты сущностей, так как они еще не были присоединены к менеджеру сущностей. Они остаются в состоянии "новый" (new) и могут быть присоединены или сохранены в базе данных путем вызова метода persist или merge менеджера сущностей.
  • Удаленные (removed) объекты сущностей: Операция detach не влияет на удаленные объекты сущностей. Удаленные объекты остаются в состоянии "удаленный" (removed) и будут удалены из базы данных при вызове метода flush или commit менеджера сущностей.
  • Отсоединенные (detached) объекты сущностей: Если операция detach вызывается на уже отсоединенном объекте сущности, то она не имеет эффекта на этот объект. Он остается в состоянии "отсоединенный" (detached) и может быть снова присоединен к менеджеру сущностей путем вызова метода merge или reattach менеджера сущностей.

2710. Для чего нужна аннотация Basic?

Аннотация @Basic в Java используется в контексте Java Persistence API (JPA) для указания, что поле или свойство сущности должно быть сохранено в базе данных. Она является одной из базовых аннотаций JPA и может применяться к полям или методам доступа (геттерам и сеттерам) сущности.

Применение аннотации @Basic гарантирует, что значение поля или свойства будет сохранено в базе данных без каких-либо дополнительных настроек. Она может использоваться вместе с другими аннотациями JPA, такими как @Column, @Transient, @Enumerated и другими, для более точной настройки сохранения данных.

Например, аннотация @Basic может быть применена к полю или методу доступа сущности следующим образом:

@Entity
public class Employee {
    @Id
    private Long id;

    @Basic
    private String name;

    // Геттеры и сеттеры
}

В этом примере поле name будет сохранено в базе данных без дополнительных настроек, так как оно помечено аннотацией @Basic.

2711. Для чего нужна аннотация Access?

Аннотация Access в JPA используется для указания типа доступа к полям или свойствам сущности. В JPA существуют два типа доступа: полевой (FIELD) и свойственный (PROPERTY).

  • Полевой доступ (FIELD) означает, что JPA будет получать и устанавливать значения напрямую через поля класса сущности. Для этого необходимо пометить поля аннотацией @Access(AccessType.FIELD).
  • Свойственный доступ (PROPERTY) означает, что JPA будет использовать геттеры и сеттеры для доступа к значениям свойств класса сущности. Для этого необходимо пометить геттеры и сеттеры аннотацией @Access(AccessType.PROPERTY).

Выбор между полевым и свойственным доступом зависит от предпочтений разработчика и особенностей конкретной сущности. Некоторые разработчики предпочитают использовать полевой доступ для простых сущностей, а свойственный доступ для более сложных сущностей с логикой в геттерах и сеттерах.

Например, для указания полевого доступа к полям сущности можно использовать аннотацию @Access(AccessType.FIELD) перед объявлением класса сущности

@Access(AccessType.FIELD)
@Entity
public class Person {
    @Id
    private Long id;
    private String name;
    // остальные поля
}

А для указания свойственного доступа к свойствам сущности можно использовать аннотацию @Access(AccessType.PROPERTY) перед объявлением класса сущности

@Access(AccessType.PROPERTY)
@Entity
public class Person {
    @Id
    private Long id;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // остальные свойства
}

Важно отметить, что использование аннотации Access не является обязательным в JPA. Если аннотация Access не указана, то будет использоваться тип доступа по умолчанию, который зависит от провайдера JPA.

2712. Какими аннотациями можно перекрыть связи (override entity relationship) или атрибуты, унаследованные от суперкласса, или заданные в embeddable классе при использовании этого embeddable класса в одном из entity классов и не перекрывать в остальных?

При использовании JPA (Java Persistence API) в Java, есть несколько аннотаций, которые можно использовать для перекрытия связей или атрибутов, унаследованных от суперкласса или заданных в embeddable классе. Вот некоторые из них:

  • @AttributeOverride: Эта аннотация позволяет перекрыть атрибут, унаследованный от суперкласса, в классе-наследнике. Вы можете указать новое имя атрибута и его свойства в аннотации. Пример использования:
@Entity
@AttributeOverride(name = "propertyName", column = @Column(name = "newColumnName"))
public class Subclass extends Superclass {
    // ...
}
  • @AssociationOverride: Эта аннотация позволяет перекрыть связь, унаследованную от суперкласса, в классе-наследнике. Вы можете указать новое имя связи и ее свойства в аннотации. Пример использования:
@Entity
@AssociationOverride(name = "propertyName", joinColumns = @JoinColumn(name = "newColumnName"))
public class Subclass extends Superclass {
    // ...
}
  • @Embedded: Эта аннотация указывает, что класс должен быть встроенным (embeddable) и может быть использован в других entity классах. При использовании этой аннотации, атрибуты встроенного класса будут унаследованы в entity классе. Пример использования:
@Entity
public class EntityClass {
    @Embedded
    private EmbeddableClass embeddable;
    // ...
}
  • @AttributeOverrides и @AssociationOverrides: Эти аннотации позволяют перекрыть несколько атрибутов или связей, унаследованных от суперкласса или заданных в embeddable классе. Вы можете указать новые имена и свойства для каждого атрибута или связи в аннотации. Пример использования:
@Entity
@AttributeOverrides({
    @AttributeOverride(name = "propertyName1", column = @Column(name = "newColumnName1")),
    @AttributeOverride(name = "propertyName2", column = @Column(name = "newColumnName2"))
})
public class Subclass extends Superclass {
    // ...
}

Это лишь некоторые из аннотаций, которые можно использовать для перекрытия связей или атрибутов в JPA. Вы можете выбрать подходящую аннотацию в зависимости от вашего конкретного случая использования.

2713. Какой аннотацией можно управлять кешированием JPA для данного Entity?

Кеширование JPA для данного Entity можно управлять с помощью аннотации @Cacheable. Аннотация @Cacheable позволяет указать, что данные данного Entity могут быть закешированы. Это позволяет улучшить производительность при повторном доступе к данным, так как запросы к базе данных могут быть избежаны, если данные уже находятся в кеше.

Пример использования аннотации @Cacheable:

@Entity
@Cacheable(true) // указываем, что данные данного Entity могут быть закешированы
public class MyEntity {
    // поля и методы сущности
}

Примечание: Аннотация @Cacheable управляет кешированием на уровне Entity. Для более точной настройки кеширования, также можно использовать другие аннотации, такие как @CachePut и @CacheEvict, которые позволяют добавлять и удалять данные из кеша.

2714. Какие аннотации служит для задания класса преобразования basic атрибута Entity в другой тип при сохранении/получении данных их базы (например, работать с атрибутом Entity boolean типа, но в базу сохранять его как число)?

Аннотация, которая служит для задания класса преобразования basic атрибута Entity в другой тип при сохранении/получении данных из базы данных в JPA, - @Convert. С помощью этой аннотации можно указать конвертер, который будет использоваться для преобразования значения атрибута при сохранении и получении данных из базы.

Пример использования аннотации @Convert:

@Entity
public class MyEntity {
    @Convert(converter = BooleanToIntegerConverter.class)
    private boolean myBoolean;

    // остальные атрибуты и методы сущности
}

В этом примере, атрибут myBoolean будет преобразовываться в целое число при сохранении и получении данных из базы. Для этого будет использоваться конвертер BooleanToIntegerConverter, который должен быть реализован отдельно.

@Converter
public class BooleanToIntegerConverter implements AttributeConverter<Boolean, Integer> {
    @Override
    public Integer convertToDatabaseColumn(Boolean attribute) {
        return attribute ? 1 : 0;
    }

    @Override
    public Boolean convertToEntityAttribute(Integer dbData) {
        return dbData == 1;
    }
}

В данном примере, конвертер BooleanToIntegerConverter преобразует значение типа Boolean в целое число при сохранении в базу данных и обратно при получении данных из базы.

Примечание: Обратите внимание, что аннотация @Convert может быть применена к любому basic атрибуту Entity, который может быть преобразован в другой тип данных.

2715. Какой аннотацией можно задать класс, методы которого должен выполнится при определенных JPA операциях над данным Entity или Mapped Superclass (такие как удаление, изменение данных и т.п.)?

Вы можете использовать аннотацию @EntityListeners для задания класса, методы которого должны выполниться при определенных JPA операциях над данным Entity или Mapped Superclass, таких как удаление или изменение данных. Аннотация @EntityListeners позволяет указать класс или классы слушателей, которые будут обрабатывать события жизненного цикла сущности.

Пример использования аннотации @EntityListeners:

@Entity
@EntityListeners(MyEntityListener.class)
public class MyEntity {
    // поля и методы сущности
}

public class MyEntityListener {
    @PrePersist
    public void prePersist(Object entity) {
        // код, который должен выполниться перед сохранением сущности
    }

    @PostRemove
    public void postRemove(Object entity) {
        // код, который должен выполниться после удаления сущности
    }

    // другие методы обработки событий жизненного цикла сущности
}

В приведенном примере класс MyEntity помечен аннотацией @EntityListeners(MyEntityListener.class), что означает, что методы класса MyEntityListener будут вызываться при определенных событиях жизненного цикла сущности MyEntity, таких как @PrePersist перед сохранением и @PostRemove после удаления.

2716. Для чего нужны callback методы в JPA? К каким сущностям применяются аннотации callback методов? Перечислите семь callback методов (или что тоже самое аннотаций callback методов)

Callback методы в JPA используются для выполнения определенных действий при возникновении определенных событий в жизненном цикле сущностей. Они позволяют разработчикам встраивать свою логику в различные этапы обработки сущностей.

Аннотации callback методов применяются к сущностям в JPA для указания, какие методы должны быть вызваны при определенных событиях. Например, при создании, обновлении или удалении сущности.

Вот семь callback методов (или аннотаций callback методов) в JPA:

  • @PrePersist: вызывается перед сохранением новой сущности в базу данных.
  • @PostPersist: вызывается после сохранения новой сущности в базу данных.
  • @PreUpdate: вызывается перед обновлением существующей сущности в базе данных.
  • @PostUpdate: вызывается после обновления существующей сущности в базе данных.
  • @PreRemove: вызывается перед удалением существующей сущности из базы данных.
  • @PostRemove: вызывается после удаления существующей сущности из базы данных.
  • @PostLoad: вызывается после загрузки существующей сущности из базы данных.

Эти callback методы позволяют разработчикам выполнять дополнительные действия, такие как валидация данных, обновление связанных сущностей или выполнение других операций, связанных с жизненным циклом сущностей.

2717. Какие аннотации служат для установки порядка выдачи элементов коллекций Entity?

Для установки порядка выдачи элементов коллекций Entity в JPA можно использовать аннотацию @OrderBy. Эта аннотация позволяет указать поле или свойство, по которому следует упорядочить элементы коллекции при их извлечении из базы данных.

Пример использования аннотации @OrderBy:

@Entity
public class MyEntity {
    // ...

    @OneToMany
    @OrderBy("fieldName ASC") // Упорядочить элементы коллекции по возрастанию значения поля fieldName
    private List<ChildEntity> children;

    // ...
}

В данном примере, элементы коллекции children будут упорядочены по возрастанию значения поля fieldName.

Обратите внимание, что порядок выдачи элементов коллекции может зависеть от используемой базы данных и драйвера JPA. Подробности можно найти в документации конкретной реализации JPA, такой как Hibernate.

2718. Какой аннотацей можно исключить поля и свойства Entity из маппинга (property or field is not persistent)?

Аннотацией, которая позволяет исключить поля и свойства Entity из маппинга (то есть сделать их непостоянными), является @Transient

Пример использования аннотации @Transient в JPA:

@Entity
public class MyEntity {
    @Id
    private Long id;

    private String persistentField;

    @Transient
    private String transientField;

    // Геттеры и сеттеры
}

В приведенном примере, поле persistentField будет включено в маппинг и сохранено в базе данных, в то время как поле transientField будет исключено из маппинга и не будет сохранено в базе данных.

2719. Какие два вида кэшей (cache) вы знаете в JPA и для чего они нужны?

JPA (Java Persistence API) поддерживает два вида кэшей: кэш первого уровня (level 1 cache) и кэш второго уровня (level 2 cache).

Кэш первого уровня (level 1 cache) - это кэш, который находится внутри EntityManager'а и привязан к конкретной сессии. Он используется для хранения сущностей, которые были загружены или изменены в рамках текущей сессии. Кэш первого уровня автоматически обновляется при выполнении операций чтения и записи с использованием EntityManager'а. Он позволяет избежать повторных запросов к базе данных при обращении к уже загруженным сущностям в рамках текущей сессии.

Кэш второго уровня (level 2 cache) - это общий кэш, который может использоваться между различными сессиями и EntityManager'ами. Он предоставляет механизм кэширования сущностей и запросов на уровне приложения. Кэш второго уровня позволяет снизить количество запросов к базе данных и улучшить производительность приложения. Он может быть настроен для хранения сущностей, запросов и других данных, которые могут быть повторно использованы в разных сессиях.

Кэширование в JPA полезно для улучшения производительности приложения, особенно при работе с часто используемыми сущностями или запросами.

2720. Какие есть варианты настройки second-level cache (кэша второго уровня) в JPA или что аналогично опишите какие значения может принимать элемент shared-cache-mode из persistence.xml?

JPA есть несколько вариантов настройки кэша второго уровня. Один из способов - использование элемента shared-cache-mode в файле persistence.xml. Этот элемент определяет режим использования кэша второго уровня для всех сущностей в приложении. Вот некоторые значения, которые может принимать shared-cache-mode:

  • ALL: Все сущности в приложении будут кэшироваться в кэше второго уровня.
  • NONE: Ни одна сущность не будет кэшироваться в кэше второго уровня.
  • ENABLE_SELECTIVE: Только сущности, помеченные аннотацией @Cacheable(true), будут кэшироваться в кэше второго уровня.
  • DISABLE_SELECTIVE: Только сущности, помеченные аннотацией @Cacheable(false), не будут кэшироваться в кэше второго уровня.

2721. Как можно изменить настройки fetch стратегии любых атрибутов Entity для отдельных запросов (query) или методов поиска (find), то если у Entity есть атрибут с fetchType = LAZY, но для конкретного запроса его требуется сделать EAGER или наоборот?

Вы можете изменить настройки стратегии загрузки (fetch strategy) для отдельных запросов или методов поиска в JPA. Если у атрибута сущности установлен fetchType = LAZY, но для конкретного запроса вам нужно сделать его EAGER или наоборот, вы можете использовать аннотацию @EntityGraph или явно указать fetch strategy в запросе.

Использование аннотации @EntityGraph: Вы можете использовать аннотацию @EntityGraph для указания желаемой стратегии загрузки для конкретного запроса. Ниже приведен пример:

@Entity
public class Entity {
    // ...
    @OneToMany(fetch = FetchType.LAZY)
    private List<RelatedEntity> relatedEntities;
    // ...
}

@Repository
public interface EntityRepository extends JpaRepository<Entity, Long> {
    @EntityGraph(attributePaths = "relatedEntities")
    Entity findById(Long id);
}

В этом примере, при вызове метода findById в репозитории EntityRepository, атрибут relatedEntities будет загружен EAGER, несмотря на то, что его стратегия загрузки по умолчанию установлена как LAZY.

Явное указание стратегии загрузки в запросе: Вы также можете явно указать стратегию загрузки в запросе с помощью ключевого слова FETCH. Ниже приведен пример:

@Repository
public interface EntityRepository extends JpaRepository<Entity, Long> {
    @Query("SELECT e FROM Entity e LEFT JOIN FETCH e.relatedEntities WHERE e.id = :id")
    Entity findByIdWithRelatedEntities(@Param("id") Long id);
}

В этом примере, при вызове метода findByIdWithRelatedEntities в репозитории EntityRepository, атрибут relatedEntities будет загружен EAGER, несмотря на то, что его стратегия загрузки по умолчанию установлена как LAZY.

Обратите внимание, что изменение стратегии загрузки может повлиять на производительность вашего приложения, поэтому рекомендуется использовать EAGER загрузку только в случаях, когда это действительно необходимо.

2722. Каким способом можно в коде работать с кэшем второго уровня (удалять все или определенные Entity из кеша, узнать закэшировался ли данное Entity и т.п.)?

В JPA (Java Persistence API) существует возможность работать с кэшем второго уровня. Кэш второго уровня представляет собой механизм кэширования данных на уровне EntityManagerFactory, что позволяет улучшить производительность при работе с базой данных.

Для работы с кэшем второго уровня в JPA можно использовать следующие методы:

  • Удаление всех Entity из кэша: Для удаления всех Entity из кэша второго уровня можно использовать метод getCache() у объекта EntityManagerFactory Пример использования:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("yourPersistenceUnit");
emf.getCache().evictAll();
  • Удаление определенного Entity из кэша: Для удаления определенного Entity из кэша второго уровня можно использовать метод evict() у объекта EntityManagerFactory Пример использования:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("yourPersistenceUnit");
emf.getCache().evict(YourEntity.class);
  • Проверка, закэшировано ли определенное Entity: Для проверки, закэшировано ли определенное Entity, можно использовать метод contains() у объекта EntityManagerFactory Пример использования:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("yourPersistenceUnit");
boolean isCached = emf.getCache().contains(YourEntity.class, entityId);

Обратите внимание, что поддержка кэша второго уровня может различаться в различных реализациях JPA, таких как Hibernate. Пожалуйста, обратитесь к документации конкретной реализации для получения более подробной информации.

2723. Каким способом можно получить метаданные JPA (сведения о Entity типах, Embeddable и Managed классах и т.п.)?

ы можете получить метаданные JPA, такие как информацию о типах сущностей (Entity), встраиваемых классах (Embeddable) и управляемых классах (Managed), с использованием JPA Metamodel API Этот API предоставляет набор интерфейсов для динамического доступа к метамодели, соответствующей управляемым классам в единице сохранения (persistence unit).

Пример кода:

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.Metamodel;

public class JpaMetadataExample {
    public static void main(String[] args) {
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("yourPersistenceUnitName");
        Metamodel metamodel = entityManagerFactory.getMetamodel();

        for (EntityType<?> entityType : metamodel.getEntities()) {
            System.out.println("Entity Name: " + entityType.getName());
            // Дополнительная обработка метаданных сущности
        }

        entityManagerFactory.close();
    }
}

В приведенном выше примере мы создаем EntityManagerFactory и получаем Metamodel с помощью метода getMetamodel(). Затем мы можем использовать методы getEntities() и getName() для получения информации о каждой сущности в метамодели.

Обратите внимание, что в примере выше вам нужно заменить "yourPersistenceUnitName" на имя вашей единицы сохранения (persistence unit).

2724. Что такое JPQL (Java Persistence query language) и чем он отличается от SQL?

JPQL (Java Persistence Query Language) - это язык запросов, используемый в Java Persistence API (JPA) для выполнения операций с базой данных на основе объектной модели. JPQL является независимым от платформы языком запросов, который определен в спецификации JPA и используется для выполнения запросов к сущностям, хранящимся в реляционной базе данных [[1[1].

Основное отличие JPQL от SQL заключается в том, что JPQL оперирует объектами сущностей JPA, а не непосредственно с таблицами базы данных. Синтаксис запросов JPQL напоминает синтаксис SQL, но вместо таблиц и столбцов используются имена сущностей и их атрибуты. JPQL поддерживает различные операции, такие как SELECT, UPDATE и DELETE, а также агрегатные функции, сортировку и группировку.

Вот примеры некоторых JPQL-запросов:

SELECT: SELECT e FROM Employee e WHERE e.salary > 50000
UPDATE: UPDATE Employee e SET e.salary = e.salary * 1.1 WHERE e.department = 'IT'
DELETE: DELETE FROM Employee e WHERE e.department = 'HR'

JPQL также поддерживает операции соединения, обновления и удаления данных в пакетном режиме, а также возможность объявления запросов статически в метаданных или динамически в коде.

Использование JPQL позволяет разработчикам работать с базой данных, используя объектную модель и избегать прямой работы с SQL-запросами. Это делает код более читаемым, поддерживаемым и позволяет использовать преимущества JPA, такие как кэширование и управление транзакциями.

Важно отметить, что JPQL является частью спецификации JPA и является независимым от платформы языком запросов, в то время как SQL является языком запросов, специфичным для конкретной базы данных.

2725. Что означает полиморфизм (polymorphism) в запросах JPQL (Java Persistence query language) и как его «выключить»?

Полиморфизм (polymorphism) в запросах JPQL (Java Persistence query language) означает возможность использования различных типов сущностей в одном запросе. Это позволяет обращаться к сущностям разных классов, которые наследуются от одного базового класса или интерфейса, с помощью общего типа. Таким образом, можно выполнять запросы, которые включают несколько типов сущностей и получать результаты, соответствующие каждому из них.

Чтобы "выключить" полиморфизм в запросах JPQL, можно использовать оператор TYPE. Он позволяет ограничить полиморфизм запроса и получить точный тип аргумента. Например, вы можете использовать оператор TYPE для выбора только сущностей определенного типа или для исключения определенного типа из результата запроса.

Пример использования оператора TYPE в JPQL:

SELECT e FROM Entity e WHERE TYPE(e) = com.example.Cat

В этом примере выбираются только сущности типа Cat.

Таким образом, оператор TYPE позволяет контролировать полиморфизм в запросах JPQL и выбирать только сущности определенного типа.

2726. Что такое Criteria API и для чего он используется?

Criteria API - это часть Java Persistence API (JPA), которая предоставляет программистам возможность создавать динамические запросы к базе данных с использованием объектно-ориентированного подхода вместо написания SQL-запросов вручную Он используется для создания запросов и определения критериев поиска в JPA.

Criteria API позволяет строить запросы с помощью объектов, таких как CriteriaBuilder, CriteriaQuery и Root, вместо использования строкового подхода, который используется в Java Persistence Query Language (JPQL) Он предоставляет более типобезопасный и удобный способ создания запросов, а также обеспечивает возможность компиляции и проверки запросов на этапе компиляции.

С помощью Criteria API вы можете создавать запросы, определять условия фильтрации, сортировки и объединения таблиц, а также выполнять другие операции с базой данных Он предоставляет более гибкий и мощный способ создания запросов, чем простые SQL-запросы или JPQL.

Основные преимущества Criteria API:

  • Типобезопасность: Criteria API позволяет использовать типы данных Java для определения критериев поиска, что обеспечивает более безопасное выполнение запросов.
  • Объектно-ориентированный подход: Criteria API позволяет строить запросы с использованием объектов, что делает код более понятным и легко поддерживаемым.
  • Компиляция и проверка на этапе компиляции: Criteria API позволяет компилировать и проверять запросы на этапе компиляции, что помогает обнаружить ошибки в запросах до их выполнения.
  • Использование Criteria API может быть особенно полезным в ситуациях, когда требуется генерировать запросы динамически, в зависимости от условий или параметров Он также может быть полезен при работе с сложными запросами, включающими объединение таблиц, фильтрацию и сортировку.

Пример использования Criteria API:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> query = cb.createQuery(Employee.class);
Root<Employee> root = query.from(Employee.class);
query.select(root).where(cb.equal(root.get("department"), "IT"));
List<Employee> employees = entityManager.createQuery(query).getResultList();

В этом примере мы создаем запрос с использованием Criteria API для получения списка сотрудников из таблицы Employee, у которых значение поля "department" равно "IT".

Итак, Criteria API - это часть Java Persistence API (JPA), которая предоставляет программистам возможность создавать динамические запросы к базе данных с использованием объектно-ориентированного подхода Он используется для создания запросов и определения критериев поиска в JPA Criteria API предоставляет более гибкий и типобезопасный способ создания запросов, чем SQL-запросы или JPQL

2727. В чем разница в требованиях к Entity в Hibernate, от требований к Entity, указанных в спецификации JPA (см. вопрос 10)?

В Hibernate существуют некоторые дополнительные требования к Entity, которые не указаны в спецификации JPA. Вот некоторые из них

  • Hibernate позволяет использовать каскадные операции сохранения, обновления и удаления, которые не являются обязательными в JPA.
  • Hibernate поддерживает дополнительные аннотации, такие как @LazyToOne, @LazyCollection, @BatchSize, которые не являются частью стандарта JPA.
  • Hibernate предоставляет возможность настройки ленивой инициализации с помощью аннотаций @LazyToOne и @LazyCollection, что не является обязательным в JPA.
  • Hibernate предоставляет свои собственные возможности для работы с критериями запросов, которые не являются частью JPA, такие как Criteria API.
  • Hibernate также предоставляет возможность настройки кэширования с помощью аннотаций @Cacheable и @Cache, что не является обязательным в JPA.

Обратите внимание, что эти требования специфичны для Hibernate и могут не работать с другими реализациями JPA.

2728. Какая уникальная стратегия наследования есть в Hibernate, но нет в спецификации JPA?

Hibernate поддерживает три основные стратегии отображения наследования: одна таблица для всех подклассов (Single Table), отдельная таблица для каждого подкласса (Table per Class), и отдельная таблица для каждого конкретного класса (Table per Concrete Class).

Однако, есть уникальная стратегия наследования в Hibernate, которая отсутствует в спецификации JPA. Это стратегия под названием "Joined Subclass" (Присоединенный подкласс). В этой стратегии, каждый подкласс имеет свою отдельную таблицу, но также имеет столбцы, которые наследуются от родительского класса.

Пример использования стратегии "Joined Subclass" в Hibernate:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Vehicle {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String brand;
    // other common attributes and methods
}

@Entity
public class Car extends Vehicle {
    private int numberOfDoors;
    // car-specific attributes and methods
}

@Entity
public class Motorcycle extends Vehicle {
    private boolean hasSidecar;
    // motorcycle-specific attributes and methods
}

В этом примере, у класса Vehicle есть отдельная таблица, а также у каждого подкласса (Car и Motorcycle) есть своя отдельная таблица, но они также наследуют столбцы из таблицы Vehicle.

2729. Какие основные новые возможности появились в спецификации JPA 2.1 по сравнению с JPA 2.0 (перечислите хотя бы пять-шесть новых возможностей)?

JPA 2.1 представляет несколько новых возможностей по сравнению с JPA 2.0. Вот пять-шесть из них:

  • Entity Graphs: Возможность определить граф загрузки сущностей, чтобы выбирать только нужные атрибуты и связанные сущности.
  • Converters: Возможность использовать конвертеры для преобразования значений атрибутов сущностей при сохранении и загрузке из базы данных.
  • DDL Generation: Возможность генерировать DDL-скрипты (Data Definition Language) для создания таблиц и других объектов базы данных на основе аннотаций сущностей.
  • Stored Procedures: Возможность вызывать хранимые процедуры базы данных из JPA-кода.
  • Criteria Update/Delete: Возможность выполнять массовые обновления и удаления данных с использованием Criteria API.

Это лишь некоторые из новых возможностей, представленных в JPA 2.1.