JPA,Hibernate:查找引发NullPointerException异常

3

我正在使用这段代码通过主键从数据库获取实体:

@Override
public Entity read(final long key) throws DAOException {
    try {
        EntityManager em = PM.getEntityManager();
        em.getTransaction().begin();
        Sportart result = em.find(Entity .class, key);
        em.getTransaction().commit();
        em.close();
        return result;
    } catch (Exception e) {
        e.printStackTrace();
        throw new DAOException("Error reading Entity.");
    }
}

这是堆栈跟踪:

java.lang.NullPointerException
    at org.hibernate.engine.internal.StatefulPersistenceContext.getLoadedCollectionOwnerOrNull(StatefulPersistenceContext.java:756)
    at org.hibernate.event.spi.AbstractCollectionEvent.getLoadedOwnerOrNull(AbstractCollectionEvent.java:75)
    at org.hibernate.event.spi.InitializeCollectionEvent.<init>(InitializeCollectionEvent.java:36)
    at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1931)
    at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:558)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:260)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142)
    at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:447)
    at abc.de.App.entities.Entity.hashCode(Entity.java:75)
    at java.util.HashMap.hash(Unknown Source)
    at java.util.HashMap.put(Unknown Source)
    at java.util.HashSet.add(Unknown Source)
    at java.util.AbstractCollection.addAll(Unknown Source)
    at org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:344)
    at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:251)
    at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:238)
    at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:211)
    at org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl.endLoading(CollectionReferenceInitializerImpl.java:168)
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishLoadingCollections(AbstractRowReader.java:255)
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:218)
    at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:140)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:138)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102)
    at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:100)
    at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:693)
    at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:92)
    at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1933)
    at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:558)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:260)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142)
    at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:447)
    at abc.de.App.entities.Other.hashCode(Other.java:206)
    at java.util.HashMap.hash(Unknown Source)
    at java.util.HashMap.put(Unknown Source)
    at java.util.HashSet.add(Unknown Source)
    at java.util.AbstractCollection.addAll(Unknown Source)
    at org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:344)
    at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:251)
    at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:238)
    at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:211)
    at org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl.endLoading(CollectionReferenceInitializerImpl.java:168)
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishLoadingCollections(AbstractRowReader.java:255)
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:218)
    at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:140)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:138)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102)
    at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:186)
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4126)
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:503)
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:468)
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:213)
    at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:275)
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151)
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1106)
    at org.hibernate.internal.SessionImpl.access$2000(SessionImpl.java:176)
    at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2587)
    at org.hibernate.internal.SessionImpl.get(SessionImpl.java:991)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1110)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:1068)
    at abc.de.App.dao.implementations.DAOImpl.read(DAOImpl.java:44)
    at abc.de.App.dao.implementations.DAOImpl.read(DAOImpl.java:1)
    at abc.de.App.controllers.Controller.saveData(Controller.java:73)
    at abc.de.App.views.View.lambda$2(View.java:183)
    at java.lang.Thread.run(Unknown Source)

还有实体:

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

@Entity
public class Entity implements Model {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long Entity_id;
    @Column(nullable = false)
    private String bez;
    @Column(nullable = false)
    private String bes;
    @ManyToMany(mappedBy = "Entities", fetch = FetchType.EAGER)
    private Set<Other> other = new HashSet<>();


    public Entity() {

    }

    public long getEntity_id() {
        return Entity_id;
    }

    public void setEntity_id(final long Entityid) {
        this.Entity_id = Entityid;
    }

    public String getbez() {
        return bez;
    }

    public void setbez(final String bez) {
        this.bez = bez;
    }

    public String getbes() {
        return bes;
    }

    public void setbes(final String bes) {
        this.bes = bes;
    }

    public Set<Other> getOther() {
        return other;
    }

    public void setOther(final Set<Other> Other) {
        this.other = other;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((bes == null) ? 0 : bes.hashCode());
        result = prime * result
                + ((bez == null) ? 0 : bez.hashCode());
        result = prime * result
                + ((other == null) ? 0 : other.hashCode());
        result = prime * result + (int) (Entity_id ^ (Entity_id >>> 32));
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Entity other = (Entity) obj;
        if (bes == null) {
            if (other.bes != null) {
                return false;
            }
        } else if (!bes.equals(other.bes)) {
            return false;
        }
        if (bez == null) {
            if (other.bez != null) {
                return false;
            }
        } else if (!bez.equals(other.bez)) {
            return false;
        }
        if (other == null) {
            if (other.other != null) {
                return false;
            }
        } else if (!other.equals(other.other)) {
            return false;
        }
        if (Entity_id != other.Entity_id) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Entity [Entity_id=" + Entity_id + ", bez="
                + bez + ", bes=" + bes
                + ", other=" + other + "]";
    }

}

我在我的另一个实体中使用相同的代码,那里它可以正常工作。

这里可能是什么原因呢?


1
java.lang.NullPointerException [...] at abc.de.App.entities.Entity.hashCode(Entity.java:75) - 第75行是哪一行?在您粘贴的代码中,第75行是空行。 - sina
1个回答

4

这个错误会导致控制台填充重复的错误消息。看起来像是无限递归。那么它从哪里来呢? 我们来看看错误消息,我们会发现在 hibernate 的底层某个地方计算了你的实体的哈希值。在你的实体的 hashCode() 中,你调用了 other.hashCode(),它将调用集合中元素的哈希和,从而调用 Other.hashCode()。很可能你的 Other.hashCode() 调用了 Entities.hashCode(),它将调用 Entity.hashCode(),以此类推……这样就产生了无限递归。


1
谢谢,这让我省去了很多烦恼。我正在使用Lombok,它甚至在我不知情的情况下为我创建了一个hashCode函数。 - Mike Nakis
这不是递归问题,而是某些版本的Hibernate中的错误。在Lombok中最简单的方法是通过注释从哈希码中排除嵌套设置字段。请参见我的答案https://stackoverflow.com/questions/46140456/spring-data-findone-nullpointerexception/63715074#63715074,其中引用了一些其他帖子以获取更多详细信息。 - orbfish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接