Session 在带有RequestScope的ManagedBean中使用有状态EJB时出现问题

Session 在带有RequestScope的ManagedBean中使用有状态EJB时出现问题,session,jsf-2,ejb-3.1,Session,Jsf 2,Ejb 3.1,我在GlassFishV3应用服务器中使用JSF2.0和EJB3.1。我实际上面临着以下问题: 在带有RequestScope的MenagedBean中,我想访问一个会话对象(一个带有@Stateful的EJB),它应该存储一些会话相关信息,如seleced类别、seleced页面(每个类别都有一个datatable分页器)等等。我想没有什么特别的。 第一次选择类别时,将创建并显示datatable。好的,到目前为止。 现在,如果单击一个项目(行)以显示该项目的详细信息,或者如果应该显示下一个页

我在GlassFishV3应用服务器中使用JSF2.0和EJB3.1。我实际上面临着以下问题:
在带有RequestScope的MenagedBean中,我想访问一个会话对象(一个带有@Stateful的EJB),它应该存储一些会话相关信息,如seleced类别、seleced页面(每个类别都有一个datatable分页器)等等。我想没有什么特别的。
第一次选择类别时,将创建并显示datatable。好的,到目前为止。 现在,如果单击一个项目(行)以显示该项目的详细信息,或者如果应该显示下一个页面,则会重新创建会话(有状态EJB),并再次使用默认值来显示和呈现该页面

代码如下所示:

@ManagedBean
@RequestScoped
public class TableViewBean {

    @EJB
    SessionBean session;

    public DataModel getTable() {
            return session.getDataModel();
         }

        public SessionBean getSession(){
            return session;
        }
         public void next() {
             session.getPaginator().nextPage();
             session.resetList();
         }

         public void previous() {
                session.getPaginator().previousPage();
                session.resetList();
         }
         // some other code
    }
和会话EJB:

@Stateful
public class SessionBean {

private String selectedType = "Entity";

private DataModel dataModel;
private int rowsPerPage = 5;
private Paginator paginator;


public void setSelectedType(String type){
    if(!type.equalsIgnoreCase(selectedType)){
        selectedType = type;

        updateService();
    }
    resetList();
}


public void resetList() {
    dataModel = null;
}

public void resetPagination() {
    paginator = null;
}

public int getRowsPerPage() {
    return rowsPerPage;
}

public void setRowsPerPage(int rowsPerPage) {
    this.rowsPerPage = rowsPerPage;
    resetList();
    resetPagination();
}

public Paginator getPaginator() {
    if (paginator == null) {
        paginator = new Paginator(rowsPerPage) {

            @Override
            public int getItemsCount() {
                return selectedService.getCount();
            }

            @Override
            public DataModel createPageDataModel() {
                DataModel model = null;
                if(selectedService != null){
                    model = new ListDataModel(....);
                }
                return model;
            }
        };
    }

    return paginator;

}

public DataModel getDataModel() {
    if(dataModel == null){
        dataModel = getPaginator().createPageDataModel();
    }

    return dataModel;
}
}

如果我将ManagedBean的作用域更改为SessionScope,那么一切都可以正常工作,但我不喜欢这样,因为这会占用内存

我的代码有什么问题…请帮帮我


Greetz,Gerry

您的RequestScoped ManagedBean将为每个请求重新实例化(这毕竟是RequestScoped的意思)。因此,每次实例化都会注入一个新的SFSB实例。

好的,但是我如何管理我的需求,以使用requestScope Managedbean作为backingbean,并拥有一个会话长EJB来维护所有与会话相关的内容,并可在不同的backingbean中使用?为什么请求范围管理bean又是一个需求?因为内存问题?但是您的托管bean只持有对有状态bean的引用(如果您想将该bean作为有状态bean使用,这是必需的)。您的内存问题(如果有的话)可以指有状态bean本身,而不是真正的轻量级托管bean;但是,您需要以某种方式将SFSB存储在HttpSession中,然后在托管bean的getTable()方法中查找它,而不是将其作为实例字段注入。由于SFSB实例“与特定的客户端关联”,如果您的客户端(托管bean)丢失,而另一个客户端代替它进行下一个请求,新版本没有任何与之关联的SFSB(直到注入新版本)。因此,SFSB确实维护state和all,但是客户机不能保存多个请求以使用它。你需要将你的bean与一个能够活得更长的客户关联起来。我明白了!我误解了“客户”这个词。我想到了一个像webbrowser之类的客户机。我没有想到ManagedBean可以是有状态bean的客户机。谢谢!