Чтобы Hibernate не создавал SQL запросы на вставку и обновление строк заранее, на этапе запуска приложения, а делал это каждый раз во время непосредственно вставки/обновления, можно использовать аннотации @DynamicInsert и @DynamicUpdate.
Ставятся эти аннотации непосредственно над классом предметной области:
1 2 3 4 5 |
@Entity @org.hibernate.annotations.DynamicInsert @org.hibernate.annotations.DynamicUpdate public class Item { ... |
Поскольку эти аннотации не являются стандартными JPA аннотациями, а доступны только в Hibernate, то мы пишем их полное имя.
Какую проблему решает данный подход
Допустим есть следующий класс предметной области:
1 2 3 4 5 6 7 8 9 |
@Entity public class Client { @Id @GeneratedValue Long id; private String fullName; private String address; //Конструкторы, геттеры и сеттеры, equals(), hashCode() и т.д. } |
Во время старта приложения Hibernate создаст для этой сущности (как минимум) четыре SQL запроса (обычный CRUD), чтобы не тратить вычислительные мощности на их создание во время выполнения. Выглядеть они будут примерно следующим образом.
Выборка:
1 |
SELECT * FROM client; |
Удаление:
1 |
DELETE FROM client WHERE id = ?; |
Вставка:
1 |
INSERT INTO client (id, full_name, address) VALUES (?, ?, ?); |
Обновление:
1 |
UPDATE client SET full_name = ?, address = ? WHERE id = ?; |
У операций вставки и обновления в этих примерах просматривается особенность. Если мы хотим создать такие SQL заранее, то мы должны упомянуть в них сразу все поля. Причём в реальности и для вставки, и для обновления у нас могут быть данные не для всех полей. Особенно это актуально для обновления. Мы хотим, например, обновить всего одно поле, но в запросе указываем все поля, заново вставляя в них те же данные, которые там уже есть.
В ситуациях, когда те или иные таблицы имеют много полей и активно используются, такой подход может существенно сказаться на производительности приложения. Использование аннотаций @DynamicInsert и @DynamicUpdate закрывает эту проблему, заставляя Hibernate формировать соответствующий SQL запросы на вставку и обновление на лету во время исполнения, задействуя только те поля, которые реально используются.