12 Replies Latest reply on Oct 28, 2008 3:23 AM by adamw

    oneToOne Uni Directional Relation Versioning

    niharika

      Hello,

      I'm having a problem with versioning of a OneToOne relationship with envers.

      I'm using:
      Envers 1.1.0 beta2 for hibernate 3.3
      Hibernate 3.3.0.CR2

      Example
      (A Specimen has a Status associated with it)

      EmsiSpecimen

      
      @Entity
      @Table(name="EMSI_SPECIMEN")
      @Name("EmsiSpecimen")
      public class EmsiSpecimen implements Serializable {
      
       private static final long serialVersionUID = 1l;
      
       @Versioned
       @Column(name = "IMPORT_DATE")
       private Date importDate;
      
       @Versioned
       @Column (name = "DESCRIPTION", nullable = true)
       private String description;
      
       @Versioned
       @OneToOne(optional = true)
       @JoinColumn(name = "STATUS_FK", nullable = true)
       private Status status;
      
       //other getters and setters
      
      


      Status:

      
      @Entity
      @Versioned
      @Table(name="STATUS")
      @NamedQuery(
       name="findStatus",
       query="SELECT s FROM Status s WHERE status = :status"
      )
      public class Status {
      
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO, generator="status_seq")
       @SequenceGenerator(name="status_seq", sequenceName="SPEC_SATUS_ID_SEQ", allocationSize=1)
       int id;
      
       @Column(name = "STATUS")
       private String status;
      
       public Status() {
       }
      
      




      Test Code

      
      VersionsReader lVersionsReader = VersionsReaderFactory.get(mEntityManager);
      List<Number> lRevisionList = lVersionsReader.getRevisions(EmsiSpecimen.class, aEmsiSpecimen.getId());
      
      for (Number lRevisionNumber : lRevisionList){
       EmsiSpecimen lEmsiSpecimenRevision = lVersionsReader.find(EmsiSpecimen.class,
       aEmsiSpecimen.getId(),lRevisionNumber);
      
       specimenRevisions.add(lEmsiSpecimenRevision);
      


      I get the following exception at the line colored in red in the test code.

      08:22:37,208 ERROR [SeamPhaseListener] swallowing exception
      javax.el.ELException: javax.ejb.EJBTransactionRolledbackException: Unable to find org.partners.betr.emsi.model.Status with id null


      Database:

      The Emsi_Specimen table has a STATUS_FK.

      Can you please tell me what am I doing wrong?

      Thanks !

        • 1. Re: oneToOne Uni Directional Relation Versioning
          adamw

          Hello,

          could you please post the full stack trace?

          Also, isn't the aEmsiSpecimen.getId() null?

          By the way, you can retrieve history of an entity + the associated revision entity (in your case EmsiSpecimen) with just one query - revision of entity. See the beta javadoc: http://www.jboss.org/files/envers/api-beta/index.html.

          --
          Adam

          • 2. Re: oneToOne Uni Directional Relation Versioning
            niharika

            Hello Adam,

            Here is the full stack trace


            
            javax.el.ELException: javax.ejb.EJBTransactionRolledbackException: Unable to fin
            d org.partners.betr.emsi.model.Status with id null
             at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:333
            )
             at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:274
            )
             at org.jboss.el.parser.AstMethodSuffix.getValue(AstMethodSuffix.java:59)
            
             at org.jboss.el.parser.AstMethodSuffix.invoke(AstMethodSuffix.java:65)
             at org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
             at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:27
            6)
             at org.jboss.seam.core.Expressions$2.invoke(Expressions.java:174)
             at org.jboss.seam.navigation.Pages.callAction(Pages.java:689)
             at org.jboss.seam.navigation.Pages.preRender(Pages.java:327)
             at org.jboss.seam.jsf.SeamPhaseListener.preRenderPage(SeamPhaseListener.
            java:562)
             at org.jboss.seam.jsf.SeamPhaseListener.beforeRenderResponse(SeamPhaseLi
            stener.java:473)
             at org.jboss.seam.jsf.SeamPhaseListener.beforeServletPhase(SeamPhaseList
            ener.java:146)
             at org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener.ja
            va:116)
             at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:222)
             at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
             at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
            icationFilterChain.java:290)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
            ilterChain.java:206)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter
            .java:83)
             at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:38)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter
            .java:69)
             at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter
            .java:69)
             at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter
            .java:69)
             at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter
            .java:69)
             at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177)
            
             at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267)
             at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFil
            ter.java:380)
             at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507)
             at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter
            .java:69)
             at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter
            .java:69)
             at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
            icationFilterChain.java:235)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
            ilterChain.java:206)
             at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFi
            lter.java:96)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
            icationFilterChain.java:235)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
            ilterChain.java:206)
             at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
            alve.java:230)
             at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
            alve.java:175)
             at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(Securit
            yAssociationValve.java:179)
             at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValv
            e.java:84)
             at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
            ava:127)
             at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
            ava:102)
             at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedC
            onnectionValve.java:157)
             at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
            ve.java:109)
             at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav
            a:262)
             at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
            :844)
             at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
            ss(Http11Protocol.java:583)
             at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:44
            6)
             at java.lang.Thread.run(Thread.java:595)
            Caused by: javax.ejb.EJBTransactionRolledbackException: Unable to find org.partn
            ers.betr.emsi.model.Status with id null
             at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:87)
            
             at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130)
             at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java
            :195)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
            java:101)
             at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInt
            erceptor.java:95)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
            java:101)
             at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulIn
            stanceInterceptor.java:83)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
            java:101)
             at org.jboss.aspects.security.AuthenticationInterceptor.invoke(Authentic
            ationInterceptor.java:77)
             at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3Auth
            enticationInterceptor.java:110)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
            java:101)
             at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterce
            ptor.java:46)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
            java:101)
             at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(Asynchrono
            usInterceptor.java:106)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
            java:101)
             at org.jboss.ejb3.stateful.StatefulContainer.localInvoke(StatefulContain
            er.java:206)
             at org.jboss.ejb3.stateful.StatefulLocalProxy.invoke(StatefulLocalProxy.
            java:119)
             at $Proxy126.findSpecimenRevisions(Unknown Source)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
            java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
            sorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
             at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocation
            Context.java:31)
             at org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideIn
            terceptor.java:76)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
            Context.java:56)
             at org.jboss.seam.security.SecurityInterceptor.aroundInvoke(SecurityInte
            rceptor.java:138)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
            Context.java:68)
             at org.jboss.seam.ejb.RemoveInterceptor.aroundInvoke(RemoveInterceptor.j
            ava:43)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
            Context.java:68)
             at org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(Synchroni
            zationInterceptor.java:32)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
            Context.java:68)
             at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:
            107)
             at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInter
            ceptor.java:54)
             at org.javassist.tmp.java.lang.Object_$$_javassist_4.findSpecimenRevisio
            ns(Object_$$_javassist_4.java)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
            java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
            sorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:329
            )
             ... 53 more
            Caused by: javax.persistence.EntityNotFoundException: Unable to find org.partner
            s.betr.emsi.model.Status with id null
             at org.hibernate.ejb.Ejb3Configuration$Ejb3EntityNotFoundDelegate.handle
            EntityNotFound(Ejb3Configuration.java:109)
             at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(Abstract
            LazyInitializer.java:79)
             at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyIn
            itializer.java:68)
             at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(Abstrac
            tLazyInitializer.java:111)
             at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(Ja
            vassistLazyInitializer.java:166)
             at org.partners.betr.emsi.model.Status_$$_javassist_11.toString(Status_$
            $_javassist_11.java)
             at org.partners.betr.emsi.model.EmsiSpecimen.toString(EmsiSpecimen.java:
            280)
             at java.lang.String.valueOf(String.java:2615)
             at java.lang.StringBuilder.append(StringBuilder.java:116)
             at org.partners.betr.emsi.seam.AuditReportAction.findSpecimenRevisions(A
            uditReportAction.java:224)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
            java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
            sorImpl.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(InvocationCo
            ntextImpl.java:166)
             at org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationCo
            ntext.java:44)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
            Context.java:56)
             at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackI
            nterceptor.java:28)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
            Context.java:68)
             at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterc
            eptor.java:39)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
            Context.java:68)
             at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodConte
            xtInterceptor.java:44)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
            Context.java:68)
             at org.jboss.seam.persistence.EntityManagerProxyInterceptor.aroundInvoke
            (EntityManagerProxyInterceptor.java:29)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
            Context.java:68)
             at org.jboss.seam.persistence.HibernateSessionProxyInterceptor.aroundInv
            oke(HibernateSessionProxyInterceptor.java:31)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocation
            Context.java:68)
             at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:
            107)
             at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionB
            eanInterceptor.java:50)
             at sun.reflect.GeneratedMethodAccessor171.invoke(Unknown Source)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
            sorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationCo
            ntextImpl.java:118)
             at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3Int
            erceptorsInterceptor.java:63)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
            java:101)
             at org.jboss.ejb3.entity.ExtendedPersistenceContextPropagationIntercepto
            r.invoke(ExtendedPersistenceContextPropagationInterceptor.java:57)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
            java:101)
             at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invok
            e(TransactionScopedEntityManagerInterceptor.java:54)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
            java:101)
             at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsI
            nterceptor.java:47)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
            java:101)
             at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
             ... 91 more
            
            
            


            aEmsiSpecimen.getId() is not null. Actually, I didn't post the entire code. Here it is:



            
            
             public void findSpecimenRevisions(EmsiSpecimen aEmsiSpecimen){
            
             specimenRevisions = new ArrayList<EmsiSpecimen>();
            
             VersionsReader lVersionsReader = VersionsReaderFactory.get(mEntityManager);
             List<Number> lRevisionList = lVersionsReader.getRevisions(EmsiSpecimen.class, aEmsiSpecimen.getId());
            
             for (Number lRevisionNumber : lRevisionList){
            
            
             EmsiSpecimen lEmsiSpecimenRevision = lVersionsReader.find(EmsiSpecimen.class,
             aEmsiSpecimen.getId(),lRevisionNumber);
            
             specimenRevisions.add(lEmsiSpecimenRevision);
            
             }
            
             }
            
            


            I am making sure that the Status of the EmsiSpecimen is populated and is not null. And the STATUS_FK in the Emsi_Specimen_Versions table is populated as well.

            Thank you for your response.

            • 3. Re: oneToOne Uni Directional Relation Versioning
              anaholzbach

              Upon debugging it turns out that the lVersionsReader.find call does return the correct revision of EmsiSpecimen but all the relationships (all of which are to simple lookup tables) are being handled by hibernate's JavassistLazyInitializer (and have accordingly null values), even though they are not specified as fetch type lazy in the actual EmsiSpecimen entity.

              Could this have something to do with this error?

              Thanks!

              Ana
              (at the risk of confusing Adam - I'm writing this because I'm working on the same project as niharika)

              • 4. Re: oneToOne Uni Directional Relation Versioning
                adamw

                Hello,

                well, the first weird thing is that "envers" (part of the package name) doesn't come up in the stack trace. The exception originates here:

                at org.partners.betr.emsi.model.Status_$$_javassist_11.toString(Status_$
                $_javassist_11.java)
                 at org.partners.betr.emsi.model.EmsiSpecimen.toString(EmsiSpecimen.java:
                280)
                 at java.lang.String.valueOf(String.java:2615)
                 at java.lang.StringBuilder.append(StringBuilder.java:116)
                 at org.partners.betr.emsi.seam.AuditReportAction.findSpecimenRevisions(A
                uditReportAction.java:224)
                


                while appending a value to a StringBuilder - but I don't see a StringBuilder in your code :). All relations in versioned classes are by default lazily loaded, but not by using JavassistLazyInitializer. So it looks like it's a value not even returned by Envers ...

                Well, it's weird :) I'll also take a look in the evening.

                --
                Adam

                • 5. Re: oneToOne Uni Directional Relation Versioning
                  anaholzbach

                  Hi Adam,

                  Thanks for your reply. You're right that the error was occurring in the toString() method of EmsiSpecimen, but the fact remains that we're not able to load the Status entity pertaining to the EmisSpecimen at that revision. lEmsiSpecimenRevision.getStatus().getStatus() (where we examine the instance variable "status" of the referenced entity Status) always results in EntityNotFoundException.

                  I saw the example where you call getReference() on a revision of UniRefIngEntity. This seems like a similar case to me and thus one that should work.

                  Thanks,

                  Ana

                  • 6. Re: oneToOne Uni Directional Relation Versioning
                    adamw

                    Hello,

                    yes, of course it should work :) Can you please post the full Status and EmsiSpecimen classes, with the toString() method and the code that you run and that fails?

                    Also, you can catch me on IRC (irc.freenode.net), #envers, maybe we'll be able to solve the problem faster talking directly :)

                    --
                    Adam

                    • 7. Re: oneToOne Uni Directional Relation Versioning
                      adamw

                      Unfortunately I'm not able to reproduce your problem. Maybe you could isolate a test case?

                      --
                      Adam

                      • 8. Re: oneToOne Uni Directional Relation Versioning
                        anaholzbach

                        Hi Adam,

                        Thanks for trying to reproduce it :). I have a test case that demonstrates this behavior. It's obviously something we're doing wrong. How can I send it to you?

                        Thanks again.

                        Ana

                        • 9. Re: oneToOne Uni Directional Relation Versioning
                          adamw

                          Of course - the easiest way is to attach it in a JIRA bug.
                          Or via e-mail, if you prefer: adam dot warski at jboss dot org.

                          --
                          Adam

                          • 10. Re: oneToOne Uni Directional Relation Versioning
                            anaholzbach

                            Heh, I hesitated to enter a JIRA issue since I'm not really sure this is a bug. Anyway, here it is... https://jira.jboss.org/jira/browse/ENVERS-65

                            Thanks!

                            Ana

                            • 11. Re: oneToOne Uni Directional Relation Versioning
                              anaholzbach

                              Per Adam's suggestion, adding rows in the versions tables for the the entities that were being pre-populated by a script outside of the application fixes this.

                              Thanks!

                              Ana

                              • 12. Re: oneToOne Uni Directional Relation Versioning
                                adamw

                                Great, I'll close the issue :)

                                Adam