当前位置: 首页 > 知识库问答 >
问题:

@Singleton bean无法初始化,因为不是预期的事务状态

司寇山
2023-03-14

我有一个场景,我需要在应用程序启动时加载一个 bean (ReportManager),以便它可以安排报告执行(由 DataStore bean 从数据库轮询)。

在谷歌上搜索后,我发现了@单件、@启动和@依赖的注释,我是这样使用的:

@Singleton
@Startup
@DependsOn("DataStore")
public class ReportManager {
    @EJB
    DataStore dataStore;

    @PostConstruct
    public void scheduleReports() {
       logger.log("INITIALIZED");
       List<Report> reports = dataStore.getReports();
       ....
    }
}

@Singleton
@RolesAllowed("user") //I had security checks implemented like that beforehand
public class DataStore {
    @PostConstruct
    public void initialize() {
        logger.log("INITIALIZED");
    }

    public List<Report> getReports() {
        ...
    }
}

问题是我在部署期间遇到了非常奇怪的异常:

<2012-09-27 14:04:15 CEST> <Warning> <Deployer> <BEA-149004> <Failures were detected while initiating deploy task for application "app".>
<2012-09-27 14:04:15 CEST> <Warning> <Deployer> <BEA-149078> <Stack trace for message 149004
weblogic.application.ModuleException: Exception starting module: EJBModule(app-ejb-1.0-SNAPSHOT.jar)

Unable to deploy EJB: ReportManager from app-ejb-1.0-SNAPSHOT.jar:

Singleton ReportManager(Application: app, EJBComponent: app-ejb-1.0-SNAPSHOT.jar) failed to initialize.

   at weblogic.ejb.container.deployer.EJBModule.start(EJBModule.java:592)
 .....

Caused By: weblogic.ejb.container.InternalException: Transaction marked rollback or not expected transaction status: 1
   at weblogic.ejb.container.manager.SingletonSessionManager.postCallback(SingletonSessionManager.java:464)

不是真正的异常消息。特别是我也没有收到任何“初始化”日志条目。当我注释掉dataStore.getReports()调用时,一切正常,并且bean以正确的顺序构建(生成了“初始化”消息)。包括数据存储方法调用导致上述错误,并以某种方式抑制所有日志输出。

我正在使用Weblogic 12c。

共有2个答案

况安然
2023-03-14

就我而言,我使用的是 SpringLoader.java 类,它是一个加载 Spring 配置的@Singleton。Spring 配置了 Quartz 调度程序,该调度程序正在尝试访问其数据库表(作为某些事务的一部分)。

因此,在我的例子中,它帮助向SpringLoader类添加了以下行:@TransactionManagement(TransactionManagementType.BEAN)

之后,将显示一些更有意义的错误消息:ORA-00942:表或视图不存在。

顺便说一句:也值得添加这一行:@ConcurrencyManagement(ConcurrencyManagementType.BEAN)

杜焕
2023-03-14

最后,我弄清楚了导致错误的原因。它是@RolesAllowed声明,由于安全上下文为空而阻塞方法调用,在 Bean 中执行时未@PostConstruct方法中设置@Startup(来自 EJB 3.1 规范,第 4.3.4 章:PostConstruct 生命周期回调拦截器方法在未指定的安全上下文中执行)。

使其工作所需的只是向调用的方法添加@PermitAll

@PermitAll
public List<Report> getReports() {
   ...
}

错误是如此错误,我决定把这个案例放在这里,因为我无法谷歌答案。

 类似资料:
  • 上面的代码没有给我任何错误,即一切都是整洁的编写和导入等。但当我尝试初始化时,如下所示: 我得到以下错误: 这里的问题是什么?

  • 我的EJB3.1 bean初始化有困难,更具体地说,由于感知到的事务回滚而失败,即使我已经用标记了bean。这应该意味着任何客户端事务都在bean方法条目上暂停,直到退出(当它将被恢复时。这绝对是我想要的事务apprach。 代码和错误的“要点”如下(注意,其中一些是手摇的,以隐藏细节,但都是相关的和有代表性的): 这会引发以下错误: 当我调试时,实际上包装了以下异常: 同样,调试引发了一些有趣的

  • 当通过hadoop作业在ES上编写时,它会因日志而冻结,原因是:bought by:java.lang.noClassDefFoundError:无法初始化类,这可能是什么原因? RemoteTransportException[[未能反序列化类型[org.ellasticsearch.action.admin.cluster.node.liveness.livenessResponse]]];嵌

  • 问题内容: 在Tensorflow /Keras中,从https://github.com/pierluigiferrari/ssd_keras运行代码时,请使用估算器:ssd300_evaluation。我收到此错误。 无法获得卷积算法。这可能是因为cuDNN无法初始化,所以请尝试查看上面是否打印了警告日志消息。 我正在运行的问题: 的Python:3.6.4。 Tensorflow版本:1.1

  • 我有一个EJB无状态会话Bean。我有以下要求: 这个无状态EJB应该在启动时初始化 初始化代码应该对数据库进行事务性访问 问题是: @Startup仅适用于@Singleton EJB @PostConstruct注释(至少在WebSphere上)在这一点上没有事务性上下文,所以初始化代码在这里爆炸! 可能的解决方案? 使用JavaEE定时器,但它似乎是为周期性执行而设计的。我只想在零点执行一次

  • 我正在开发我的第一个 Swing 应用程序,现在提出了一个难题:在静态初始化期间或开始实际执行后执行引导和资源初始化。我是什么意思...我有单例: 因此,方法如下所示 或者,也许我在启动后手动初始化资源,然后运行它。逻辑上正确的方式是什么?