Настройка информации о пользовательских версиях с помощью Hibernate Envers в OpenLiberty - PullRequest
0 голосов
/ 13 июня 2019

Мы переносим приложение из JEE7 в JEE8.Это приложение использует Hibernate-ORM и Hibernate-Envers.На JEE7 это была версия 5.2.17, на JEE8 сейчас 5.4.3 для обеих библиотек.У нас есть пользовательская версия ревизии, которая расширяет DefaultRevisionEntity путем добавления пользовательской информации посредством реализации RevisionListener.На JEE7 он прекрасно работает на OpenLiberty 19.0.0.5, для JEE8 и Hibernate 5.4.3 мы получаем ошибки.В JEE8 и Hibernate 5.4.3 теперь можно использовать функциональность CDI в ревизионистах.( Установка даты редакции вручную с помощью Hibernate Envers ).В OpenLiberty инициализация revisionlistener каким-то образом выполняется, когда ни один менеджер bean-компонентов не готов к использованию, как это показывает трассировка стека:

Caused by: java.lang.IllegalStateException: org.hibernate.resource.beans.container.internal.NotYetReadyException: CDI BeanManager not (yet) ready to use
[INFO]  at org.hibernate.resource.beans.container.internal.JpaCompliantLifecycleStrategy$BeanImpl.initialize(JpaCompliantLifecycleStrategy.java:112)
[INFO]  at org.hibernate.resource.beans.container.internal.CdiBeanContainerExtendedAccessImpl$BeanImpl.initialize(CdiBeanContainerExtendedAccessImpl.java:113)
[INFO]  at org.hibernate.resource.beans.container.internal.CdiBeanContainerExtendedAccessImpl$BeanImpl.getBeanInstance(CdiBeanContainerExtendedAccessImpl.java:119)
[INFO]  at org.hibernate.resource.beans.internal.ManagedBeanRegistryImpl$ContainedBeanManagedBeanAdapter.getBeanInstance(ManagedBeanRegistryImpl.java:139)
[INFO]  at org.hibernate.envers.internal.revisioninfo.DefaultRevisionInfoGenerator.generate(DefaultRevisionInfoGenerator.java:77)
[INFO]  at org.hibernate.envers.internal.synchronization.AuditProcess.getCurrentRevisionData(AuditProcess.java:133)
[INFO]  at org.hibernate.envers.internal.synchronization.AuditProcess.executeInSession(AuditProcess.java:115)
[INFO]  at org.hibernate.envers.internal.synchronization.AuditProcess.doBeforeTransactionCompletion(AuditProcess.java:174)
[INFO]  at org.hibernate.envers.internal.synchronization.AuditProcessManager$1.doBeforeTransactionCompletion(AuditProcessManager.java:47)
[INFO]  at org.hibernate.engine.spi.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:954)
[INFO]  ... 20 more
[INFO] Caused by: org.hibernate.resource.beans.container.internal.NotYetReadyException: CDI BeanManager not (yet) ready to use
[INFO]  ... 31 more
[INFO] Caused by: java.lang.NullPointerException
[INFO]  at org.hibernate.resource.beans.container.internal.JpaCompliantLifecycleStrategy$BeanImpl.initialize(JpaCompliantLifecycleStrategy.java:109)
[INFO]  ... 29 more

Я нашел этот https://discourse.hibernate.org/t/beanmanager-createinstance-being-called-before-afterbeandiscovery-event-fired/2239 диалог, который может указывать нав том же направлении.

На самом деле это наши функции, установленные в server.xml.

<featureManager>
    <feature>jaxrs-2.1</feature> 
    <feature>jsonp-1.1</feature>
    <feature>cdi-2.0</feature>
    <feature>jpaContainer-2.2</feature>
    <feature>ejbLite-3.2</feature>
    <feature>mpMetrics-1.1</feature>
    <feature>mpHealth-1.0</feature>
    <feature>mpConfig-1.3</feature>
    <feature>servlet-4.0</feature>
</featureManager>

Если вам нужна дополнительная информация, я предоставлю их.Это известная проблема ?Буду признателен за подсказку или решение этой проблемы.

Большое спасибо.

1 Ответ

1 голос
/ 14 июня 2019

Да, из ответов, которые я получил от Hibernate и IBM, это кажется известной проблемой, и, как я уже упоминал на форуме, я смог разработать обходной путь для решения этой проблемы под руководством очень полезной команды Hibernate. .

Обходной путь должен был реализовать org.hibernate.search.hcore.spi.EnvironmentSynchronizer для контроля, когда инициализация JPA может безопасно продолжаться, и javax.enterprise.inject.spi.Extension, чтобы определить, когда CDI имеет BeanManager готов.

Я регистрирую свою реализацию EnvironmentSynchronizer с org.hibernate.service.spi.ServiceContributor интерфейсом. Внутри EnvironmentSynchronizer метод события whenEnvironmentReady передает значение Runnable, которое представляет задачу, отвечающую за инициализацию JPA. Это нужно отложить до тех пор, пока CDI не завершит обнаружение компонента, и BeanManager будет готов.

Моя реализация расширения CDI ожидает метод события AfterBeanDiscovery, который является подходящим временем для успешного продолжения отложенной задачи инициализации JPA.

После того, как мой обходной путь был на месте, я начал взаимодействовать с IBM Support, чтобы повысить осведомленность о проблеме совместимости и посмотреть, можно ли встроить этот детализированный элемент управления инициализацией Hibernate в WebSphere Liberty в будущем выпуске. IBM указала, что они хотели бы, чтобы Hibernate работал из коробки с WebSphere, что является фантастическим, поэтому я надеюсь, что мы увидим полную поддержку последней версии Hibernate в WebSphere Liberty в ближайшем будущем.

Обновление: Я только что подтвердил, что, к сожалению, наша реализация EnvironmentSynchronizer не откладывает инициализацию Envers. Инициализация Envers все еще дает сбой при запуске в WebSphere с нашим обходным решением.

Я обновлю наш случай с IBM, включив в него Envers, и добавлю примечание в ветку форума Hibernate, чтобы узнать, есть ли какие-либо доступные варианты.

Обновление: Вот решение, которое я протестировал с Hibernate Envers и пользовательским RevisionListener. Добавление этого файла в файл persistence.xml позволит успешно запустить WebSphere:

<property name="hibernate.delay_cdi_access" value="true"/>

Комментарии от Стива Эберсоле:

Этот параметр (2), по сути, указывает Hibernate отложить доступ к BeanManager до тех пор, пока он сначала не потребуется, во время выполнения. Другими словами, когда вы в первый раз выполняете операцию, для которой нужен определенный компонент CDI, Hibernate запросит об этом BeanManager. Это имеет серьезный недостаток в том, что если бин не существует, вы не узнаете об этом до времени выполнения, возможно, через несколько месяцев после развертывания.

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

...