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

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
@MetaValue в Hibernate

Аннотация @MetaValue используется в связке с @AnyMetaDef, @ManyToAny или @Any для определения соответствия между дискриминатором (меткой типа) и конкретным классом сущности. Она позволяет Hibernate понять, какую сущность загружать при полиморфных ассоциациях.

Пакет: org.hibernate.annotations

Применяется внутри: @AnyMetaDef.metaValues или @TypeDef.metaValues.

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


Атрибуты @MetaValue
targetEntity: Класс сущности, на который ссылается метка.
value: Значение дискриминатора в БД (например, "BOOK" или 1).

Пример использования
@AnyMetaDef(
name = "mediaMetaDef",
metaType = "string", // Тип столбца-дискриминатора (varchar)
idType = "long", // Тип ID целевой сущности
metaValues = {
@MetaValue(targetEntity = Book.class, value = "BOOK"),
@MetaValue(targetEntity = Movie.class, value = "MOVIE")
}
)


Жизненный цикл и обработка

Как работает @MetaValue?

При сохранении:
Hibernate смотрит тип объекта в коллекции (например, Book).
Записывает в столбец-дискриминатор (item_type) значение "BOOK".


При загрузке:
Hibernate читает item_type из БД (например, "MOVIE").
Сопоставляет значение с классом Movie через
@MetaValue.
Загружает сущность Movie по item_id.


Где хранится дискриминатор?

В отдельном столбце таблицы (например, item_type).
Или в общей таблице, если используется @Any +
@Column.

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

Пример 1: Полиморфная коллекция (@ManyToAny)
@Entity
public class Library {
@Id
private Long id;

@ManyToAny
@AnyMetaDef(
name = "mediaMetaDef",
metaType = "string",
idType = "long",
metaValues = {
@MetaValue(targetEntity = Book.class, value = "BOOK"),
@MetaValue(targetEntity = Movie.class, value = "MOVIE")
}
)
@JoinTable(
name = "library_items",
joinColumns = @JoinColumn(name = "library_id"),
inverseJoinColumns = @JoinColumn(name = "item_id")
)
@Column(name = "item_type") // Столбец для дискриминатора
private List<Object> items; // Может содержать Book и Movie
}


Пример 2: Одиночная полиморфная ссылка (@Any)
@Entity
public class Review {
@Id
private Long id;

@Any(metaDef = "mediaMetaDef")
@JoinColumn(name = "content_id")
@Column(name = "content_type") // Дискриминатор
private Object content; // Book или Movie
}


Ограничения

Нет типобезопасности:
Коллекция List<Object> требует проверки instanceof.
Решение: использовать Visitor-паттерн или DTO.


Ограниченная поддержка в JPA:
Запросы с WHERE content_type = 'BOOK' не работают в чистом JPA.
Решение: нативные SQL-запросы или Hibernate.initialize().


Нет каскадирования:
CascadeType.ALL не поддерживается.

#Java #Training #Hard #Spring #Hibernate #MetaValue