Классы-значения имеют свой набор полей и при встраивании в класс-сущность каждому такому полю будет создана колонка соответствующего типа, например, VARCHAR для полей типа String, BIGINT для полей типа Long.
Типы создаваемых колонок можно поменять с помощью конвертеров не только для полей класса-сущности, но и для полей встраиваемых классов.
Создадим базовое веб-приложения на связке Spring Boot 3 + Hibernate + PostgreSQL
Убедитесь, что файле /src/main/resources/application.properties есть следующая строка, позволяющая Hibernate’у автоматически создавать (и обновлять) схему БД при запуске приложения на основании аннотаций в классах предметной области:
1 |
spring.jpa.hibernate.ddl-auto=update |
Создадим встраиваемый класс-значение:
1 2 3 4 5 6 7 8 9 10 11 |
@Embeddable public class Address { @Column(length = 100) private String city; private String street; private Integer houseNumber; //Конструкторы, геттеры и сеттеры, equals(), hashCode() и т.д. } |
Создадим конвертер:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Converter public class HouseNumberToStringConverter implements AttributeConverter<Integer, String> { @Override public String convertToDatabaseColumn(Integer houseNumber) { return String.valueOf(houseNumber); } @Override public Integer convertToEntityAttribute(String dbData) { return Integer.valueOf(dbData); } } |
В нашем встраиваемом классе поле houseNumber имеет тип Integer. Мы бы хотели, чтобы это поле преобразовывалось в String при сохранении в базу и обратно из String в Integer при вычитке данных из БД. Чтобы в БД для хранения номера дома использовалась колонка типа VARCHAR.
Создадим класс-сущность:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@Entity public class Person { @Id @GeneratedValue private Long id; private String name; @Convert( converter = HouseNumberToStringConverter.class, attributeName = "houseNumber" ) private Address homeAddress; //Конструкторы, геттеры и сеттеры, equals(), hashCode() и т.д. } |
Мы помечаем поле Address homeAddress аннотацией @Convert, в которую параметром converter передаём класс конвертера, который будет применяться к полю, указанному в параметре attributeName, в нашем случае к полю houseNumber. Таким образом мы указали Hibernate’у при создании схемы создать для поля houseNumber колонку типа VARCHAR, так как HouseNumberToStringConverter конвертирует данные в String и обратно, а для String создаётся колонка типа VARCHAR. А также запускать конвертер при каждом сохранении и вычитке данных.
Чтобы убедится, что HIbernate создал для поля Integer houseNumber колонку типа VARCHAR достаточно просто запустить приложение и посмотреть схему данных в консоли psql:
В консоли видно, что для поля Integer houseNumber создана колонка HOUSE_NUMBER типа VARCHAR. Теперь в Java коде мы сможем оперировать этими данными как Integer’ами, а в БД они будут храниться в виде строк.