Рубрики
Без рубрики

Как сопоставить строковое свойство JPA со столбцом JSON с помощью Hibernate

Узнайте, как сопоставить строковое свойство JPA со столбцом JSON при использовании Hibernate ORM и проекта с открытым исходным кодом типа hibernate.

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