gpt4 book ai didi

java - 在 OpenLiberty 上使用 Hibernate Envers 设置自定义修订信息

转载 作者:行者123 更新时间:2023-12-02 09:46:53 28 4
gpt4 key购买 nike

我们正在将应用程序从 JEE7 迁移到 JEE8。该应用程序依赖于 Hibernate-ORM 和 Hibernate-Envers。在 JEE7 上,版本为 5.2.17,在 JEE8 上,两个自由库现在版本为 5.4.3。我们有一个自定义修订实体,它通过 RevisionListener 的实现添加用户信息来扩展 DefaultRevisionEntity。在 JEE7 上,它在 OpenLiberty 19.0.0.5 上运行良好,对于 JEE8 和 Hibernate 5.4.3,我们遇到错误。在 JEE8 和 Hibernate 5.4.3 上,现在可以在修订监听器中使用 CDI 功能。 (Setting the revision date manually with Hibernate Envers)。在 OpenLiberty 上,当没有 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>

如果您需要更多信息,我会提供。这是一个已知问题吗?如果您能为这个问题提供提示或解决方案,我将不胜感激。

非常感谢。

最佳答案

是的,从我从 Hibernate 和 IBM 收到的回复来看,这似乎确实是一个已知问题,正如我在论坛中提到的,我能够在非常乐于助人的 Hibernate 团队的指导下开发该问题的解决方法.

解决方法是实现org.hibernate.search.hcore.spi.EnvironmentSynchronizer来控制JPA初始化何时可以安全地继续,以及javax.enterprise.inject.spi.Extension code> 以便检测 CDI 何时准备好 BeanManager

我使用org.hibernate.service.spi.ServiceContributor接口(interface)注册了EnvironmentSynchronizer的实现。在EnvironmentSynchronizer 内部,whenEnvironmentReady 事件方法传入一个Runnable,它表示负责JPA 初始化的任务。这需要推迟到 CDI 完成 Bean 发现并且 BeanManager 准备就绪为止。

我的 CDI 扩展实现等待 AfterBeanDiscovery 事件方法,这是允许之前推迟的 JPA 初始化任务成功继续的正确时间。

制定好解决方法后,我开始与 IBM 支持人员沟通,以提高对兼容性问题的认识,并了解这种对 Hibernate 初始化的细粒度控制是否可以在未来版本中内置到 WebSphere Liberty 中。 IBM 表示他们希望 Hibernate 能够与 WebSphere 一起工作,这太棒了,所以我希望在不久的将来我们能在 WebSphere Liberty 中看到对最新版本 Hibernate 的全面支持。

更新:不幸的是,我刚刚确认,我们的 EnvironmentSynchronizer 实现不会推迟 Envers 初始化。使用我们的解决方法,Envers 初始化在 WebSphere 中启动时仍然会崩溃。

我将更新我们与 IBM 的案例,将 Envers 纳入其中,并在 Hibernate 论坛的帖子中添加注释,以查看是否有任何立即可用的选项。

更新:这是我使用 Hibernate Envers 和自定义 RevisionListener 测试过的解决方案。将其添加到 persistence.xml 将允许 WebSphere 成功启动:

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

史蒂夫·埃伯 Solr 的评论:

This option (2) essentially tells Hibernate to delay accessing the BeanManager until it first needs to which is during runtime. In other words, the first time you perform an operation that needs a particular CDI bean Hibernate will ask the BeanManager for it. This has a serious downside in that if the bean does not exist you will not know about that until runtime, conceivably months after a deployment.

我们可能会在短期内使用此选项,并打算在 IBM WebSphere 完全支持开箱即用的最新版本 Hibernate 后将其删除。

关于java - 在 OpenLiberty 上使用 Hibernate Envers 设置自定义修订信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56583092/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com