4

我在 and 之间有@OneToMany 关系,并且在UserDomainand之间PartageDomain有相同的关系。有一个由和组成的复合键。当我尝试在表中保存记录时,出现此异常:FileDomainPartageDomainPartageDomainUserDomainFileDomainPartageDomain

Caused by: java.lang.NullPointerException
    at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:136)
    at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:144)
    at org.hibernate.type.EntityType.getHashCode(EntityType.java:312)
    at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:212)
    at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:126)
    at org.hibernate.engine.EntityKey.<init>(EntityKey.java:70)
    at org.hibernate.engine.StatefulPersistenceContext.getDatabaseSnapshot(StatefulPersistenceContext.java:263)
    at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:212)
    at org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:535)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:103)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:523)
    at com.stage.dao.PartageDaoImpl.add(PartageDaoImpl.java:39)
    at com.stage.service.PartageServiceImpl.add(PartageServiceImpl.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy42.add(Unknown Source)
    at com.stage.beans.UserManagedBean.saveUserRights(UserManagedBean.java:234)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:102)
    ... 23 more

我做了一些研究,发现这个异常来自三个案例:

a)我们有一个复合键,其中一个键的属性是另一个持久类的 FK。

b) 另一个持久类有一个 ID 字段,其值正在生成。

c) 另一个持久类的实例是瞬态的(还没有 ID)

文档中没有说明我们如何解决这些问题,但是按照 hibernate 文档中的建议,我重写了 equals() 和 hashCode() 以实现复合标识符相等。并且还实现了Serializable,但它总是不起作用。因此,如果有人对我的问题的根源有所了解;

正如上面评论中所建议的,我将 hashcode 方法添加到我的UserDomainandFileDomain中,getIdandgetLink方法获取相应的对象 ID。

部分userDomain

    public class UserDomain implements Serializable {
    ....
    @OneToMany (cascade=CascadeType.ALL)
        private Collection<PartageDomain> partageDomain = new ArrayList<PartageDomain>();
    public Collection<PartageDomain> getPartageDomain() {
            return partageDomain;
        }

        public void setPartageDomain(Collection<PartageDomain> partageDomain) {
            this.partageDomain = partageDomain;
        }
public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        UserDomain that = (UserDomain) o;

        if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null) return false;

        return true;
    }
    public int hashCode() {
        return (getId() != null ? getId().hashCode() : 0);
    }

部分FileDomain

    public class FileDomain implements Serializable {
    ...
        @OneToMany 
        private Collection<PartageDomain> partageDomain = new ArrayList<PartageDomain>();

        public Collection<PartageDomain> getPartageDomain() {
            return partageDomain;
        }

        public void setPartageDomain(Collection<PartageDomain> partageDomain) {
            this.partageDomain = partageDomain;
        }
public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        FileDomain that = (FileDomain) o;

        if (getLink() != null ? !getLink().equals(that.getLink()) : that.getLink() != null) return false;

        return true;
    }
    public int hashCode() {
        return (getLink() != null ? getLink().hashCode() : 0);
    }

部分PartageDomain

public class PartageDomain implements Serializable {
@EmbeddedId
    private PartageId partageId = new PartageId();
public PartageId getPartageId() {
        return partageId;
    }

    public void setPartageId(PartageId partageId) {
        this.partageId = partageId;
    }
...
public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        PartageDomain that = (PartageDomain) o;

        if (getPartageId() != null ? !getPartageId().equals(that.getPartageId()) : that.getPartageId() != null) return false;

        return true;
    }

    public int hashCode() {
        return (getPartageId() != null ? getPartageId().hashCode() : 0);
    }

PartageId班级:

@Embeddable

    public class PartageId implements Serializable {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        @ManyToOne
        private FileDomain fileDomain;

        @ManyToOne
        private UserDomain userDomain;

        public FileDomain getFileDomain() {
            return fileDomain;
        }

        public void setFileDomain(FileDomain fileDomain) {
            this.fileDomain = fileDomain;
        }

        public UserDomain getUserDomain() {
            return userDomain;
        }

        public void setUserDomain(UserDomain userDomain) {
            this.userDomain = userDomain;
        }

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            PartageId that = (PartageId) o;

            if (fileDomain != null ? !fileDomain.equals(that.fileDomain) : that.fileDomain != null) return false;
            if (userDomain != null ? !userDomain.equals(that.userDomain) : that.userDomain != null)
                return false;

            return true;
        }

        public int hashCode() {
            int result;
            result = (fileDomain != null ? fileDomain.hashCode() : 0);
            result = 31 * result + (userDomain != null ? userDomain.hashCode() : 0);
            return result;
        }
    }
4

0 回答 0