JSF - CDI再次实例化会话bean

时间:2012-08-13 22:55:12

标签: multithreading jsf ejb cdi

源代码:

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是一个使用javax.inject.Named和javax.enterprise.context.SessionScoped注释的会话bean。

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

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

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

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

更新08/15/12:

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

最后更新:

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

0 个答案:

没有答案