Автор оригинала: 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 аннотации.