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

Тип МАССИВА HSQLDB в режиме гибернации

Реализация типа Hibernate для поддержки МАССИВА HSQLDB довольно проста. В этой статье вы узнаете, как сопоставлять как строковые [], так и целочисленные[] массивы при использовании Hibernate и HSQLDB.

Автор оригинала: Vlad Mihalcea.

Как ранее объяснялось , хотя Hibernate по умолчанию не поддерживает типы столбцов массива базы данных, вы можете легко реализовать пользовательский тип Hibernate ArrayType . В то время как предыдущее решение работало на PostgreSQL, в этой статье вы увидите, что его довольно легко адаптировать к HSQLDB.

Как реализовать пользовательский #Hibernate Тип массива. @vlad_mihalcea https://t.co/HJGv5uz7zY pic.twitter.com/xTVPbING1C

Предполагая, что в нашей системе есть следующее Событие сущность:

Нам нужен способ сохранить атрибуты String[] и Integer[] entity, поскольку Hibernate по умолчанию не поддерживает типы массивов, зависящие от базы данных.

Для этого мы будем использовать два пользовательских типа гибернации:

@Entity(name = "Event")
@Table(name = "event")
@TypeDefs({
    @TypeDef(
        name = "string-array", 
        typeClass = VarCharStringArrayType.class
    ),
    @TypeDef(
        name = "int-array", 
        typeClass = IntArrayType.class
    ),
})
public class Event {

    @Id
    private Long id;

    @Type(type = "string-array")
    @Column(
        name = "sensor_names", 
        columnDefinition = "VARCHAR(100) ARRAY"
    )
    private String[] sensorNames;

    @Type(type = "int-array")
    @Column(
        name = "sensor_values", 
        columnDefinition = "INT ARRAY"
    )
    private Integer[] sensorValues;

    //Getters and setters omitted for brevity
}

Код для Строкового типа массива и Типа IntArrayType был описан ранее в этой статье поэтому мы не будем повторять его здесь.

Единственное отличие заключается в том, что мы используем Тип массива строк VarChar сейчас, поскольку HSQLDB не поддерживает тип столбца TEXT базы данных:

public class VarCharStringArrayType
        extends StringArrayType {

    public static final VarCharStringArrayType INSTANCE = 
        new VarCharStringArrayType();

    public VarCharStringArrayType() {
        super(
            VarCharStringArrayTypeDescriptor.INSTANCE
        );
    }
}

Также дескриптор типа массива строк VarChar тоже довольно тривиален:

public class VarCharStringArrayTypeDescriptor
        extends StringArrayTypeDescriptor {

    public static final VarCharStringArrayTypeDescriptor INSTANCE = 
            new VarCharStringArrayTypeDescriptor();

    @Override
    public String getSqlArrayType() {
        return "varchar";
    }
}

И, вот оно что!

Вам не нужно создавать все эти типы вручную. Вы можете просто получить их через Maven Central, используя следующую зависимость:


    com.vladmihalcea
    hibernate-types-55
    ${hibernate-types.version}

Для получения дополнительной информации ознакомьтесь с проектом с открытым исходным кодом типа hibernate .

При сохранении двух Событий сущностей:

Event nullEvent = new Event();
nullEvent.setId(0L);

entityManager.persist(nullEvent);

Event event = new Event();
event.setId(1L);
event.setSensorNames(
    new String[]{"Temperature", "Pressure"}
);
event.setSensorValues(
    new Integer[]{12, 756}
);

entityManager.persist(event);

Hibernate выполнит следующие инструкции SQL INSERT:

INSERT INTO event (
    sensor_names, 
    sensor_values, 
    id
) 
VALUES (
    NULL(ARRAY), 
    NULL(ARRAY), 
    0
)

INSERT INTO event (
    sensor_names, 
    sensor_values, 
    id
) 
VALUES (
    ARRAY['Temperature','Pressure'], 
    ARRAY[12,756], 
    1
)

При извлечении объекта Событие :

Event event = entityManager.find(Event.class, 1L);

assertArrayEquals(new String[]{"Temperature", "Pressure"}, event.getSensorNames());
assertArrayEquals(new Integer[]{12, 756}, event.getSensorValues());

Hibernate может правильно сопоставить базовый тип столбца МАССИВА с массивами String[] и Integer[] Java.

Вы также можете использовать JPQL для фильтрации результатов на основе заданного массива Java:

Event event = entityManager
.createQuery(
    "select e " +
    "from Event e " +
    "where e.sensorNames = :sensorNames", Event.class)
.setParameter
    "sensorNames", 
    new String[]{"Temperature", "Pressure"}
)
.getSingleResult();

Как показано в этой статье, сопоставление типов столбцов МАССИВА с массивами Java String[] или Integer довольно просто при использовании Hibernate.