Автор оригинала: Vlad Mihalcea.
Вступление
В этой статье я собираюсь объяснить, почему вы всегда должны использовать функцию динамического обновления Hibernate для объектов, отображающих свойства JSON.
Поскольку Hibernate ORM не поддерживает типы столбцов JSON, мы собираемся использовать библиотеку Hibernate Types , которая предоставляет JsonType
, позволяющий сопоставлять Строку
, Карту
, Список
, JsonNode
, записи Java или POJOs в столбцах JSON, независимо от того, используете ли вы PostgreSQL, MySQL, Oracle, SQL Server или H2.
Модель предметной области
Наше приложение требует сохранения Книги
сущностей, которые выглядят следующим образом:
@Entity(name = "Book") @Table(name = "book") @TypeDef(typeClass = JsonType.class, name = "json") public class Book { @Id @GeneratedValue private Long id; @NaturalId private String isbn; private String title; private String author; @Column(columnDefinition = "jsonb") @Type(type = "json") private String properties; }
Атрибут свойства
сущности отображается в столбце jsonb
PostgreSQL, и по этой причине для обработки сопоставления используется тип Json
из проекта “Типы гибернации”.
Обновление объекта гибернации без динамического обновления
По умолчанию при изменении сущности:
entityManager .unwrap(Session.class) .bySimpleNaturalId(Book.class) .load("978-9730228236") .setTitle( "High-Performance Java Persistence, 2nd edition" );
Hibernate выполняет инструкцию UPDATE, которая включает в себя все атрибуты сущности, даже те, которые не были изменены:
UPDATE book SET author = 'Vlad Mihalcea', properties = '{ "price":44.99, "reviews":[{ "date":"2017-11-14", "rating":5, "review":"Excellent book to understand Java Persistence", "reviewer":"Cristiano" },{ "date":"2019-01-27", "rating":5, "review":"The best JPA ORM book out there", "reviewer":"T.W" },{ "date":"2016-12-24", "rating":4, "review":"The most informative book", "reviewer":"Shaikh" } }', title = 'High-Performance Java Persistence, 2nd edition' WHERE id = 1
Обратите внимание, что объект properties
JSON также задан, и чем больше объект JSON, тем выше влияние на производительность отправки ненужных данных.
Используйте динамическое обновление гибернации для свойств JSON
Как я объяснил в этой статье , вы можете использовать аннотацию @DynamicUpdate
, чтобы указать Hibernate, что вы хотите, чтобы оператор UPDATE создавался динамически при очистке контекста сохранения.
Итак, при добавлении @DynamicUpdate
аннотации к Книге
сущности:
@Entity(name = "Book") @Table(name = "book") @TypeDef(typeClass = JsonType.class, name = "json") @DynamicUpdate public class Book { ... }
И, повторно запустив предыдущий тестовый случай изменения сущности, мы видим, что Hibernate выполняет инструкцию UPDATE, которая включает только те столбцы, которые были изменены:
UPDATE book SET title = 'High-Performance Java Persistence, 2nd edition' WHERE id = 1
Намного лучше!
Вывод
Как вы можете видеть, использование функции динамического обновления Hibernate для сущностей, содержащих свойства JSON, является очень хорошей идеей, поскольку она позволяет избежать отправки объектов JSON в базу данных и установить в столбце то же значение, которое было прочитано ранее.
Для получения более подробной информации о сопоставлении столбцов JSON с JPA и Hibernate также ознакомьтесь с этой статьей.