Вступление
Проект hibernate-types открытым исходным кодом позволяет отображать JSON, ARRAY, YearMonth , Month или столбцы, специфичные для базы данных (например, адреса INET).
В этой статье мы рассмотрим, как можно сопоставить тип Enum PostgreSQL с массивом Java при использовании JPA и Hibernate.
Maven зависимость
Прежде всего, вам нужно настроить следующую зависимость Maven в pom.xml конфигурации вашего проекта pom.xml :
|
1
2
3
4
5
|
<dependency> <groupId>com.vladmihalcea</groupId> <artifactId>hibernate-types-52</artifactId> <version>2.3.5</version></dependency> |
Если вы используете более старые версии Hibernate, обратитесь к репозиторию GitHub hibernate-types для получения дополнительной информации о зависимости соответствия для текущей версии Hibernate.
Модель предметной области
Давайте предположим, что в нашей схеме базы данных есть следующее перечисление sensor_state PostgreSQL:
|
1
2
3
4
5
|
CREATE TYPE sensor_state AS ENUM ( 'ONLINE', 'OFFLINE', 'UNKNOWN'); |
Наше приложение должно хранить События в следующей таблице базы данных:
|
1
2
3
4
5
6
7
|
CREATE TABLE event ( id bigint NOT NULL, sensor_names text[], sensor_values integer[], sensor_states sensor_state[], CONSTRAINT event_pkey PRIMARY KEY (id)) |
Обратите внимание, что sensor_names , sensor_values и sensor_states хранятся в виде массивов. Чтобы сопоставить типы столбцов массива PostgreSQL с массивами Java, вам нужен собственный тип Hibernate, поскольку встроенные типы не поддерживают сохранение специфичных для базы данных массивов.
Однако благодаря библиотеке hibernate-types вы можете легко сопоставить таблицу event со следующей сущностью Event :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
@Entity(name = "Event")@Table(name = "event")@TypeDefs({ @TypeDef( typeClass = StringArrayType.class, defaultForType = String[].class ), @TypeDef( typeClass = IntArrayType.class, defaultForType = int[].class ), @TypeDef( typeClass = EnumArrayType.class, defaultForType = SensorState[].class, parameters = { @Parameter( name = EnumArrayType.SQL_ARRAY_TYPE, value = "sensor_state" ) } )})public class Event { @Id private Long id; @Column( name = "sensor_names", columnDefinition = "text[]" ) private String[] sensorNames; @Column( name = "sensor_values", columnDefinition = "integer[]" ) private int[] sensorValues; @Column( name = "sensor_states", columnDefinition = "sensor_state[]" ) private SensorState[] sensorStates; public Long getId() { return id; } public Event setId( Long id) { this.id = id; return this; } public String[] getSensorNames() { return sensorNames; } public Event setSensorNames( String[] sensorNames) { this.sensorNames = sensorNames; return this; } public int[] getSensorValues() { return sensorValues; } public Event setSensorValues( int[] sensorValues) { this.sensorValues = sensorValues; return this; } public SensorState[] getSensorStates() { return sensorStates; } public Event setSensorStates( SensorState[] sensorStates) { this.sensorStates = sensorStates; return this; }} |
Обратите внимание на API в стиле Fluent, используемый сущностью Event . В то время как JPA является более строгим, когда дело доходит до определения сеттеров, Hibernate позволяет вам определять сеттеры, чтобы вы могли строить сущность, используя API в стиле Fluent. Для более подробной информации, проверьте эту статью .
Аннотация @TypeDef используется для определения соответствия между типами классов массива Java и связанными с ними типами Hibernate:
- Тип массива Java
String[]обрабатываетсяStringArrayType. - Тип массива Java
int[]обрабатываетсяIntArrayType - Java
SensorState[]обрабатываетсяEnumArrayType. ПараметрEnumArrayType.SQL_ARRAY_TYPEиспользуется для описания специфичного для базы данных типа столбца, используемого для хранения Enum.
SensorState Java SensorState отображается следующим образом:
|
1
2
3
4
5
|
public enum SensorState { ONLINE, OFFLINE, UNKNOWN;} |
Время тестирования
Теперь при сохранении следующего объекта Event :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
entityManager.persist( new Event() .setId(1L) .setSensorNames( new String[]{ "Temperature", "Pressure" }) .setSensorValues( new int[]{ 12, 756 } ) .setSensorStates( new SensorState[]{ SensorState.ONLINE, SensorState.OFFLINE, SensorState.ONLINE, SensorState.UNKNOWN } ) ); |
Hibernate выполняет следующую инструкцию SQL INSERT:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
Query:[" insert into event ( sensor_names, sensor_states, sensor_values, id ) values ( ?, ?, ?, ? )"], Params:[( {"Temperature","Pressure"}, {"ONLINE","OFFLINE","ONLINE","UNKNOWN"}, {"12","756"}, 1)] |
И когда мы выбираем сущность Event , мы видим, что все свойства выбраны правильно
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
Event event = entityManager.find(Event.class, 1L);assertArrayEquals( new String[]{ "Temperature", "Pressure" }, event.getSensorNames());assertArrayEquals( new int[]{ 12, 756 }, event.getSensorValues());assertArrayEquals( new SensorState[]{ SensorState.ONLINE, SensorState.OFFLINE, SensorState.ONLINE, SensorState.UNKNOWN }, event.getSensorStates()); |
Круто, верно?
Если вам понравилась эта статья, держу пари, что вам понравятся и мои книжные и видео курсы .
Вывод
Проект hibernate-types поддерживает больше, чем типы ARRAY. Вы можете отобразить специфичные для PostgreSQL Enums, Nullable Character , JSON или даже предоставить свои собственные неизменяемые пользовательские Types Hibernate.
Чтобы узнать больше о проекте hibernate-types , ознакомьтесь с этой статьей .
| Опубликовано на Java Code Geeks с разрешения Влада Михалча, партнера нашей программы JCG. См. Оригинальную статью здесь: Как отобразить PostgreSQL Enums на свойства сущностей JPA с помощью Hibernate
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |

