Java 关于如何组合CDIBeans的疑问:SessionScoped和RequestScoped

Java 关于如何组合CDIBeans的疑问:SessionScoped和RequestScoped,java,session,jakarta-ee,jsf-2,java-ee-6,Java,Session,Jakarta Ee,Jsf 2,Java Ee 6,我的目标是展示一个具有创建、检索和更新功能的jsf页面。 我决定为每个操作创建不同的CDIBean和不同的复合组件,然后将它们放在页面中 到目前为止还不错,但我刚刚完成,发现了一个非常令人困惑的bug,我不知道如何修复它: 执行创建操作的CDIBean工具是一个@RequestScoped bean,因此输入字段在请求后会自行清理。(参见下图) 我对它一点问题都没有(只是那个警告我无法摆脱),它工作得很好 我创建的下一个小工具是一个也可以编辑数据的数据表。为此,我需要使用@SessionSco

我的目标是展示一个具有创建、检索和更新功能的jsf页面。 我决定为每个操作创建不同的CDIBean和不同的复合组件,然后将它们放在页面中

到目前为止还不错,但我刚刚完成,发现了一个非常令人困惑的bug,我不知道如何修复它:

执行创建操作的CDIBean工具是一个@RequestScoped bean,因此输入字段在请求后会自行清理。(参见下图)

我对它一点问题都没有(只是那个警告我无法摆脱),它工作得很好

我创建的下一个小工具是一个也可以编辑数据的数据表。为此,我需要使用@SessionScopped CDIBean(见下图)

问题来了: 当呈现页面时,@SessionScoped bean会缓存会话中的数据,但是当使用@RequestScoped bean插入新数据时,数据会进入数据库,但datatable不会显示新输入的值,因为它们不在会话中

那我该怎么办? 在这里,我将向您展示两个bean:

创建BEAN

@Named("subjectControllerCreate")
@RequestScoped
public class SubjectControllerCreate implements Serializable {

    private Subject currentSubject;
    @EJB
    private SubjectFacade ejbFacade;

    //INITIALIZATION
    public SubjectControllerCreate() {
        currentSubject = new Subject();
    }


    //CREATE


       public String create() {
            try {         
                    currentSubject.setCreationDate(new Date());
                    getSubjectFacade().create(currentSubject);//Adds the current subject to the database!
                    JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SubjectCreated"));
                    return "";//Can perform a redirect here if we want
                //}
                //return null;
            } catch (Exception e) {
                JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                return null;
            }
        }
@Named("subjectControllerUpdate")
@SessionScoped
public class SubjectControllerUpdate implements Serializable {

    //Using DataModel<Subject> instead of List<Subject> is necessary in order to be able to get the current row.
    private DataModel<Subject> subjects;    
    @EJB
    private SubjectFacade ejbFacade;

    //INITIALIZATION   
    @PostConstruct
    public void init() {
       subjects = new ListDataModel<Subject>(getSubjectFacade().findAll());
    }

    //RETRIEVE
    public DataModel<Subject> retrieve() {
        return subjects;
    }

    //UPDATE
    public void update() {
        getSubjectFacade().edit(subjects.getRowData());
    }

    //HELP METHODS
    //RETURN THE FACADE FOR DATA MANIPULATION(Best practice)
    private SubjectFacade getSubjectFacade() {
        return ejbFacade;
    }

    //GETTERS AND SETTERS
    public DataModel<Subject> getSubjects() {
        return subjects;
    }

    public void setSubjects(DataModel<Subject> subjects) {
        this.subjects = subjects;
    }        
}
更新BEAN

@Named("subjectControllerCreate")
@RequestScoped
public class SubjectControllerCreate implements Serializable {

    private Subject currentSubject;
    @EJB
    private SubjectFacade ejbFacade;

    //INITIALIZATION
    public SubjectControllerCreate() {
        currentSubject = new Subject();
    }


    //CREATE


       public String create() {
            try {         
                    currentSubject.setCreationDate(new Date());
                    getSubjectFacade().create(currentSubject);//Adds the current subject to the database!
                    JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SubjectCreated"));
                    return "";//Can perform a redirect here if we want
                //}
                //return null;
            } catch (Exception e) {
                JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                return null;
            }
        }
@Named("subjectControllerUpdate")
@SessionScoped
public class SubjectControllerUpdate implements Serializable {

    //Using DataModel<Subject> instead of List<Subject> is necessary in order to be able to get the current row.
    private DataModel<Subject> subjects;    
    @EJB
    private SubjectFacade ejbFacade;

    //INITIALIZATION   
    @PostConstruct
    public void init() {
       subjects = new ListDataModel<Subject>(getSubjectFacade().findAll());
    }

    //RETRIEVE
    public DataModel<Subject> retrieve() {
        return subjects;
    }

    //UPDATE
    public void update() {
        getSubjectFacade().edit(subjects.getRowData());
    }

    //HELP METHODS
    //RETURN THE FACADE FOR DATA MANIPULATION(Best practice)
    private SubjectFacade getSubjectFacade() {
        return ejbFacade;
    }

    //GETTERS AND SETTERS
    public DataModel<Subject> getSubjects() {
        return subjects;
    }

    public void setSubjects(DataModel<Subject> subjects) {
        this.subjects = subjects;
    }        
}
@Named(“subjectControllerUpdate”)
@会议范围
公共类SubjectControllerUpdate实现可序列化{
//为了能够获取当前行,需要使用DataModel而不是List。
私有数据模型主体;
@EJB
私人主体;
//初始化
@施工后
公共void init(){
主题=新的ListDataModel(getSubjectFacade().findAll());
}
//取回
公共数据模型检索(){
返回主题;
}
//更新
公共无效更新(){
getSubjectFacade().edit(subjects.getRowData());
}
//帮助方法
//返回用于数据操作的外观(最佳实践)
私有SubjectFacade getSubjectFacade(){
返回ejbFacade;
}
//接球手和接球手
公共数据模型getSubjects(){
返回主题;
}
公共void集合主题(数据模型主题){
这个。主题=主题;
}        
}
当检测到Create对话框关闭时,是否可以让数据表发送一些ajax请求,以获取新输入的其余数据? 如果是,我怎么做

这是我的数据表的标记:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core">

    <h:form>
        <p:dataTable id="allSubjects" var="subject" value="#{subjectControllerUpdate.subjects}" paginator="true" rows="7" >
            <p:ajax event="rowEdit" listener="#{subjectControllerUpdate.update()}"/>
            <p:column headerText="Name" sortBy="#{subject.name}" style="width:200px" >
                <p:cellEditor>  
                    <f:facet name="output">  
                        <h:outputText value="#{subject.name}"/>  
                    </f:facet>  
                    <f:facet name="input">  
                        <p:inputText value="#{subject.name}" style="width:100%"/>  
                    </f:facet>  
                </p:cellEditor>  
            </p:column>

            <p:column sortBy="#{subject.description}" headerText="Description">               
                <p:cellEditor>  
                    <f:facet name="output">  
                        <h:outputText value="#{subject.description}"/>  
                    </f:facet>  
                    <f:facet name="input">  
                        <p:inputText value="#{subject.description}" style="width:100%"/>  
                    </f:facet>  
                </p:cellEditor>    
            </p:column>

            <p:column sortBy="#{subject.credits}" headerText="Credits" style="width:50px">
                <p:cellEditor>  
                    <f:facet name="output">  
                        <h:outputText value="#{subject.credits}"/>  
                    </f:facet>  
                    <f:facet name="input">  
                        <p:inputText value="#{subject.credits}" style="width:100%"/>  
                    </f:facet>  
                </p:cellEditor>
            </p:column>

            <p:column headerText="Options" style="width:50px">                   
                <p:rowEditor />
            </p:column>         
        </p:dataTable>
    </h:form>    

</html>


非常感谢您的帮助

您能不能将
@SessionScoped
bean注入
@RequestScoped
bean中,当单击create时,调用
@SessionScoped
bean中的方法刷新?

是的,这听起来是最简单、最好的选择。现在可以用了,谢谢!