Использовать можно стандартный
AttributeConverter из JPA. Что-то типа такого:
public class ShippingAddressConverter implements AttributeConverter<ShippingAddressData, String> {
private final ObjectMapper objectMapper = new ObjectMapper();
private final JavaType shippingAddressType =
this.objectMapper.getTypeFactory().constructSimpleType(ShippingAddressData.class, null);
@Override
public String convertToDatabaseColumn(ShippingAddressData attribute) {
if (attribute == null) {
return null;
}
try {
return this.objectMapper.writeValueAsString(attribute);
} catch (JsonProcessingException e) {
throw new PersistenceException("Failed to serialize shipping address", e);
}
}
@Override
public ShippingAddressData convertToEntityAttribute(String dbData) {
if (dbData == null) {
return new ShippingAddressData();
}
try {
return this.objectMapper.readValue(dbData, shippingAddressType);
} catch (IOException e) {
throw new PersistenceException("Failed to deserialize shipping address", e);
}
}
}
и в
Entity объявить поле:
@Column(name = "shipping_address")
@Convert(converter = ShippingAddressConverter.class)
private ShippingAddressData shippingAddress;
Тут, правда, есть одна засада: PostgreSQL по умолчанию не приводит строки к типу json или jsonb (или только к jsonb?). Так что проще всего объявить в БД правила приведения типов:
CREATE CAST (varchar AS jsonb) WITH INOUT AS IMPLICIT;
CREATE CAST (text AS jsonb) WITH INOUT AS IMPLICIT;
Объявлять приведение и к varchar и к text пришлось, потому что Hibernate иногда зачем-то явно указывает типы данных, подставляя параметры SQL-запросов. И какой это тип будет (text или varchar) зависит только от Hibernate. Так что, на всякий случай, объявляю оба.