Hibernate Envers — очень старый проект. Так получилось, что всякие вещи вроде аудировнаия изменений, мне приходилось выполнять триггерами на уровне БД с подхимичиванием переменных сессий и Envers обходил меня сторной.
Выглядит проект неплохо и легко встраивается в spring-boot приложение.
Все зависимости уже включены в BOM и достаточно только включить модуль в проект, спринг сам возьмет нужную версию.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
</dependency>
После подключения я добавил аннотацию @Audited своему классу, для которого мне нужно было хранить ревизиии. А также AuditingEntityListener чтобы доставать из контекста безопасности Spring данные об авторизации: мне нужно знать кто менял карточку.
Envers, являясь модулем, представляет механизм в котором вы сами должны описать откуда береде данные об авторизации.
@Audited
@EntityListeners(AuditingEntityListener.class)
@NamedEntityGraphs({
@NamedEntityGraph(
name = "cardWithLog",
attributeNodes = {
@NamedAttributeNode("ccLog")
}
)
})
public class Card implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "f_name")
private String fName;
@Column(name = "reg_doc_date")
private LocalDate regDocDate;
}
Генератор схемы Hibernate я стараюсь не использовать, были у меня моменты когда я продуктивную базу дропал, думаю что у всех они были, поэтому использую Liquibase. Я счастливо скопировл табличку, была “card” стала “card_aud” и при первом же старте получил проблемы.
Исторически всегда настороженно даю оценку, когда нужно подключать стороннюю открытую библиотеку с которой у меня не было большого опыта работы. Дело в том что в opensource проектах есть баги, которые очень не спешат исправлять, они конечно есть в bug report и на StackOverflow это записано как “known bug”.
Я вот эти “known bug” очень не люблю. С одной стороны мы заплатили целых 0 рублей за библиотеку, а с другой обидно когда комментарий вот такой.
For 4.3 there is a work-around as stated above by using a Type rather than a AttributeConverter
То есть вроде как вместо аннотации @Converter мы можем объявить custom type и все у нас заработает, но с другой надо понимать, как применяется Type. Если вы его добавите через @Type для своего поля даже написав конвертер, Envers как было на него все равно так и будет.
То есть от @Converter(autoApply = true) придется отказаться, в версии 4.3 Envers не умеет с ним работать и будет кидать вам org.hibernate.MappingException для не стандартных типов.
@Converter(autoApply = true)
public static class LocalDateConverter implements AttributeConverter<LocalDate, java.sql.Date> {
@Override
public java.sql.Date convertToDatabaseColumn(LocalDate date) {
return date == null ? null : java.sql.Date.valueOf(date);
}
@Override
public LocalDate convertToEntityAttribute(java.sql.Date date) {
return date == null ? null : date.toLocalDate();
}
}
Как починить напишу в продолжении статьи про Envers.