Установка даты ревизии вручную с помощью Hibernate Envers - PullRequest
0 голосов
/ 26 апреля 2019

Насколько я знаю, Hibernate Envers сохраняет ревизию при создании, изменении или удалении объекта, помеченного @Audited.

Envers автоматически устанавливает дату ревизии в текущее время. Можно ли установить это время вручную?

Мне нужно это для обработки временной коллекции, где данные имеют правильное время, которое мне нужно было бы установить вручную.

1 Ответ

1 голос
/ 26 апреля 2019

Можно, но на первый взгляд это может показаться не интуитивным.

Когда Envers создает свой экземпляр объекта ревизии, происходит несколько вещей.

  1. Аннотированное свойство @RevisionTimestamp устанавливается с текущим временем.
  2. Необязательный RevisionListener вызывается и предоставляет экземпляр объекта правки.

Вы можете указать RevisionListener двумя способами, и это действительно зависит от того, разрешается ли в настоящее время предоставление пользовательского экземпляра объекта ревизии или использования экземпляра Envers на основе вашей настройки.

Поставка пользовательской редакции

В этой ситуации вы можете указать RevisionListener, установив его в аннотации класса @RevisionEntity для класса сущности.

@RevisionEntity(YourCustomRevisionListener.class)
public class CustomRevisionEntity {
  ...
}

Поставка RevisionListener через конфигурацию

В этой ситуации вам понадобится добавить дополнительное свойство конфигурации начальной загрузки для Hibernate, либо через файл hibernate.properties, либо в коде, где вы явно задаете свойства конфигурации hibernate:

org.hibernate.envers.revision_listener=com.company.envers.YourCustomRevisionListener

Независимо от того, какой подход вы используете, вы затем реализуете контракт слушателя и явно устанавливаете значение метки времени на основе любых правил, которые нужны вашему приложению:

public class YourCustomRevisionListener implements RevisionListener {
  @Override
  public void newRevision(Object revisionEntity) {
    // I am going to assume here you're using a custom revision entity.
    // If you are not, you'll need to cast it to the appropriate class implementation.
    final CustomRevisionEntity revisionEntityImpl = (CustomRevisionEntity) revisionEntity;
    revisionEntityImpl.setTimestamp( resolveValidTimestampValue() );
  }

  private long resolveValidTimestampValue() {
    // implement your logic here.
  }
}

Здесь есть пара предостережений. Если вам нужно разрешить значение из какого-либо bean-компонента в пространстве приложения, вам необходимо определить, какое из следующего применимо к вам:

Использование версии Hibernate Envers до версии 5.3

В этом случае вам придется использовать устаревший подход к переменным ThreadLocal для передачи экземпляров / значений области приложения для доступа к тем, которые находятся внутри слушателя.

Использование Hibernate Envers 5.3 или более поздней версии с CDI

В этом случае вы можете просто внедрить bean-компонент CDI, используя инъекцию CDI, так как мы добавили поддержку автоматического разрешения bean-компонентов CDI при создании экземпляра слушателя.

Использование Hibernate Envers 5.3 или более поздней версии с Spring 5.1 +

Вы можете внедрять Spring Bean непосредственно в слушателя, используя аннотации Spring, как слушатель был Spring-bean.

Использование Hibernate Envers 5.3 или новее с Spring до 5.1

В этом случае вам нужно будет использовать устаревший подход к переменным ThreadLocal, поскольку Spring Framework не добавляла поддержку для внедрения bean-компонентов в bean-компоненты Hibernate до версии 5.1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...