如何解决目标无法到达,' null'?

时间:2015-04-04 03:45:08

标签: jsf jpa glassfish-4

大家好我是javaweb的新手,我尝试创建我的第一个javaweb项目,当然是通过一些教程。但是当一些动作被调用时,我收到了一个错误。有人可以帮忙!这是我做的:

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>  

当试图运行我的项目时发生的事情是:
1.当我点击show.xhtml

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

它说: 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)  
    ...  

但在网址上显示:
http://localhost:8080/javaeesample/faces/details.xhtml?pid=1

  1. 当我点击create.xhtml中的“保存”按钮时,我收到错误:
  2. 发生错误:

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

    我展开Stack Trace并显示

    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)
    

    我不知道是什么让我的personBean.person.name为null。

    非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

由于Tiny似乎不想写答案,我会这样做。这个答案的基础部分是他的评论:

  

目标无法访问,&#39; null&#39;返回null:#{personBean.person}   或#{personBean}null。我闻到personnull。你正试图   预先填充personDetails()内的人。为什么要初始化   使用<f:event type="javax.faces.event.PreRenderComponentEvent" listener="#{personBean.personDetails()}"/>的人?你最好   预先填充private Person person;(和private List<Person> listPerson;,您在getter方法中懒得初始化   不必要地)在更好的初始化位置 - 在方法内部   用@PostConstruct注释。

现在对此有更多解释

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

此错误表示:&#34; #{personBean.person}#{personBean}为空(请参见上文)。假设person是罪魁祸首,我完全和Tiny在一起。

这个的根本原因是,在用于初始化Person运行的侦听器时,xhtml文件已经被完全解析。在您的听众有机会更改person之前,应该已经访问过它的属性。

这会导致您的错误。解决这个问题的方法很简单:

不要让person为空。 使用急切初始化可以防止这种情况,并使PersonBean看起来如下:

@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

这允许您删除getter中的延迟初始化部分,并且应该解决您的问题。

替代方法是(Tiny中已经提到his comment),使用注释为@PostConstruct的方法,如下所示:

@PostConstruct
public void initialize() {
    this.person = (Person) personDao.findPerson(pid);
    this.personList = personDao.listPerson();
}