Автор оригинала: Vlad Mihalcea.
Вступление
В этой статье мы рассмотрим, как мы можем хранить атрибуты сущности Java Map в столбцах JSON при использовании JPA, Hibernate и типов Hibernate project.
Хотя вы также можете сохранять атрибуты Java Map
сущностей в столбцах PostgreSQL HStore , тип столбца JSON является гораздо более распространенным вариантом, особенно с учетом того, что он работает с другими реляционными базами данных, такими как Oracle, SQL Server или MySQL.
Как вы уже видели, проект Hibernate Types позволяет сопоставлять тип столбца JSON с широким спектром атрибутов сущностей JPA, таких как POJOs, JsonNode
, коллекции или String
типы объектов Java:
- Как отобразить атрибуты сущности POJO в формате JSON с помощью JPA и гибернации
- Как JSON-кодировать атрибуты сущностей как JSON с помощью JPA и гибернации
- Как сопоставить строковое свойство JPA со столбцом JSON с помощью Hibernate
- Как сопоставить коллекции JSON с помощью JPA и гибернации
В этой статье показано, что вы также можете сопоставлять типы столбцов JSON с атрибутами сущностей Java Map при использовании JPA и Hibernate.
Зависимость Maven для сопоставления JSON с JPA и гибернацией
Первое, что нам нужно сделать, это добавить зависимость типов гибернации из центрального репозитория Maven. Например, если вы используете Maven, вам необходимо добавить в свой проект следующую зависимость pom.xml
файл конфигурации:
com.vladmihalcea hibernate-types-55 ${hibernate-types.version}
Для более старых версий Hibernate ORM вы можете использовать зависимости hibernate-types-5
, hibernate-types-43
или hibernate-types-4
. В документации Типы гибернации
проект содержится более подробная информация о том, какую зависимость следует использовать в зависимости от версии ORM гибернации, используемой вашим проектом.
Модель предметной области
Давайте предположим, что у нас есть следующая книга
таблица в нашей реляционной базе данных:
И мы хотим сопоставить его с Книгой
сущностью, чей свойства
атрибут имеет тип//Map<Строка, строка>
:
Сопоставление свойства сущности Java Map со столбцом JSON с помощью JPA и Hibernate
Сущность Book
JPA отображается следующим образом:
@Entity(name = "Book") @Table(name = "book") @TypeDef(name = "json", typeClass = JsonType.class) public class Book { @Id @GeneratedValue private Long id; @NaturalId @Column(length = 15) private String isbn; @Type(type = "json") @Column(columnDefinition = "jsonb") private Mapproperties = new HashMap<>(); public String getIsbn() { return isbn; } public Book setIsbn(String isbn) { this.isbn = isbn; return this; } public Map getProperties() { return properties; } public Book setProperties(Map properties) { this.properties = properties; return this; } public Book addProperty(String key, String value) { properties.put(key, value); return this; } }
Аннотация @TypeDef
используется для регистрации типа Json
, который обрабатывает типы столбцов JSON при использовании Oracle или PostgreSQL, SQL Server или MySQL.
Свойство isbn
использует аннотацию @NaturalID , которая позволяет нам извлекать объект Book
по номеру ISBN, не зная его числового идентификатора.
Атрибут свойства
имеет тип Map<Строка, строка>
, поэтому он использует аннотацию @Type
для ссылки на тип json
, который мы зарегистрировали ранее с помощью аннотации @TypeDef
.
Получатели, установщики, а также метод addProperty
утилиты используют API в стиле Fluent для упрощения способа создания Книги
экземпляров сущностей.
Время Тестирования
При сохранении следующей Книги
сущности:
entityManager.persist( new Book() .setIsbn("978-9730228236") .addProperty("title", "High-Performance Java Persistence") .addProperty("author", "Vlad Mihalcea") .addProperty("publisher", "Amazon") .addProperty("price", "$44.95") );
Hibernate создает следующую инструкцию SQL INSERT:
INSERT INTO book ( isbn, properties, id ) VALUES ( '978-9730228236', { "author":"Vlad Mihalcea", "price":"$44.95", "publisher":"Amazon", "title":"High-Performance Java Persistence" }, 1 )
И при извлечении сущности Book
мы видим, что атрибут properties
entity правильно извлечен из базы данных:
Book book = entityManager.unwrap(Session.class) .bySimpleNaturalId(Book.class) .load("978-9730228236"); MapbookProperties = book.getProperties(); assertEquals( "High-Performance Java Persistence", bookProperties.get("title") ); assertEquals( "Vlad Mihalcea", bookProperties.get("author") );
Потрясающе, правда?
Вывод
Как вы можете видеть, сопоставление свойства сущности Java Map JPA с типом столбца JSON очень просто при использовании типов Hibernate project.
Типы гибернации поддерживают многие нестандартные типы столбцов, а не только JSON. Вы можете использовать его для сопоставления массивов, инициализации, HStore, перечислений, специфичных для PostgreSQL, столбцов, допускающих обнуление Символов
, или использовать расширенные экземпляры ResultTransformer .
Если вы используете JPA и Hibernate, то вам определенно следует также использовать типы Hibernate project.