Автор оригинала: Vlad Mihalcea.
Вступление
В этой статье я хочу показать вам, как можно сопоставить строковое свойство JPA со столбцом базы данных JSON с помощью проекта hibernate-types
с открытым исходным кодом.
Хотя, вероятно, чаще всего используется JsonNode или POJO (Обычный старый объект Java) на стороне Java, платформа hibernate-types
очень гибкая и позволяет использовать тип свойства String
JPA для представления структуры JSON.
Как сопоставить строковое свойство JPA со столбцом JSON с помощью #Hibernate |/@vlad_mihalcea https://t.co/6ttwyQks7v pic.twitter.com/fuXWYAXrCy
Модель предметной области
Учитывая, что у нас есть книга
таблица базы данных, которая определяет свойства
столбец типа jsonb
PostgreSQL.
Связанная сущность Book
JPA может быть отображена следующим образом:
@Entity(name = "Book") @Table(name = "book") @TypeDef( name = "json", typeClass = JsonType.class ) public class Book { @Id @GeneratedValue private Long id; @NaturalId private String isbn; @Type(type = "json") @Column(columnDefinition = "jsonb") private String properties; //Getters and setters omitted for brevity }
Свойство isbn
отображается с помощью специфичной для гибернации @NaturalID
аннотации, которая позволяет извлекать сущность по ее естественному идентификатору .
Атрибут properties
JPA кодирует различные свойства, связанные с книгой, в объекте JSON String
. Из определения JPA @Column
мы видим, что связанный столбец базы данных имеет тип jsonb
.
Теперь, поскольку Hibernate не предоставляет собственный Тип
для обработки столбцов базы данных JSON, нам необходимо использовать тип Json
, предлагаемый библиотекой hibernate-types
.
Чтобы использовать библиотеку hibernate-types
в своем проекте, просто добавьте следующую зависимость Maven:
com.vladmihalcea hibernate-types-55 ${hibernate-types.version}
Если вы используете более старую версию Hibernate, перейдите в репозиторий hibernate-types
GitHub и найдите соответствующую зависимость hibernate-types
для вашей текущей версии Hibernate.
Время тестирования
При сохранении следующей Книги
сущности:
entityManager.persist( new Book() .setIsbn("978-9730228236") .setProperties( "{" + " \"title\": \"High-Performance Java Persistence\"," + " \"author\": \"Vlad Mihalcea\"," + " \"publisher\": \"Amazon\"," + " \"price\": 44.99" + "}" ) );
Hibernate создает следующую инструкцию SQL INSERT:
INSERT INTO book ( isbn, properties, id ) VALUES ( '978-9730228236', '{"title":"High-Performance Java Persistence","author":"Vlad Mihalcea","publisher":"Amazon","price":44.99}', 1 )
Обратите внимание на API в стиле Fluent, используемый при создании объекта Book
. Для получения более подробной информации о создании объектов с использованием API в стиле Fluent ознакомьтесь с этой статьей .
Теперь при извлечении ранее сохраненной Книги
сущности:
Book book = entityManager .unwrap(Session.class) .bySimpleNaturalId(Book.class) .load("978-9730228236"); assertTrue(book.getProperties().contains("\"price\": 44.99"));
Мы видим, что атрибут properties
правильно заполнен типом Json
.
Круто, правда?
Вывод
Хотя создание пользовательского типа гибернации является простым , гораздо удобнее использовать проект типы гибернации
с открытым исходным кодом, поскольку вам нужно добавить только одну зависимость и указать, какой пользовательский Тип
вы хотите использовать с помощью @TypeDef
аннотации.