为什么JSF会将在支持bean中成功实例化的嵌套类置空?

为什么JSF会将在支持bean中成功实例化的嵌套类置空?,jsf,primefaces,Jsf,Primefaces,为了清晰(和简洁),我只列出了代码的关键部分 我有一个支持bean MemberView,其中包含两个嵌套类: private Person person; private Member member; 在页面加载时实例化的: @PostConstruct public void init() { person = new Person(); member = new Member(); } 使用适当的getter和setter。我有一个网页member.xhtml,它利用P

为了清晰(和简洁),我只列出了代码的关键部分

我有一个支持bean MemberView,其中包含两个嵌套类:

private Person person;
private Member member;
在页面加载时实例化的:

@PostConstruct
public void init() {
    person = new Person();
    member = new Member();
}
使用适当的getter和setter。我有一个网页member.xhtml,它利用PrimeFaces并显示嵌套类属性:

<p:inputText value="#{memberView.person.lastName}" />
<p:inputText value="#{memberView.member.id}" />
这是我单击
命令按钮时的输出:

INFO: getMember() invoked
INFO: getMember() returning Member: scc.model.Member@6f453701 with ID: null
INFO: getMember() invoked
INFO: getMember() returning Member: scc.model.Member@6f453701 with ID: null
INFO: getMember() invoked
INFO: getMember() returning Member: scc.model.Member@6f453701 with ID: null
INFO: setMember() invoked with argument: null
INFO: getMember() invoked
WARNING: getMember() returning NULL
显然,该类成员正在被清除。还有一个细节。如果我注释掉成员ID输入字段

<!-- <p:inputText value="#{memberView.member.id}" /> -->

然后选择Retrieve按钮,页面用嵌套的MemberView Person类提供的成员名称和名称字段填充dataTable:

<p:dataTable id="dtPerson" var="member"
            style="margin-top:10px;text-align:center;width:400px;minWidth:400px"
                     value="#{memberView.selectableMemberList}"
                     selectionMode="single" editable="false"
                     selection="#{memberView.member}" >

<p:inputText value="#{memberView.person.lastName}" />


在成功返回实例化类的三次调用之后,我完全无法解释使用null参数对setMember方法的EL调用。我愿意接受任何建议。

感谢你们两位及时而有益的回复。根据BalusC的建议,跟踪显示方法类在DataTable.processUpdates期间为空。由于没有行数据,因此在表中找不到成员,PrimeFaces SelectableDataModel返回null,然后由JSF方法BeanELResolver.setValue设置

我以前的数据库都使用多对一关系,其中ArrayList在后期构造时填充,并且根据设计,此后从不为空。这里一个可能的解决方案是在页面加载时填充数据表,正如BalusC在2006年的文章中所建议的(“您可以在[backing]bean的构造函数或初始化块中加载数据列表。”)

一种更通用的解决方案是,在初始化时以及查询返回空结果集时,为数据表提供一个空白而非空的数据列表:

/**
* Member edited/displayed in web page text fields 
*/
private Member member;

/**
 * List of Member Objects
 */ 
private List<Member> mList;

/**
 *  Member List implementing PF SelectableDataModel
 */
private SelectableMemberList selectableMemberList;

/**
 * Creates a blank [not empty] SelectableMemberList.
 * Call on PostConstruct & on return of empty result set.
 */
private void blankSelectableMemberList() {
    if(mList == null) {         // instantiate on init()
        mList = new ArrayList<>();
    }
    if(mList.isEmpty()) {       // add blank Object
        mList.add(new Member());
    }
selectableMemberList = new SelectableMemberList(mList);
}
/**
*在网页文本字段中编辑/显示的成员
*/
私人会员;
/**
*成员对象列表
*/ 
私人名单;
/**
*实现PF SelectableDataModel的成员列表
*/
私有SelectableMemberList SelectableMemberList;
/**
*创建一个空白[非空]SelectableMemberList。
*在构造后&返回空结果集时调用。
*/
私有void blankSelectableMemberList(){
如果(mList==null){//在init()上实例化
mList=新的ArrayList();
}
如果(mList.isEmpty()){//添加空白对象
mList.add(新成员());
}
selectableMemberList=新的selectableMemberList(mList);
}

我希望这对任何想显示“空”数据表的人都有帮助。

您在同一属性上设置了
。这是有意的吗?如果未选择任何内容或提供的选择与datatable中的任何记录都不匹配,则后果不言而喻。这是否意味着datatable会将memberView.member设置为null,即使未进行任何选择且未触发任何选择事件?我的选择侦听器记录所有此类事件。我还有很多其他网页,其中dataTable selection设置为clazzView.clazz,同一表单上的inputText字段设置为clazzView.clazz.variable,这些工作正常。所以要回答你的问题,是的,这是故意的。我可以理解一个类变量被设置为null,但不能理解类本身。是的,因为datatable无法知道您如何处理“空/新/初始化”成员对象。空值更显式。在jsf“提交周期”的不同阶段调用getter,请参阅。你可以围绕你的经历工作,但这将是一个。。。变通办法。如果在同一提交中处理dataTable,最好不要使用与BalusC statedIt相同的属性。您可以通过查看XHR负载或在setter中设置断点并检查调用它的调用堆栈以及调用原因来确认这一点。这是一个“复杂”的解决方法。最好看看如何使用
commdButton
上的
process
属性来限制不“处理”数据表选择。复杂性是一个视角问题。我对基于Java的解决方案很满意,因为我理解它,并且发现它很容易实现,而链接中包含的信息很难解读。另外,我更喜欢在代码中保留空检查,而不是将它与视图(MVC)混合在一起。此外,这可能只是反映了我自己的局限性,我不知道如何将数据表的处理限制为查询是否返回空结果集(如果可行)。最后,空值对程序员来说是一种诅咒,我更喜欢把它们排除在我的代码之外。如果我发布的链接中的信息很难解读,我担心你会遇到许多相关的问题,(部分)在解决方法中修复它们,最后“责怪”JSF太复杂。。。最好是真正理解链接中的信息。这很重要!我从来没有说过要在视图中执行空检查。。。
<p:dataTable id="dtPerson" var="member"
            style="margin-top:10px;text-align:center;width:400px;minWidth:400px"
                     value="#{memberView.selectableMemberList}"
                     selectionMode="single" editable="false"
                     selection="#{memberView.member}" >

<p:inputText value="#{memberView.person.lastName}" />
/**
* Member edited/displayed in web page text fields 
*/
private Member member;

/**
 * List of Member Objects
 */ 
private List<Member> mList;

/**
 *  Member List implementing PF SelectableDataModel
 */
private SelectableMemberList selectableMemberList;

/**
 * Creates a blank [not empty] SelectableMemberList.
 * Call on PostConstruct & on return of empty result set.
 */
private void blankSelectableMemberList() {
    if(mList == null) {         // instantiate on init()
        mList = new ArrayList<>();
    }
    if(mList.isEmpty()) {       // add blank Object
        mList.add(new Member());
    }
selectableMemberList = new SelectableMemberList(mList);
}