11 Replies Latest reply on Jan 21, 2014 1:21 PM by hexc0de

    ManyToOne gives EntityNotFoundException

    ingo77

      My problem is that I get a EntityNotFoundException when I load a entity if the one side of a Many-to-one unidirectional doesn't exists in the database.

      Can someone please explain why.

      Obviosly I don't have a FK in the database and in this case it's not an option to add one.

      I would prefer to just get null when I call the getA() method in class B.

      I have not seen anywhere that the one side of a relation must exists, is this really true?


      I have this:

      Class A{...}



      Class B{
      ....
       @ManyToOne
       @JoinColumns({
       @JoinColumn(name="b_a_fk1", referencedColumnName="a_pk1",insertable=false,updatable=false),
       @JoinColumn(name="b_a_fk2", referencedColumnName="a_pk2",insertable=false,updatable=false),
       })
       public A getA() {
       return a;
       }
       public void setA(A a) {
       this.a=a;
       }
      }



      Thank you in advance.





      Full stacktrace:

      Exception in thread "AWT-EventQueue-0" javax.ejb.EJBException: javax.persistence.EntityNotFoundException: Unable to find A with id 1.1234567890123
      at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:69)
      at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)
      at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:197)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
      at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:131)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:263)
      at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
      at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
      at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
      at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
      at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
      at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
      at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
      Caused by: javax.persistence.EntityNotFoundException: Unable to find A with id 1.1234567890123
      at org.hibernate.ejb.Ejb3Configuration$Ejb3EntityNotFoundDelegate.handleEntityNotFound(Ejb3Configuration.java:107)
      at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:143)
      at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:193)
      at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:101)
      at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
      at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:846)
      at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:266)
      at org.hibernate.type.EntityType.resolve(EntityType.java:303)
      at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:116)
      at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
      at org.hibernate.loader.Loader.doQuery(Loader.java:717)
      at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
      at org.hibernate.loader.Loader.doList(Loader.java:2144)
      at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2028)
      at org.hibernate.loader.Loader.list(Loader.java:2023)
      at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:393)
      at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
      at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
      at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
      at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
      at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:64)
      at se.prosilia.xplod.j2ee.sessFacade.lager.LagerSearchBean.findLagerplatsWithBetween(LagerSearchBean.java:286)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:585)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
      at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
      at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
      at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:197)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
      at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:131)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:263)
      at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
      at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
      at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
      at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
      at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
      at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
      at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
      at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:190)
      at org.jboss.remoting.Client.invoke(Client.java:525)
      at org.jboss.remoting.Client.invoke(Client.java:488)
      at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:55)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:55)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:77)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
      at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:102)
      at $Proxy0.findLagerplatsWithBetween(Unknown Source)
      at se.prosilia.delegator.lager.LagerSearchDelegator.findLagerplatsWithBetween(LagerSearchDelegator.java:60)
      at se.posten.logistik.applications.xplod.gui.AtLagerplatsTitt$LPSearch.actionPerformed(AtLagerplatsTitt.java:363)
      at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)
      at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169)
      at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
      at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
      at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:234)
      at java.awt.Component.processMouseEvent(Component.java:5488)
      at javax.swing.JComponent.processMouseEvent(JComponent.java:3126)
      at java.awt.Component.processEvent(Component.java:5253)
      at java.awt.Container.processEvent(Container.java:1966)
      at java.awt.Component.dispatchEventImpl(Component.java:3955)
      at java.awt.Container.dispatchEventImpl(Container.java:2024)
      at java.awt.Component.dispatchEvent(Component.java:3803)
      at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)
      at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3892)
      at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)
      at java.awt.Container.dispatchEventImpl(Container.java:2010)
      at java.awt.Component.dispatchEvent(Component.java:3803)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
      at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)




        • 1. Re: ManyToOne gives EntityNotFoundException
          alexg79

          If you look at the data for class B, does it have rows where the A reference is non-null and refers to a nonexistent A entity? That would explain the error you're getting. Why are you specifying the join columns by hand anyway?

          • 2. Re: ManyToOne gives EntityNotFoundException
            ingo77

            Thanks for your answer.

            I need to specify the columnnames because the databaseschema already exists and it's not an option to change this.

            If I understand you correct, YES.

            Table A
            a_pk1 a_pk2 col3
            -----------------------------------
            1 1 1
            
            Table B
            b_pk1 b_a_fk1 b_a_fk2
            -----------------------------------
            1 1 1234567890123
            


            With this lovely peace of art I want to show that table B has a reference to A, but the record doesn't exists i Table A. I would call this a error in the database but like a said it's not an option to change this.

            Any ideas?




            • 3. Re: ManyToOne gives EntityNotFoundException
              alexg79

              I'd say you have a serious problem there. If you use @ManyToOne, the referenced entity must exist. The only other option is to specify that field as a long and retrieve the referenced entity by means of a separate query. Be warned though, getSingleResult() from a Query throws an exception (NoResultException if memory serves) instead of returning null if it can't find the requested entity.

              • 4. Re: ManyToOne gives EntityNotFoundException
                ingo77

                I hate the answer but anyway
                Thanks a lot.

                I was afraid of this but still a bit surprised.
                Has everyone else access to perfectly designed databases, I haven't?

                I'm not sure what to do, either your solution (which will work) or try to change the dbSchema, this is not the only example for issues like this.

                Again, thanks a lot.

                Regards Ingo


                • 5. Re: ManyToOne gives EntityNotFoundException
                  alexg79

                  I think most of us just use the database as persist storage for their applications, meaning that they get to dictate the db schema. This usually involves schema autogeneration through the EJB 3.0 persistence provider.

                  • 6. Re: ManyToOne gives EntityNotFoundException
                    tpben

                    There is a solution, but it is part of hibernate NOT the EJB3 specification!

                    I know your pain about working with hideous legacy databases!

                    If you include the hibernate-annotations.jar from the jboss lib directory you can use the following annotation on your accessor method: -

                    @NotFound(action=NotFoundAction.IGNORE)


                    Entities with invalid foreign keys will be ignored by the EntityManager.

                    There is a portability cost, but it might be worth it!!

                    • 7. Re: ManyToOne gives EntityNotFoundException

                      Sorry but this is just broken.

                      If you had a database schema at all integrity constraints would be enforced.

                      So unless you use MySQL (and a rather old version) this could not happen.

                      Regards

                      Felix

                      • 8. Re: ManyToOne gives EntityNotFoundException
                        ingo77

                        Thank you TPBen!!!

                        An Excellent solution to the problem!!

                        To fhh, like TPben stated, working with legacy databases isn't always easy.

                        The relation is missing in the database tier but I want it in the business tier and in this case adding the FK to the databse(Oracle) is not an option.

                        Thank you !!

                        • 9. Re: ManyToOne gives EntityNotFoundException

                          "Legacy system" smells for like a poor excuse for broken data. Foreign key constraints are usually in place for a good reason. If you ignore them all kinds of bad things may happen.

                          Regards

                          Felix

                          • 10. Re: ManyToOne gives EntityNotFoundException
                            jkronegg
                            @NotFound(action=NotFoundAction.IGNORE)

                            When this annotation is added to a LAZY fetched @ManyToOne, Hibernate will issue two SQL queries: one for the main object, and one for the @ManyToOne. So you loose the LAZY behavior, see http://opensource.atlassian.com/projects/hibernate/browse/HHH-2753

                             

                            But you can have @ManyToOne with LAZY loading AND without throwing EntityNotFoundException with the following code:

                             

                            public MyManyToOneEntity getMyManyToOneEntityOrNull() {

                              try {

                                // force fetching the entity (will raise an EntityNotFoundException if not found)

                                getMyManyToOneEntity().toString(); // or whatever method which force a fetch

                                return getMyManyToOneEntity();

                              } catch (EntityNotFoundException e) {

                                return null;

                              }

                            }

                             

                             

                            This way, Hibernate will issue one query for the main object, and one other query for the MyManyToOneEntity but only when the getMyManyToOneEntityOrNull() method is called.

                            • 11. Re: ManyToOne gives EntityNotFoundException
                              hexc0de

                              @Ben Walker

                               

                              @NotFound(action=NotFoundAction.IGNORE)  
                              
                              

                               

                              This solved my problem... Many Thanks !!