Raphael H
Raphael H

Reputation: 69

CDI Bean member loses value during request

I have years of experience developing JSF applications, but this is a confusing bug, which is driving me insane. I think I need a fresh pair of eyes to find the possible error.

First off, the details about the environment:

Now about the Problem/Bug itself. In Phase 4 of the JSF-Lifecycle, the Update model values phase, somehow a member object inside my CDI-Bean returns null. When the values in the models are updated, a PropertyNotFoundException is thrown. The confusing part is, I use virtually the same boilerplate code for all my projects, this is the first time I encounter that problem. To make it even more confusing, I have three entities and only one of them is updated correctly.

XHTML-Snippet:

<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)" />

Controller-Snippet:

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;
    }

As mentioned, in Phase 4 of the JSF Lifecycle, the project entity somehow loses its value. And I get the rather infamous exception

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

For testing I put prints inside the PostConstruct and the respective getter of the project inside the controller. This is the output from loading the page to after I trigger the save-Button:

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!

It is simple crud-code, no real magic involved, I've done it a thousand times and now this happens. I double-checked the imports everywhere, cleaned all temp-data, tested it on various Server Versions, tested all CDI-Scopes, compared the xhtml- and controller-files with diffs, etc. I have done all the steps that usually fix bugs like that or give me a hint towards the solution. Nothing. It boggles my mind that it works for one entity, while the others throw the error. This inconsistent behaviour makes it even harder for me find the bug, when the wiring of xhtml and controller is basically the same for all entities.

I am at the end of my knowledge on this one. Maybe my eyes just don't find the cause after so many hours, but it seems perfectly fine to me. Has anyone of you encountered that before?

If you need more information, I'll be happy to provide them. I appreciate any hint and thank you for your help.

Upvotes: 2

Views: 127

Answers (1)

Raphael H
Raphael H

Reputation: 69

With the hint of BalusC I tracked down the error.

Somehow a PrimeFaces Datatable way up on the page triggered its selection with null in the same request, overriding the entity. I don't know why it would be doing that without an actual selection, but with adding explicit processing of the inputfields the error vanished. The entity that had no problem, had no DataTable in its XHTML, which would explain why the behaviour was inconsistent, with the same controller-code.

This makes me feel really stupid, but with that final hint of introspecting the setter, which I should have done in the first place, I found the error.

Thank you BalusC, thank you Stackoverflow!

Upvotes: 1

Related Questions