Java for Beginner
672 subscribers
540 photos
155 videos
12 files
827 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Аннотации @OneToMany и @ManyToOne

Аннотации @OneToMany и @ManyToOne используются в Java Persistence API (JPA) для обозначения отношений "один ко многим" и "многие к одному" между сущностями. Они находятся в пакете javax.persistence (или jakarta.persistence в Jakarta EE).

@OneToMany: Указывает, что одна сущность связана с коллекцией других сущностей.
@ManyToOne: Указывает, что множество сущностей связано с одной сущностью.

Эти аннотации часто используются вместе для описания двусторонних отношений.

Параметры и настройки

@OneToMany

targetEntity:

Указывает класс целевой сущности (если он не может быть выведен из типа поля).

Пример:
@OneToMany(targetEntity = Order.class)
private List<Order> orders;


cascade: (#CASCADE)
Определяет каскадные операции, которые должны быть применены к связанным сущностям.
Возможные значения: CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE, CascadeType.REFRESH, CascadeType.DETACH, CascadeType.ALL.

CascadeType.PERSIST:
Каскадное сохранение. Если сущность сохраняется (например, через EntityManager.persist()), то связанные сущности также будут сохранены.

CascadeType.MERGE:

Каскадное обновление. Если сущность обновляется (например, через EntityManager.merge()), то связанные сущности также будут обновлены.

CascadeType.REMOVE:
Каскадное удаление. Если сущность удаляется (например, через EntityManager.remove()), то связанные сущности также будут удалены.

CascadeType.REFRESH:
Каскадное обновление состояния. Если сущность обновляется из базы данных (например, через EntityManager.refresh()), то связанные сущности также будут обновлены.

CascadeType.DETACH:

Каскадное отсоединение. Если сущность отсоединяется от контекста persistence (например, через EntityManager.detach()), то связанные сущности также будут отсоединены.

CascadeType.ALL:
Каскадное применение всех операций. Включает в себя PERSIST, MERGE, REMOVE, REFRESH, и DETACH. Все операции, применяемые к сущности, будут каскадно применены к связанным сущностям.

Пример:
@OneToMany(cascade = CascadeType.ALL)
private List<Order> orders;


fetch:
Определяет стратегию загрузки связанных сущностей.

Возможные значения: FetchType.EAGER (загрузка сразу) или FetchType.LAZY (ленивая загрузка).
По умолчанию: FetchType.LAZY.

Пример:
@OneToMany(fetch = FetchType.EAGER)
private List<Order> orders;


mappedBy:
Указывает поле в целевой сущности, которое управляет отношением (используется на стороне, которая не владеет отношением).

Пример:
@OneToMany(mappedBy = "customer")
private List<Order> orders;


orphanRemoval:
Указывает, должны ли связанные сущности быть удалены при удалении их из коллекции или установке в null.
По умолчанию: false.

Пример:
@OneToMany(orphanRemoval = true)
private List<Order> orders;



@ManyToOne

Также как и для @OneToMany
targetEntity
cascade
fetch


Но отличается наличием:
optional:
Указывает, может ли связанная сущность быть null.
По умолчанию: true.

Пример:
@ManyToOne(optional = false)
private Customer customer;


Значения по умолчанию

Для @OneToMany:
fetch = FetchType.LAZY
orphanRemoval = false


Для @ManyToOne:
fetch = FetchType.EAGER
optional = true


Жизненный цикл

Применение: Аннотации применяются на этапе маппинга сущностей JPA. Они указывают на отношения между сущностями.
Инициализация: При загрузке сущности из базы данных JPA загружает связанные сущности в зависимости от стратегии загрузки (EAGER или LAZY).
Уничтожение: При удалении сущности JPA учитывает каскадные операции и параметр orphanRemoval.


Варианты настройки

Одностороннее отношение:
Отношение управляется одной из сущностей. Пример:
@Entity
public class Customer {
@OneToMany
private List<Order> orders;
}


Двустороннее отношение:
Отношение управляется обеими сущностями. Пример:
@Entity
public class Customer {
@OneToMany(mappedBy = "customer")
private List<Order> orders;
}

@Entity
public class Order {
@ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
}


#Java #Training #Hard #Spring #SpringDataJPA #OneToMany #ManyToOne
Аннотация @ManyToMany

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

Аннотация @ManyToMany принимает несколько параметров для настройки отношения:

targetEntity:
Указывает класс целевой сущности (если он не может быть выведен из типа поля).

Пример:
@ManyToMany(targetEntity = Role.class)
private List<Role> roles;


cascade: (#CASCADE)
Определяет каскадные операции, которые должны быть применены к связанным сущностям.
Возможные значения: CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE, CascadeType.REFRESH, CascadeType.DETACH, CascadeType.ALL.

Пример:
@ManyToMany(cascade = CascadeType.ALL)
private List<Role> roles;


fetch:
Определяет стратегию загрузки связанных сущностей.
Возможные значения: FetchType.EAGER (загрузка сразу) или FetchType.LAZY (ленивая загрузка).

По умолчанию: FetchType.LAZY.

Пример:
@ManyToMany(fetch = FetchType.EAGER)
private List<Role> roles;


mappedBy:
Указывает поле в целевой сущности, которое управляет отношением (используется на стороне, которая не владеет отношением).

Пример:
@ManyToMany(mappedBy = "users")
private List<Role> roles;


orphanRemoval:
Указывает, должны ли связанные сущности быть удалены при удалении их из коллекции или установке в null.
По умолчанию: false.

Пример:
@ManyToMany(orphanRemoval = true)
private List<Role> roles;


Значения по умолчанию

Если параметры не указаны, используются значения по умолчанию:
fetch = FetchType.LAZY
orphanRemoval = false


Жизненный цикл

Применение: Аннотация
@ManyToMany применяется на этапе маппинга сущностей JPA. Она указывает, что между двумя сущностями существует отношение "многие ко многим".
Инициализация: При загрузке сущности из базы данных JPA загружает связанные сущности в зависимости от стратегии загрузки (EAGER или LAZY).
Уничтожение: При удалении сущности JPA учитывает каскадные операции и параметр orphanRemoval.


Варианты настройки

Одностороннее отношение:
Отношение управляется одной из сущностей. Пример:
@Entity
public class User {
@ManyToMany
private List<Role> roles;
}


Двустороннее отношение:
Отношение управляется обеими сущностями. Пример:
@Entity
public class User {
@ManyToMany(mappedBy = "users")
private List<Role> roles;
}

@Entity
public class Role {
@ManyToMany
@JoinTable(
name = "user_role",
joinColumns = @JoinColumn(name = "role_id"),
inverseJoinColumns = @JoinColumn(name = "user_id")
)
private List<User> users;
}


Каскадные операции:
Используются для автоматического применения операций к связанным сущностям. Пример:
@ManyToMany(cascade = CascadeType.ALL)
private List<Role> roles;


Ленивая загрузка:
Используется для оптимизации производительности. Пример:
@ManyToMany(fetch = FetchType.LAZY)
private List<Role> roles;


Кастомизация промежуточной таблицы:
С помощью аннотации @JoinTable можно настроить промежуточную таблицу для отношения "многие ко многим". Пример:
@ManyToMany
@JoinTable(
name = "user_role",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private List<Role> roles;


#Java #Training #Hard #Spring #SpringDataJPA #ManyToMany
Аннотация @Cascade в Hibernate

Аннотация @Cascade (org.hibernate.annotations.Cascade) управляет каскадными операциями (сохранение, обновление, удаление) для ассоциаций между сущностями. Она дополняет или заменяет стандартные каскадные операции JPA (CascadeType).

Отличается от javax.persistence.CascadeType тем, что поддерживает специфичные для Hibernate каскады, например, CascadeType.LOCK или CascadeType.REPLICATE.

Параметры

Принимает одно или несколько значений из перечисления org.hibernate.annotations.CascadeType:
PERSIST – сохраняет связанную сущность при сохранении родителя (аналог CascadeType.PERSIST).
MERGE – обновляет связанную сущность при обновлении родителя (аналог CascadeType.MERGE).
REMOVE – удаляет связанную сущность при удалении родителя (аналог CascadeType.REMOVE).
REFRESH – обновляет связанную сущность при обновлении родителя (аналог CascadeType.REFRESH).
DETACH – отключает связанную сущность от контекста (аналог CascadeType.DETACH).
SAVE_UPDATE – сохраняет или обновляет связанную сущность при сохранении/обновлении родителя (устарело в Hibernate 6+, вместо этого используйте PERSIST + MERGE).
LOCK – блокирует связанную сущность при блокировке родителя (специфично для Hibernate).
REPLICATE – реплицирует связанную сущность при репликации родителя (специфично для Hibernate).
DELETE – удаляет связанную сущность при удалении родителя (аналог REMOVE, но работает в некоторых случаях иначе).
DELETE_ORPHAN – удаляет связанную сущность, если она больше не связана с родителем (работает только для коллекций).


Примеры использования

Каскадное сохранение и удаление
@Entity
public class Parent {
@Id
private Long id;

@OneToMany(mappedBy = "parent")
@Cascade({CascadeType.PERSIST, CascadeType.REMOVE})
private List<Child> children;
}


Что делает:
При сохранении Parent автоматически сохраняются все Child.
При удалении Parent автоматически удаляются все Child.


Каскадное обновление и управление "сиротами"
@Entity
public class Author {
@Id
private Long id;

@OneToMany(mappedBy = "author")
@Cascade({CascadeType.MERGE, CascadeType.DELETE_ORPHAN})
private List<Book> books;
}


Что делает:
При обновлении Author обновляются все связанные Book.
Если книга удаляется из списка books, она автоматически удаляется из БД (orphanRemoval).


Специфичные каскады Hibernate (LOCK, REPLICATE)
@Entity
public class Order {
@Id
private Long id;

@OneToMany(mappedBy = "order")
@Cascade({CascadeType.LOCK, CascadeType.REPLICATE})
private List<Item> items;
}


Что делает:
При блокировке Order блокируются все Item.
При репликации Order реплицируются все Item.


Разница между @Cascade и cascade в JPA

JPA (javax.persistence.CascadeType)
@OneToMany(mappedBy = "parent", cascade = {javax.persistence.CascadeType.PERSIST, javax.persistence.CascadeType.REMOVE})


Стандартный механизм JPA.
Поддерживает только базовые операции (PERSIST, MERGE, REMOVE, REFRESH, DETACH, ALL).


Hibernate (@Cascade)
@OneToMany(mappedBy = "parent")
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})


Расширенный функционал (например, DELETE_ORPHAN, LOCK, REPLICATE).
Работает только в Hibernate.


Когда использовать @Cascade?

Если нужны специфичные для Hibernate каскады (LOCK, REPLICATE).
Если требуется удаление "сирот" (DELETE_ORPHAN).
В остальных случаях лучше использовать стандартный
cascade из JPA.

Оптимизация производительности

Каскадные операции могут приводить к неожиданным DELETE/UPDATE.

Рекомендуется:
Использовать orphanRemoval только там, где это необходимо.
Избегать CascadeType.ALL (может привести к неявным удалениям).


#Java #Training #Hard #Spring #Hibernate #Cascade