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
@DynamicInsert в Hibernate

Аннотация @DynamicInsert (из пакета org.hibernate.annotations) указывает Hibernate генерировать SQL-запросы INSERT только для ненулевых полей сущности. Это позволяет оптимизировать вставку данных, исключая из запроса столбцы со значениями null.

Применяется на уровне класса сущности:
@Entity
@DynamicInsert
public class User { ... }


У
@DynamicInsert нет настраиваемых атрибутов — это маркерная аннотация (присутствие/отсутствие влияет на поведение).

Как работает

Если @DynamicInsert = true (или аннотация присутствует):
Hibernate анализирует, какие поля сущности не null.
В SQL-запрос INSERT включаются только эти поля.


Если @DynamicInsert = false (по умолчанию):
В INSERT попадают все поля, включая null.

Примеры SQL

Без @DynamicInsert
User user = new User();
user.setId(1L);
user.setName("Alice"); // age = null


Сгенерированный SQL (все поля, даже age=null):
INSERT INTO user (id, name, age) VALUES (1, 'Alice', NULL);


С @DynamicInsert
@DynamicInsert
@Entity
public class User { ... }


Тот же код, но SQL будет короче:
INSERT INTO user (id, name) VALUES (1, 'Alice');  -- поле age пропущено!


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

Во время компиляции маппинга
Hibernate определяет, нужно ли учитывать
@DynamicInsert для сущности.
При выполнении
session.save()
Проверяются значения полей.
Формируется SQL с учетом только ненулевых полей.
При генерации прокси-классов (если используется ленивая загрузка)
Не влияет напрямую, но может уменьшить объем данных в кеше.


Настройки и интеграция

В hibernate.cfg.xml или application.properties:
hibernate.dynamic_insert=true  # Применяется ко всем сущностям!


Но лучше использовать аннотацию для точечного контроля.

Совместимость с другими аннотациями

@DynamicUpdate – аналогично оптимизирует UPDATE.
@SelectBeforeUpdate – может конфликтовать (проверяет изменения перед UPDATE).


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

Плюсы
Уменьшает размер SQL-запросов.
Ускоряет вставку, если много null-полей.
Полезно для таблиц с большим числом столбцов.


Минусы
Усложняет отладку (меняется SQL).
Незначительный оверхед на проверку null.
Бесполезен, если все поля обычно заполнены.


Оптимальные сценарии

Таблицы с 50+ столбцами, где большинство значений null.
Частые вставки частично заполненных объектов.
Работа с унаследованными системами, где NULL в столбцах нежелателен.


Примеры

Пример 1: Игнорирование null
@DynamicInsert
@Entity
public class Product {
@Id
private Long id;
private String name;
private Integer stock; // Часто null для новых товаров
}


При сохранении Product(id=1, name="Laptop", stock=null):
INSERT INTO product (id, name) VALUES (1, 'Laptop');


Комбинация с @ColumnDefault
@DynamicInsert
@Entity
public class Account {
@Id
private Long id;

@ColumnDefault("0")
private BigDecimal balance; // Если null, БД подставит 0
}


При Account(id=1, balance=null) в БД запишется balance=0.

Ограничения
Не работает с @GeneratedValue (Hibernate требует все поля для идентификации).
Не влияет на JPQL/HQL – только на SQL, генерируемый Hibernate.
Проблемы с кешированием – если кеш второго уровня ожидает полный объект.


#Java #Training #Hard #Spring #Hibernate #DynamicInsert