1

I'm using JavaEE to build a very simple Java full stack app, so I'm using JSF with Prime Faces 6.2 to render an xthml in the frontend and EJB, JPA with Hibernate and postgresql in the backend, however, When I set rowKey="#{person.id}" from a dataTable component from Prime Faces. Next exception is thrown.

"00:13:36,307 ERROR [io.undertow.request] (default task-55) UT005023: Exception handling request to /javaee-app/faces/listPersons.xhtml: javax.servlet.ServletException ... Caused by:java.lang.NullPointerException"

listPersons.xhtml
Prime Faces DataTable Component(opening tag and its attributes)

<p:dataTable id="persons"
                 value="#{personBean.persons}"
                 var="person"
                 editable="true"
                 rowKey="#{person.id}"
                 selection="#{personBean.personSelected}"
                 selectionMode="single">

The exception thrown that appears when trying to render the page is this. enter image description here

However, if I set rowKey="#{person.name}" or even rowKey="#{person.email}" in stead of rowKey="#{person.id}" the problem disappears and xthml page is rendered correctly.

<p:dataTable id="persons"
             value="#{personBean.persons}"
             var="person"
             editable="true"
             rowKey="#{person.name}"
             selection="#{personBean.personSelected}"
             selectionMode="single">

with rowKey="#{person.name}" or rowKey="#{person.email}" xhtml page is rendered correctly"

Postgresql Database person

MODEL/ENTITY

@Entity
@Table(name = "person")
@NamedQueries({
@NamedQuery(name = "Person.findAll", query = "SELECT p FROM Person p"), 
@NamedQuery(name = "Person.findById", query = "SELECT p FROM Person p 
WHERE p.id = :id")
, @NamedQuery(name = "Person.findByName", query = "SELECT p FROM 
Person p WHERE p.name = :person_name")
, @NamedQuery(name = "Person.findByLastname", query = "SELECT p FROM 
Person p WHERE p.lastname = :lastname")
, @NamedQuery(name = "Person.findByEmail", query = "SELECT p 
FROM Person p WHERE p.email = :email")
, @NamedQuery(name = "Person.findByPhone", query = "SELECT p 
FROM Person p WHERE p.phone = :phone")})
public class Person implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@Basic(optional = false)
@NotNull
@Size(min = 1, max = 60)
@Column(name = "person_name")
private String name;

@Basic(optional = false)
@NotNull
@Size(min = 1, max = 60)
private String lastname;

@Basic(optional = false)
@NotNull
@Size(min = 1, max = 60)
private String email;

@Size(max = 60)
private String phone;

@OneToMany(mappedBy = "person", fetch = FetchType.EAGER)
private List<Users> users;

public Person() { }

public Person(Integer id) {
    this.id = id;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getLastname() {
    return lastname;
}

public void setLastname(String lastname) {
    this.lastname = lastname;
}


public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getPhone() {
    return phone;
}

public void setPhone(String phone) {
    this.phone = phone;
}

public List<Users> getUsers() {
    return users;
}

public void setUsers(List<Users> users) {
    this.users = users;
}

@Override
public int hashCode() {
    int hash = 0;
    hash += (id != null ? id.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    if (!(object instanceof Person)) {
        return false;
    }
    Person other = (Person) object;
    if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "Person [id = " + id + ", name=" + name
            + ", lastName=" + lastname + " email=" + email + ", phone=" + phone + "]";
}

Any idea to solve this problem guys? Thanks in advance

I'm also adding the images of the errors generated in the application server, in my case Wildfly 8.2

picture1 Wildfly 8.2

picture2 Wildfly 8.2

webtechnelson
  • 330
  • 1
  • 7
  • 13
  • How is the person entity populated? I see 5 constructors, one without the id parameter. Are you sure that’s not used to construct the entity? Why do you need so many anyway? – kTest Jun 21 '18 at 23:47
  • How did you populate the list? The error `Caused by:java.lang.NullPointerException` says that _at least_ one person has a null ID. By default JPA calls the empty constructor which happens to leave the ID to `null`. Maybe at one moment in your backing you add a new Person (not persisted yet in the database) to the list and this Person happens to have a null ID? – Al-un Jun 22 '18 at 07:12
  • @kTest thanks for your interest, I removed unnecessary constructors, however, problem still happens, about the empty constructor, it is necessary, since it's the default constructor. – webtechnelson Jun 22 '18 at 10:24
  • @Al1 Thanks to you too, what you say makes sense, however, the dataTable is not rendered at all. if you check the Entity it is populated from a Table named person, I added a screenshot with the current content of the table. When the xhtml is going to be rendered it brings the persons that are in the database, so it should work correctly, something is missing but I 'm just not getting it yet. – webtechnelson Jun 22 '18 at 10:24
  • can you please provide the whole stacktrace? – Simon Martinelli Jun 22 '18 at 11:38
  • @SimonMartinelli I have added the stackTrace and the errors from the application server Wildfly 8.2. Thanks for your time. – webtechnelson Jun 22 '18 at 11:54
  • 2
    Can you change getId() to return Integer instead of int? – Simon Martinelli Jun 22 '18 at 12:09
  • @SimonMartinelli oh yes Sir. you got to the bug. in front of my eyes. thanks a lot for your time, it is solved. – webtechnelson Jun 22 '18 at 12:36

1 Answers1

3

The id is of type Integer:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

Where as the getter returns int:

public int getId() {
    return id;
}

Change getId to return Integer.

Simon Martinelli
  • 34,053
  • 5
  • 48
  • 82
  • Thanks for your time, I've changed the type, issue solved. – webtechnelson Jun 22 '18 at 12:43
  • Nice finding Simon! For further development, it is worth to mention that this `NullPointerException` is the same as it in [this question](https://stackoverflow.com/q/46601104/4906586). These guys will answer you better than me regarding primitive type unboxing – Al-un Jun 25 '18 at 06:24