Идеальный ответ на ваш вопрос зависит от версий как Hibernate, так и Spring Framework, которые вы используете в настоящее время, поскольку некоторые новые функции, добавленные в более поздних версиях, облегчают получение инжекции состояния приложения в обратный вызов RevisionListener
.
Использование Hibernate 5.2 или более ранней версии
Если вы используете Hibernate 5.2 или более раннюю версию, вы будете ограничены унаследованным подходом внедрения состояния приложения с использованием ThreadLocal
переменных. В веб-приложении это легко сделать, настроив веб-фильтр или сделав его частью своего веб-контроллера.
Цель состоит в том, чтобы инициализировать ThreadLocal
перед вызовом любой бизнес-службы / компонента, выполняющей операцию постоянства, и очищать состояние после того, как операция сохранения была зафиксирована. Так как большинство приложений на основе пружин имеют тенденцию заключать метод обслуживания в аннотацию @Transactional
, тогда обработка инициализации и очистки ThreadLocal
в контроллере кажется логичной.
Поскольку ThreadLocal
- это глобальная переменная, которая ограничена исполняющим потоком, слушатель сможет запросить у локального экземпляра потока значение, чтобы установить его в настраиваемой сущности ревизии. Самое главное - установить его до запуска операции сохранения и очистить после сохранения.
Использование Hibernate 5.3+ в среде CDI
Скорее всего, это не относится к вам, поскольку вы находитесь в среде Spring, но для полноты всех возможных вариантов конфигурации я включаю его.
Если вы используете Hibernate 5.3 или более позднюю версию в среде на основе CDI, Hibernate добавил поддержку по умолчанию для внедрения CDI, в основном позволяя определенным объектам, созданным Hibernate, фактически становиться бобами CDI и поддерживать добавление состояния в них. Другими словами
public class CustomRevisionListener implements RevisionListener {
@Inject
private UserReasonBean reasonBean;
@Override
public void newRevision(Object revisionEntity) {
// inside this method, you can get the reason from the injected reasonBean
// and now set the reason on the custom revision entity instance.
}
}
Использование Hibernate 5.3+, но с версией Spring 5.0 или более ранней
Чтобы заставить внедрение бина Spring Framework работать, вы должны использовать Spring Framework 5.1 или более позднюю версию, где они добавили эту поддержку, в противном случае при использовании Spring Framework 5.0 или более ранней версии с Hibernate необходимо использовать устаревший подход с ThreadLocal
переменные.
См. Использование Hibernate 5.2 или более ранней версии
Использование Hibernate 5.3+ с Spring 5.1 +
Если вы используете Hibernate 5.3 или новее с Spring Framework 5.1 или новее, то вам повезло. В этом случае вы можете автоматически имитировать поддержку CDI по умолчанию, поскольку Spring Framework 5.1 предоставляет собственную реализацию реестра компонентов и автоматически связывает ее с платформой Hibernate. Короче говоря, это означает, что вы можете легко автоматически подключать компоненты Spring в RevisionListener
так же, как если бы вы использовали CDI.
public class CustomRevisionListener implements RevisionListener {
@Autowired
private UserReasonBean reasonBean;
@Override
public void newRevision(Object revisionEntity) {
// inside this method, you can get the reason from the injected reasonBean
// and now set the reason on the custom revision entity instance.
}
}