Hibernate-Typen-Projekt
Sie können ein mehrdimensionales PostgreSQL-Array mit der Methode Hibernate-Typen Projekt.
Sie können entweder ein Java-Array auf der Seite der Entitätsattribute verwenden oder die List
.
Datenbank-Tabelle
Nehmen wir zum Beispiel an, dass Sie Folgendes haben plane
Datenbank-Tabelle:
CREATE TABLE plane (
id INT8 NOT NULL,
name VARCHAR(255),
seat_grid seat_status[][],
PRIMARY KEY (id)
)
Wo die seat_status
ist ein PostgreSQL-Enum:
CREATE TYPE seat_status
AS ENUM (
'UNRESERVED',
'RESERVED',
'BLOCKED'
);
JPA-Einheit
Sie können die seatGrid
Spalte unter Verwendung der EnumArrayType
:
@Entity(name = "Plane")
@Table(name = "plane")
@TypeDef(
name = "seat_status_array",
typeClass = EnumArrayType.class
)
public static class Plane {
@Id
private Long id;
private String name;
@Type(
type = "seat_status_array",
parameters = @org.hibernate.annotations.Parameter(
name = "sql_array_type",
value = "seat_status"
)
)
@Column(
name = "seat_grid",
columnDefinition = "seat_status[][]"
)
private SeatStatus[][] seatGrid;
//Getters and setters omitted for brevity
public SeatStatus getSeatStatus(int row, char letter) {
return seatGrid[row - 1][letter - 65];
}
}
Sie müssen also den zu verwendenden Hibernate-Typ deklarieren. Für Enums müssen Sie den EnumArrayType
:
@TypeDef(
name = "seat_status_array",
typeClass = EnumArrayType.class
)
Les @Type
Annotation ermöglicht die Übergabe von Parametern an den Hibernate-Typ, wie die SQL-Array-Klasse:
@Type(
type = "seat_status_array",
parameters = @org.hibernate.annotations.Parameter(
name = "sql_array_type",
value = "seat_status"
)
)
Prüfzeit
Wenn Sie nun auf Folgendes bestehen Post
Einheit:
entityManager.persist(
new Plane()
.setId(1L)
.setName("ATR-42")
.setSeatGrid(
new SeatStatus[][] {
{
SeatStatus.BLOCKED, SeatStatus.BLOCKED,
SeatStatus.BLOCKED, SeatStatus.BLOCKED
},
{
SeatStatus.UNRESERVED, SeatStatus.UNRESERVED,
SeatStatus.RESERVED, SeatStatus.UNRESERVED
},
{
SeatStatus.RESERVED, SeatStatus.RESERVED,
SeatStatus.RESERVED, SeatStatus.RESERVED
}
}
)
);
Hibernate wird die richtige SQL INSERT-Anweisung ausgeben:
INSERT INTO plane (
name,
seat_grid,
id
)
VALUES (
'ATR-42',
{
{"BLOCKED", "BLOCKED", "BLOCKED", "BLOCKED"},
{"UNRESERVED", "UNRESERVED", "RESERVED", "UNRESERVED"},
{"RESERVED", "RESERVED", "RESERVED", "RESERVED"}
},
1
)
Und beim Abrufen der Entität funktioniert alles wie erwartet:
Plane plane = entityManager.find(Plane.class, 1L);
assertEquals("ATR-42", plane.getName());
assertEquals(SeatStatus.BLOCKED, plane.getSeatStatus(1, 'A'));
assertEquals(SeatStatus.BLOCKED, plane.getSeatStatus(1, 'B'));
assertEquals(SeatStatus.BLOCKED, plane.getSeatStatus(1, 'C'));
assertEquals(SeatStatus.BLOCKED, plane.getSeatStatus(1, 'D'));
assertEquals(SeatStatus.UNRESERVED, plane.getSeatStatus(2, 'A'));
assertEquals(SeatStatus.UNRESERVED, plane.getSeatStatus(2, 'B'));
assertEquals(SeatStatus.RESERVED, plane.getSeatStatus(2, 'C'));
assertEquals(SeatStatus.UNRESERVED, plane.getSeatStatus(2, 'D'));