0

Hello everyone I'm very new to javaweb and I tried to create my first javaweb project, off course by following some tutorial. However when some action were being invoke I received an error. Does anyone can help! Here is what I did:

Person.java

package org.javaeesample.entities;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person implements Serializable {
    @Id @GeneratedValue
    private Long id;

    private String name;
    private int age;

    public Person(){        
    }

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

PersonEjbDao.java

package org.javaeesample.ejbdao;

import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.javaeesample.entities.Person;

@Stateless
public class PersonEjbDao {
    @PersistenceContext
    EntityManager em;
    //private Person pers;
    public List<Person> listPerson(){
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Person> cq = cb.createQuery(Person.class);
        Root<Person> person = cq.from(Person.class);
        cq.select(person);
        return em.createQuery(cq).getResultList();
     }

    public Person findPerson(long pid){
        return em.find(Person.class, pid);
    }

    public void createPerson(Person pers){
        Person p = new Person();
        p.setName(pers.getName());
        p.setAge(pers.getAge());
        em.persist(p);
    }
}

FriendBean.java

package org.javaeesample.jsf;

import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.javaeesample.ejbdao.PersonEjbDao;
import org.javaeesample.entities.Person;

@Named(value = "personBean")
@RequestScoped
public class PersonBean {
    private Person person;
    private Long pid;
    private List<Person> listPerson;
    @Inject
    PersonEjbDao personDao;

    public List<Person> getPersons(){
        if (listPerson==null) {
            listPerson = personDao.listPerson();
        }
        return listPerson;
    }

    public void personDetails(){
        person = new Person();
        person = (Person) personDao.findPerson(pid);
    }

    public void createPerson(){
        personDao.createPerson(person);
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public Long getPid() {
        return pid;
    }

    public void setPid(Long pid) {
        this.pid = pid;
    }

}

show.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <body>

        <ui:composition template="./WEB-INF/template.xhtml">

            <ui:define name="content">
                <h:form>
                <h:dataTable value="#{personBean.persons}" var="p">
                    <h:column>
                        <f:facet name="header">Name</f:facet>
                        <h:link value="#{p.name}" outcome="details">
                            <f:param name="pid" value="#{p.id}"/>
                        </h:link>
                    </h:column>

                    <h:column>
                        <f:facet name="header">Age</f:facet>
                        #{p.age}
                    </h:column>
                </h:dataTable>

                <h:commandButton id="create" action="create" value="Create"/>
                </h:form>
            </ui:define>

        </ui:composition>

    </body>
</html>

create.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <body>

        <ui:composition template="./WEB-INF/template.xhtml">

            <ui:define name="content">
                <h:form>
                    <h:panelGrid columns="3"
                             captionClass="rightalign,leftalign,leftalign">
                        <h:outputLabel value="Name:" for="name"/>
                        <h:inputText id="name" label="Name"
                                 required="true"
                                 value="#{personBean.person.name}"/>
                        <h:message for="name"/>
                        <h:outputLabel value="Age:" for="age"/>
                        <h:inputText id="age" label="Age"
                                 size="2"
                                 value="#{personBean.person.age}"/>
                        <h:message for="age"/>
                        <h:commandButton id="save" value="Save"
                                     action="list" actionListener="#{personBean.createPerson}"/>
                    </h:panelGrid>
                </h:form>
            </ui:define>
        </ui:composition>

    </body>
</html>

details.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <body>

        <ui:composition template="./WEB-INF/template.xhtml">
            <ui:define name="content">
                <f:metadata>
                    <f:viewParam name="pid" value="#{personBean.pid}"/>
                    <f:event type="javax.faces.event.PreRenderComponentEvent" listener="#{personBean.personDetails()}"/>
                </f:metadata>

                <h:form>
                    <h:panelGrid columns="2"
                             columnClasses="rightalign,leftalign,leftalign">
                        <h:outputText value="Name:"/>
                        <h:outputText value="#{personBean.person.name}" />
                        <h:outputText value="Age:"/>
                        <h:outputText value="#{personBean.person.age}"/>
                    </h:panelGrid>
                </h:form>
            </ui:define>
        </ui:composition>

    </body>
</html>  

When tried to run my project what happened were:
1. When i clicked the link from show.xhtml

<h:link value="#{p.name}" outcome="details">
    <f:param name="pid" value="#{p.id}"/> 
</h:link>  

it says: java.lang.NullPointerException

java.lang.NullPointerException  
    at org.javaeesample.jsf.PersonBean.personDetails(PersonBean.java:37)  
    at org.javaeesample.jsf.PersonBean$Proxy$_$$_WeldClientProxy.personDetails(Unknown Source)  
    ...  

but on the url it shows:
http://localhost:8080/javaeesample/faces/details.xhtml?pid=1

  1. When i clicked 'Save' button in create.xhtml here is the error i received:

An Error Occurred:

/create.xhtml @18,73 value="#{personBean.person.name}": Target Unreachable,'null' returned null  

I expand Stack Trace and it displayed

javax.el.PropertyNotFoundException: /create.xhtml @18,73 value="#{personBean.person.name}": Target Unreachable, 'null' returned null  
    at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:95)

I don't know what makes my personBean.person.name null.

Any help is very much appreciated.

Tiny
  • 27,221
  • 105
  • 339
  • 599
Anirudh Lou
  • 781
  • 2
  • 10
  • 28
  • Thanks sir for the answer but is it necessary to do @PostConstruct and where should i put that annotation? What about my create.xhtml what causes the error? – Anirudh Lou Apr 04 '15 at 11:00

1 Answers1

0

Since Tiny doesn't seem to want to write an answer, I'll do it. Base for this answer is partly his comment which reads:

Target Unreachable,'null' returned null : Either #{personBean.person} or #{personBean} is null. I smell person is null. You are trying to pre-populate person inside the personDetails(). Why do you initialize person using <f:event type="javax.faces.event.PreRenderComponentEvent" listener="#{personBean.personDetails()}"/>? You had better pre-populate private Person person; (and private List<Person> listPerson; which you are lazily initializing inside a getter method unnecessarily) at a better initialization place - inside a method annotated with @PostConstruct.

Now a little more explanation on that

javax.el.PropertyNotFoundException: /create.xhtml @18,73 value="#{personBean.person.name}": 
    Target Unreachable, 'null' returned null

this error means: "Either #{personBean.person} or #{personBean} is null (see above). I am completely with Tiny on the assumption that person is the culprit.

The underlying cause for this is, that at the time the listener you use to initialize Person runs, the xhtml file is already completely parsed. Before your listener has the chance to change person the attributes of it should have already been accessed.

This leads to your error. A fix for this is rather simple:

Don't let person ever be null. Use eager initialization where you can to prevent this and make your PersonBean look as follows:

@RequestScoped
public class PersonBean {
     private Person person = new Person();
     private Long pid = 0l;
     private List<Person> listPerson = new ArrayList<>();
     // carry on with your code from here

This allows you to remove the lazy initialization parts in your getters and should fix your problem.

An alternative to this is (as Tiny already mentioned in his comment), using a method annotated with @PostConstruct, something like this:

@PostConstruct
public void initialize() {
    this.person = (Person) personDao.findPerson(pid);
    this.personList = personDao.listPerson();
}
Community
  • 1
  • 1
Vogel612
  • 5,620
  • 5
  • 48
  • 73
  • Why it still output nothing? I tried your suggestions but still it returned to null. On my show.xhtml only Name: and Age: were displayed and on my create.xhtml still returned to Target Unreacheable. I am using Netbeans 8.0 and glassfish4 and jsf 2.2. – Anirudh Lou Apr 17 '15 at 03:43