В предыдущей статье рассказывал про баг HHH-9042 с которым пришлось столкнуться.
В этой статье я расскажу как у меня получилось выйти из ситуации.
Не секрет, что с появлением JPA многие вещи, которые раньше делали с использованием Hibernate стало делать сложнее. Spring всячески прячет от нас реализацию EntityProvider и добраться что до сессии, что до SessionFactory не всегда поулчается красиво.
Для приведения стандартных типов Hibernate использует аннотацию @Type. В пакете org.hibernate.type лежат стандартные для Hibernate типы данных.
Для типа данных, который помещается в одной колонке достаточно org.hibernate.type.AbstractSingleColumnStandardBasicType.
Реализацию LocalDateType я взял из 5 версии Hibernate, она легко ищется как наследник org.hibernate.type.Type
Дескриптор взял оттуда же hibernate-orm
Дальше начинается интересный момент с подключением. Чтобы Hibernate начал узнавать Custom Type нужно или воспользоваться аннотацией @Type или достать где-нибудь при инициализации org.hibernate.cfg.Configuration и вызвать у него configuration.registerTypeOverride(LocalDateType.INSTANCE);
Аннотация @Type не поможет. Envers для управления ревизиями использует свои entity-объекты, поэтому на @Type на поле класса @Card результата не даст, я пробовал.
Остается класс конфигурации. И вот тут проблема, так как JPA для инициализации Hibernate используют класс HibernateJpaAutoConfiguration, выключать ее и использовать LocalSessionFactoryBean себе в итоге дороже, осбенно если у вас разные профили и диалекты и ваша конфигурация и так вас устраивает.
Я нашел рещение в механизме Service Provider
Сделал реализацию класса org.hibernate.integrator.spi.Integrator
Создал файл в ресурсах (src/main/resources) с названием org.hibernate.integrator.spi.Integrator, содержимое файла:
ru.inetwork.config.hibernate.CustomUserTypesIntegrator
После такой реализации Hibernate начал воспринимать LocalDate как базовый тип и конверторы для него больше не нужны, а Envers стартует без проблем.
Если конверторы удалять не хочется можно только в аудируемом классе дописать аннотацию @Convert(disableConversion = true) тогда и конвертор можно оставить.