【问题标题】:CDI Bean member loses value during requestCDI Bean 成员在请求期间失去价值
【发布时间】:2015-08-05 11:20:30
【问题描述】:

我有多年开发 JSF 应用程序的经验,但这是一个令人困惑的错误,让我发疯。我想我需要一双新的眼睛来发现可能的错误。

首先,关于环境的细节:

  • JDK:8u40
  • 服务器:WildFly 8.2.0.Final
  • 库:CDI 1.2、JSF 2.2、OmniFaces 2.0、PrimeFaces 5.2、Hibernate、JPA 2.1
  • IDE:Eclipse Juno

现在关于问题/错误本身。在 JSF 生命周期的第 4 阶段,即更新模型值阶段,我的 CDI-Bean 中的成员对象以某种方式返回 null。当模型中的值更新时,会引发 PropertyNotFoundException。令人困惑的是,我对所有项目都使用几乎相同的样板代码,这是我第一次遇到这个问题。更令人困惑的是,我有三个实体,其中只有一个被正确更新。

XHTML 片段:

<p:inputText id="name" value="#{projectController.project.name}"
    required="true">
    <f:validateLength minimum="2" />
</p:inputText>
<p:commandButton icon="fa-save" action="#{projectController.save}"
    value="Save" update="@(.ui-datatable) @(.ui-inputfield)" />

控制器片段:

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;

import com.deadknight.web.resumee.model.entity.dao.ProjectDao;
import com.deadknight.web.resumee.model.entity.impl.Project;
import com.deadknight.web.resumee.utils.PrimefacesUtils;

@Named
@ViewScoped
public class ProjectController extends BaseController {

    private static final long serialVersionUID = 2352991211048821234L;

    @Inject
    ProjectDao dao;

    private List<Project> allProjects;
    private Project project, selectedProject;

    @PostConstruct
    public void init() {
        allProjects = dao.listAll();
        System.out.println("Constructing project inside Post-Construct now");
        project = new Project();
    }

    public void save() {
        if (project.isTransient()) {
            dao.create(project);
        } else {
            dao.update(project);
        }
        allProjects.add(project);
        project = new Project();
    }

    public Project getProject() {
        if (project == null)
            System.out.println("Bloody thing is null!");
        else
            System.out.println("Not null yet");
        return project;
    }

    public void setProject(Project project) {
        this.project = project;
    }

如前所述,在 JSF 生命周期的第 4 阶段,项目实体不知何故失去了它的价值。我得到了一个相当臭名昭著的例外

Caused by: javax.el.PropertyNotFoundException: /administration/project.xhtml @54,26 value="#{projectController.project.name}": Target Unreachable, 'null' returned null

为了进行测试,我将打印件放入 PostConstruct 中,并将项目的相应 getter 放入控制器中。这是我触发保存按钮后加载页面到的输出:

15:51:08,394 INFO  [stdout] (default task-17) Constructing project inside Post-Construct now
15:51:08,394 INFO  [stdout] (default task-17) Not null yet
...
//Button is submitting the POST now
15:51:18,421 INFO  [stdout] (default task-20) Not null yet
15:51:18,423 INFO  [stdout] (default task-20) Not null yet
15:51:18,423 INFO  [stdout] (default task-20) Not null yet
15:51:18,424 INFO  [stdout] (default task-20) Not null yet
...
15:51:18,426 INFO  [stdout] (default task-20) Bloody thing is null!
15:51:18,426 INFO  [stdout] (default task-20) Bloody thing is null!
15:51:18,427 INFO  [stdout] (default task-20) Bloody thing is null!
15:51:18,427 INFO  [stdout] (default task-20) Bloody thing is null!

这是简单的粗略代码,没有真正的魔法,我已经做了一千次,现在发生了。我仔细检查了所有地方的导入,清理了所有临时数据,在各种服务器版本上对其进行了测试,测试了所有 CDI 范围,将 xhtml 和控制器文件与差异等进行了比较。我已经完成了通常修复错误的所有步骤像那样或给我一个解决方案的提示。没有。令人难以置信的是,它适用于一个实体,而其他实体则抛出错误。当所有实体的 xhtml 和控制器的接线基本相同时,这种不一致的行为使我更难找到错误。

我在这方面的知识已经走到了尽头。也许我的眼睛在这么多小时后找不到原因,但对我来说似乎完全没问题。你们有没有人遇到过这种情况?

如果您需要更多信息,我很乐意提供。 感谢您的任何提示,并感谢您的帮助。

【问题讨论】:

  • 我看到你有一个设置器(这在这个构造中实际上是不必要的,JSF 永远不会在嵌套的 bean/实体上调用设置器)。在其上放置一个调试断点并检查它是否以null作为值调用,如果是,则在调用堆栈中查找负责人。

标签: jsf-2 primefaces cdi


【解决方案1】:

在 BalusC 的提示下,我找到了错误。

页面上的 PrimeFaces 数据表以某种方式在同一请求中触发了它的选择,并覆盖了实体。我不知道为什么它会在没有实际选择的情况下这样做,但是通过添加对输入字段的显式处理,错误消失了。 没有问题的实体在其 XHTML 中没有 DataTable,这可以解释为什么行为不一致,使用相同的控制器代码。

这让我觉得自己真的很愚蠢,但是在最后提示我应该首先检查 setter 时,我发现了错误。

谢谢 BalusC,谢谢 Stackoverflow!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 2015-08-12
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多