@Singleton bean由于未预期的事务状态而无法初始化

时间:2012-09-27 12:37:12

标签: java-ee transactions weblogic

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

在谷歌上搜索我发现@Singleton,@ Startup和@DependsOn注释,我用过这样的话:

@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)

不是真正的异常异常消息。特别是我也没有得到任何“INITIALIZED”日志条目。当我注释掉dataStore.getReports()调用时,一切正常,并且bean按正确顺序构造(生成了“INITIALIZED”消息)。包括dataStore方法调用导致上面的错误,并以某种方式压制所有日志输出。

我正在使用Weblogic 12c。

2 个答案:

答案 0 :(得分:4)

最后我弄清楚导致错误的原因。由于空安全上下文而导致阻塞方法调用的是@RolesAllowed声明,在@PostConstruct bean中执行时未在@Startup方法中设置(来自EJB 3.1 spec, ch. 4.3.4:PostConstruct生命周期callback interceptor方法在未指定的安全上下文中执行。)。

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

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

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

答案 1 :(得分:1)

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

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

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

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