【问题标题】:null pointer exception when adding to HashSet添加到HashSet时出现空指针异常
【发布时间】:2014-05-15 00:34:20
【问题描述】:

尽管我已经初始化了 HashSet,但当我尝试向其中添加元素时,我得到了一个空指针异常。

@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "artikal")
private Set<Cenovnik> cene = new HashSet<Cenovnik>();

public Set<Cenovnik> getCene() {
    if (cene == null)
        this.cene = new HashSet<Cenovnik>();

    return cene;
}

我是这样使用它的:

Cenovnik cenovnik = new Cenovnik(date, null, cena);
Artikal artikal = artikalDao.findById(id);
Cenovnik stari = artikalDao.cena(id);

if (stari != null) {
    stari.setKrajkVazenja(date);
    cenovnikDao.merge(stari);
}

cenovnik.setArtikal(artikal);
artikal.getCene().add(cenovnik); //error!
cenovnikDao.persist(cenovnik);
artikalDao.merge(artikal);

所以,当我尝试将 cenovnik 添加到 artikal.getCene 时会发生错误,我已经检查过了,由于某种原因 getCene 似乎是问题所在。 这里是 Cenovnik 类

public class Cenovnik implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = -1436274372349853081L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "cenovnik_id", unique = true, nullable = false)
private Integer id;
  ...   

@ManyToOne
@JoinColumn(name="artikal_id", referencedColumnName="artikal_id")
private Artikal artikal;    

public Artikal getArtikal() {
    return artikal;
}

public void setArtikal(Artikal artikal) {
    this.artikal = artikal;
}
    ...
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    return result;
}

} 这是完整的堆栈跟踪:

java.lang.NullPointerException:

        rs.ac.uns.acs.ism.server.servlet.DodajCenuArtiklaController.doGet(DodajCenuArtiklaController.java:78)

        rs.ac.uns.acs.ism.server.servlet.DodajCenuArtiklaController.doPost(DodajCenuArtiklaController.java:109)

        javax.servlet.http.HttpServlet.service(HttpServlet.java:641)

        javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

        org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)

        org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)

        org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)

        org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)

        org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)

        org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)

        rs.ac.uns.acs.ism.server.servlet.DodajArtikalController.doGet(DodajArtikalController.java:72)

        rs.ac.uns.acs.ism.server.servlet.DodajArtikalController.doPost(DodajArtikalController.java:94)

        javax.servlet.http.HttpServlet.service(HttpServlet.java:641)

        javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

        org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)

        org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)

        org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)

        org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)

        org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)

        org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)

        org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)

        org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)

        org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)

        org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)

        org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)

        org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)

        org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)

        org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)

        java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

        java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

        java.lang.Thread.run(Thread.java:745)

这里是equals方法:

    @Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Cenovnik other = (Cenovnik) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    return true;
}

【问题讨论】:

  • 能发一下 Cenovnik 类的代码
  • 您在哪里遇到异常?发布堆栈跟踪并识别行。
  • 您自己的代码中的NPE?

标签: java jpa nullpointerexception ejb hashset


【解决方案1】:

如果 artikal 为空,则另一种情况。然后像这样进行空检查

 if(artikal != null) {
    artikal.getCene().add(cenovnik);
 }

试试这个来调试分解 getCene() 并添加到两行并添加一些打印语句,如果你正在使用一些记录器,请使用它。这将有助于了解发生了什么

       if(artikal != null) {
            System.out.println("artikal is not null");
            Set<Cenovnik> cenovniks= artikal.getCene();

            if(cenovniks != null) {
                System.out.println("cenovniks set is not null");
                cenovniks.add(cenovnik);
                System.out.println("Added cenovnik to set");
            } else {
                // Handle null cenovniks as appropriate to your application
                System.out.println("cenovniks set is null");
            }
        } else {
            System.out.println("artikal is null");
            // Handle null artikal as appropriate to your application
        }

否则

请注意,当添加到 hashset 时,这仅适用于 hashset 的 add() 方法

将对象添加到集合中会引发空指针异常的一个原因是:

要添加到 hashset 的对象的属性之一用于计算对象的 hashcode。并且在计算哈希码的过程中,这个属性会抛出一个空指针异常。

它可以是日期或其他一些属性。检查类的hashcode实现,在hashcode方法中放一个断点,看看是否抛出了这个空指针。

更新 1 查看 hascode 和 equals 方法似乎没有引起问题。

【讨论】:

  • 我注意到的一件事虽然在您的 equals 方法中无关,但您没有检查 Cenovnik other = (Cenovnik) obj; Cenovnik 类型传入的对象。这可能会爆炸。
  • artikal.getCene().add(cenovnik); - 我已将其标记为错误
  • @user3638849 尝试最新的 sn-p 这将提供更多信息。另外,无论谁投了反对票,请留下评论你为什么投反对票。
【解决方案2】:

您正在从数据源获取记录,然后使用它而不检查它是否为空。

试试

Artikal artikal = artikalDao.findById(id);

if (artikal != null) {
   artikal.getCene().add(cenovnik);
}  else 
{
   // throw something
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多