2

I have nested Set to my Entities. Here is my code:

MyClassA:

@Entity
@Table(name = "aaa")
public class MyClassA {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @NotEmpty
    @Size(min = 3, max = 255)
    @Column(name = "name", nullable = false)
    private String name;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private Set<MyClassB> mycollection = new HashSet<MyClassB>();

    public MyClassA() {    
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Set<MyClassB> getMyClassB() {
        return mycollection;
    }

    public void setMyClassB(Set<MyClassB> mycollection) {
        this.mycollection = mycollection;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((mycollection == null) ? 0 : mycollection.hashCode());
        return result;
    }

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

    @Override
    public String toString() {
        return "MyClassA [id=" + id + ", name=" + name + ", mycollection=" + mycollection + "]";
    }       
}

MyClassB:

@Entity
@Table(name = "bbb")
public class MyClassB {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @NotEmpty
    @Size(min = 3, max = 255)
    @Column(name = "name", nullable = false)
    private String name;

    @NotEmpty
    @Size(min = 3, max = 255)
    @Column(name = "elementname", nullable = false)
    private String elementname;                

    @NotEmpty
    @Size(min = 3, max = 255)
    @Column(name = "type", nullable = false)
    private String type;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private Set<MyClassC> mycollection = new HashSet<MyClassC>();

    public MyClassB() {    
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getElementname() {
        return elementname;
    }

    public void setElementname(String elementname) {
        this.elementname = elementname;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Set<MyClassC> getMyCollection() {
        return mycollection;
    }

    public void setMyCollection(Set<MyClassC> mycollection) {
        this.mycollection = mycollection;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((elementname == null) ? 0 : elementname.hashCode());
        result = prime * result + id;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
Line 79---> result = prime * result + ((mycollection == null) ? 0 : mycollection.hashCode());
        result = prime * result + ((type == null) ? 0 : type.hashCode());
        return result;
    }

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

    @Override
    public String toString() {
        return "MyClassB [id=" + id + ", name=" + name + ", elementname=" + elementname + ", type=" + type + ", mycollection=" + mycollection + "]";
    }       
}

MyClassC:

@Entity
@Table(name = "ccc")
public class MyClassC {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @NotEmpty
    @Size(min = 3, max = 255)
    @Column(name = "name", nullable = false)
    private String name;

    @NotEmpty
    @Size(min = 3, max = 255)
    @Column(name = "value", nullable = false)
    private String value;

    public MyClassC(){          
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((value == null) ? 0 : value.hashCode());
        return result;
    }

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

    @Override
    public String toString() {
        return "MyClassC [id=" + id + ", name=" + name + ", value=" + value + "]";
    }

}

When I am trying to get all the MyClassA objects, in my controller, I am getting the following exception:

2016-09-28 10:10:46 DEBUG DefaultHandlerExceptionResolver:134 - Resolving exception from handler [public org.springframework.http.ResponseEntity> com.example.controller.MyController.listAllMyClassA()]: java.lang.NullPointerException 2016-09-28 10:10:46 DEBUG DispatcherServlet:989 - Could not complete request 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.(InitializeCollectionEvent.java:36) at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1931) at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:559) at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:261) at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:555) at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:143) at org.hibernate.collection.internal.PersistentSet.toString(PersistentSet.java:316) at com.example.model.MyClassB.hashCode(MyClassB.java:79) at java.util.HashMap.hash(HashMap.java:338) at java.util.HashMap.put(HashMap.java:611) at java.util.HashSet.add(HashSet.java:219) at java.util.AbstractCollection.addAll(AbstractCollection.java:344) 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.Loader.endCollectionLoad(Loader.java:1157) at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1126) at org.hibernate.loader.Loader.processResultSet(Loader.java:973) at org.hibernate.loader.Loader.doQuery(Loader.java:921) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355) at org.hibernate.loader.Loader.doList(Loader.java:2554) at org.hibernate.loader.Loader.doList(Loader.java:2540) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370) at org.hibernate.loader.Loader.list(Loader.java:2365) at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1718) at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380) at com.example.dao.MyClassADaoImpl.findAllGroupQuestions(MyClassADaoImpl.java:42) at com.example.service.MyClassAImpl.findAllGroupQuestions(MyClassAImpl.java:41) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) at com.sun.proxy.$Proxy63.findAllGroupQuestions(Unknown Source) at gr.citystore.helios.controller.QuestionaireController.listAllGroupQuestions(QuestionaireController.java:212) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:168) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:96) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674) at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2500) at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2489) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)

MyClassADaoImpl:

@SuppressWarnings("unchecked")
public List<MyClassA> findAllMyClassAs() {
    Criteria criteria = createEntityCriteria();
    criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
    return (List<MyClassA>) criteria.list();
}

Finally, my service implementation MyClassAImpl:

public List<MyClassA> findAllMyClassAs() {
        return dao.findAllMyClassAs();
    }

My Hibernate version is 4.3.11.Final. If you need any other information, please let me know! Thanks

KostasC
  • 856
  • 5
  • 18
  • 35
  • Can you please indicate which line is line 79 in MyClassB.java in your code snippet? This will also help us give you a more specific answer as to why whatever is null is null despite the hibernate non-nullable annotations (which is why, for now, I'm not marking this as a duplicate of http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it). – Jason C Sep 28 '16 at 13:14
  • @JasonC, I have edit the MyClassB in the method hashCode, to indicate which line is 79. – KostasC Sep 28 '16 at 13:31
  • 1
    [Be careful comparing `Class` with `==` when using Hibernate](http://blog.xebia.com/advanced-hibernate-proxy-pitfalls/), if you've got lazy loading enabled, Hibernate can generate proxy classes and return instances of those instead of your actual class. Same deal with field access in e.g. `equals` and `hashCode`; consider using getters instead; that may or may not be the real source of your problem. Consider creating unit tests for your hashing and comparison implementations, both with objects queried from the db and manually constructed ones, to verify that your setup is working as expected. – Jason C Sep 28 '16 at 14:32
  • @JasonC I will consider your comment, thanks for your afford. – KostasC Sep 28 '16 at 15:25

1 Answers1

8

Looking at your stacktrace, I believe the source of this problem is in your hashCode methods:

com.example.model.MyClassB.hashCode(MyClassB.java:79) at

Try to remove the sets attributes from your hashCode methods. I don't think this will be necessary to calculate the hash of the class. At most of the cases, you use the business keys (i.e. the unique attributes that identifies the object).

https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/persistent-classes-equalshashcode.html

Be safe! :)

Oscar Costa
  • 144
  • 2
  • 9
  • Only at the hashCode? Or also at the equal? – KostasC Sep 28 '16 at 12:56
  • At equal method too. I changed the answer, including a reference about implementation of equal and hashCode in hibernate. – Oscar Costa Sep 28 '16 at 13:09
  • @KostasC Before you do this, let us know which line is line 79 so you're not fixing the wrong thing. This will also help us give you an answer as to why whatever is null is null despite the hibernate non-nullable annotations. – Jason C Sep 28 '16 at 13:15
  • @JasonC, I have edit the MyClassB in the method hashCode, to indicate which line is 79. – KostasC Sep 28 '16 at 13:32
  • @OscarCosta, I remove the sets attributes and the exception goes away! Thanks – KostasC Sep 28 '16 at 13:57