0

源代码:

public class ReportGenerator implements Serializable {

    private static final long serialVersionUID = -3995091296520157208L;
    @Inject
    private ReportCacheSession reportCacheSession;
    @Inject
    private UserSessionBean userSessionBean;
    @Inject
    private Instance<ReportBuilder> reportBuilderInstance;

    public static final int BUILD_ERROR = 0;
    public static final int BUILD_OK = 1;
    public static final int BUILD_NOPAGES = 2;

    private ReportBuilder reportBuilder = null;

    private FileData build(String jasperName, Map<String, Object> params, String extension, boolean guardarCache, boolean inline) {
        FileData fd = null;

        reportBuilder = reportBuilderInstance.get();
        if (reportBuilder != null) {
            reportBuilder.jasperName = jasperName;
            reportBuilder.emailName = SevUtils.getEmailName(userSessionBean.getUserInfo().getEmail());
            reportBuilder.sessionId = JSFUtils.getSessionId();
            reportBuilder.params = params;
            reportBuilder.extension = extension;
            //reportBuilder.config(jasperName, SevUtils.getEmailName(userSessionBean.getUserInfo().getEmail()), JSFUtils.getSessionId(), params, extension);
            reportBuilder.start();

            try {
                reportBuilder.join();
            } catch (InterruptedException ex) {
                Logger.getLogger(ReportGenerator.class.getName()).log(Level.SEVERE, null, ex);
            }

            fd = reportBuilder.getFileData();
        }

        if (fd != null && fd.getState() == BUILD_OK) {
            fd.setInline(inline);

            if (guardarCache) {
                reportCacheSession.addReport(fd);
            }
        }

        return fd;
    }
}

reportBuilder.start(); 是生成报告的新线程,问题是当行 reportCacheSession.addReport(fd); 被称为CDI每次创建一个新实例,但ReportCacheSession是一个会话bean,用javax.inject.Named和javax.enterprise.context.SessionScoped注解。

我不知道为什么会发生这种情况,但我的解决方案是添加一个新行,如下所示:

FileData fd = null;
reportCacheSession.toString(); //NEW LINE
reportBuilder = reportBuilderInstance.get();

reportCacheSession.toString(); 在调用我的线程之前创建 ReportCacheSession 的实例并且一切正常...

新线程对 CDI 有何影响?为什么 CDI 在我之前调用线程时创建了我的会话 bean 的新实例?

2012 年 8 月 15 日更新:

好的,我已更改我的代码以使用 EJB 注释 @Asynchronous,在这种情况下,当我生成大型 PDF 报告(XLS 报告工作没有问题)时,文件大小不完整(更少字节)和何时出现问题我尝试打开它,它显示为空白...可能是 JRExporter#exportReport 方法的问题/错误...

最后更新:

好的,报告生成是我的错误......问题是哪种替代方案最好使用 EJB 异步或 JMS?感谢所有人,每条评论都让我找到了一个好的解决方案......

4

0 回答 0