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

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Please open Telegram to view this post
VIEW IN TELEGRAM
@Immutable в Hibernate

Аннотация @Immutable помечает сущность или коллекцию как неизменяемую, что означает, что Hibernate игнорирует любые попытки обновления или удаления таких объектов. Это полезно для оптимизации производительности и предотвращения случайных изменений.
Пакет: org.hibernate.annotations.

1. Применение и параметры

@Immutable не имеет параметров — это маркерная аннотация.

Где может применяться:
На уровне класса (сущности):

@Entity  
@Immutable
public class LogEntry { ... }
Все экземпляры LogEntry становятся read-only.


На уровне коллекции:
@OneToMany  
@Immutable
private List<LogEntry> logs; // Элементы коллекции нельзя изменить


2. Жизненный цикл и поведение

При загрузке:
Объекты загружаются как обычно, но Hibernate не отслеживает изменения (не добавляет их в PersistenceContext для dirty-checking).

При попытке обновления:
Выбрасывается исключение UnsupportedOperationException (если попытаться изменить поле или вызвать entityManager.merge()).

При удалении:
Игнорируется (если только не используется @SQLDelete с кастомным запросом).

Кэширование:
Сущности с @Immutable идеально подходят для кэширования (например, @Cacheable), так как никогда не меняются.

Механизмы Hibernate и Spring Boot

1. Как Hibernate обрабатывает @Immutable

Оптимизации:
Пропускает dirty-checking для таких сущностей, что ускоряет flush().
Не создает прокси для ленивых загрузок (если
@Immutable применен к коллекции).

Исключения:
Session.update(), Session.merge(), Session.delete() игнорируются или выбрасывают исключение.

2. Интеграция с JPA и Spring Boot

JPA-аналоги:

Стандарт JPA не имеет прямой замены @Immutable, но можно эмулировать через:
@Entity  
@DynamicUpdate(false) // Отключает генерацию UPDATE
@org.hibernate.annotations.OptimisticLocking(type = NONE) // Отключает версионирование
public class LogEntry { ... }


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

1. Справочные данные (Countries, Currencies)

@Entity  
@Immutable
public class Currency {
@Id
private String code; // USD, EUR
private String name;
// Нет сеттеров
}


Запросы только на чтение:
List<Currency> currencies = entityManager  
.createQuery("SELECT c FROM Currency c", Currency.class)
.getResultList();


2. Логи и аудит (неизменяемые записи)
@Entity  
@Immutable
public class AuditLog {
@Id @GeneratedValue
private Long id;
private String action;
@Column(updatable = false)
private LocalDateTime createdAt;
}


3. Неизменяемые коллекции
@Entity  
public class User {
@Id private Long id;
@OneToMany
@Immutable
private List<LoginHistory> history; // История логинов только для чтения
}


Ограничения и обходные пути

1. Что нельзя сделать с @Immutable
Обновлять поля: Даже через нативный SQL (entityManager.createNativeQuery("UPDATE...")), если только не отключить проверки Hibernate.
Каскадные операции: CascadeType.PERSIST работает, но MERGE, DELETE — нет.


2. Альтернативы

Read-only транзакции (Spring):
@Transactional(readOnly = true) // Оптимизация на уровне JDBC  
public List<Currency> getCurrencies() { ... }


DTO и проекции:
public interface CurrencyView {  
String getCode();
String getName();
}
Плюс: не требуют Hibernate-сущностей.


#Java #Training #Hard #Spring #Hibernate #Immutable
#Mems. Теперь нужно понять непонятное.
Что выведет код?

import java.util.HashMap;

public class Task110425 {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put(new String("A"), 2);
map.put("B", 3);

System.out.println(map.get("A"));
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
15%
1
67%
2
5%
null
13%
Exception какой-нибудь
У кого еще есть такие проблемы? 😂

https://t.me/Java_for_beginner_dev

#Mems
Please open Telegram to view this post
VIEW IN TELEGRAM
@Index в Hibernate

Аннотация
@Index в Hibernate используется для определения индекса на одном или нескольких столбцах таблицы базы данных. Индексы ускоряют поиск и сортировку данных, но могут замедлять операции вставки и обновления.

Пакет: org.hibernate.annotations

Применяется к: классу (на уровне @Table), полю или свойству.

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

Аннотация @Index имеет следующие атрибуты:

name (String):
Название индекса в БД.
Если не указано, Hibernate сгенерирует имя автоматически (например, IDX_<TABLE>_<COLUMN>).


columnList (String):
Обязательный параметр.
Список столбцов, входящих в индекс, через запятую (например, "username, email").
Поддерживает порядок сортировки: "username ASC, email DESC".


unique (boolean, по умолчанию false):
Если true, создает уникальный индекс (аналог UNIQUE INDEX в SQL).

options (String):
Дополнительные SQL-опции для индекса (например, "USING HASH" для MySQL).

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

Во время компиляции:
Hibernate анализирует аннотацию и включает её в метаданные ORM.

При старте приложения (Hibernate bootstrap):
Индекс добавляется в DDL-скрипт при автоматической генерации схемы (hibernate.hbm2ddl.auto=create/update).
Если БД уже существует, Hibernate не изменяет индексы при update (только создает новые).


Во время выполнения:
Индекс используется СУБД для оптимизации запросов, но Hibernate напрямую его не контролирует.

Механизмы Hibernate и Spring Boot, влияющие на @Index

Генерация DDL (hibernate.hbm2ddl.auto):
create – создает таблицы и индексы при старте.
update – добавляет новые индексы, но не удаляет старые.
validate – проверяет соответствие модели и БД (включая индексы).
none – отключает управление схемой.


Настройки Spring Boot (application.properties):
spring.jpa.hibernate.ddl-auto=update  
spring.jpa.properties.hibernate.default_schema=public
spring.jpa.show-sql=true


Альтернативные способы определения индексов:

Через @Table(indexes = @Index(...)):
@Entity
@Table(indexes = @Index(name = "idx_user_email", columnList = "email", unique = true))
public class User { ... }


Через schema.sql (ручное управление индексами).

Кастомизация имен индексов:

Глобальное именование через ImplicitNamingStrategy (редко используется для индексов).

Особенности и ограничения

СУБД-специфичные индексы (например, частичные индексы в PostgreSQL) требуют @Index(options = "WHERE condition") или ручного SQL.
Составные индексы (columnList = "col1, col2") работают только в указанном порядке.
Миграции: Для сложных изменений индексов лучше использовать Flyway/Liquibase.


#Java #Training #Hard #Spring #Hibernate #Index
Всем доброго, субботнего утра! 🖐

Как прошла неделя?

Сегодня выходной, поэтому мы посмотрим подборку смешных видосов и делать ничего не будем! 😜

А завтра в обычное время допишем футбольный сервис с
@Shikin_Anatoliy! 💪

Всем хороших выходных! 🥳
Please open Telegram to view this post
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Кто на курсах учился, у вас там так? 😉

https://t.me/Java_for_beginner_dev

#Mems
Please open Telegram to view this post
VIEW IN TELEGRAM
Всем привет! ✌️

Сегодня мы вновь соберемся с @Shikin_Anatoliy, в 16:00 по МСК в Яндекс.Телемост, чтобы закончить тестовое задание по написанию футбольного сервиса. ⚽️

Приходите и учитесь вместе с нами! 💪

Ждем всех 🫵
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM