6 Replies Latest reply on Aug 1, 2009 8:50 AM by adamw

    NPE in AuditedPropertiesReader.addPropertiesFromClass()

      I'm using Envers 1.2.0.GA with Hibernate 3.3.1, configured via Spring. I'm not using an EntityManager; I'm using a SessionFactory. After much trial and error, due to the fact all the examples I could find assumed an EntityManager, I've gotten close, but now I am stuck.

      The first thing I had to do was switch one of my entities from being mapped via XML to use annotations (I've left the rest of my mappings as XML for the time being).

      Next, I figured out the eventListeners property was the way to add the listeners to the SessionFactory.

       <bean id="historicalAuditEventListener" class="org.hibernate.envers.event.AuditEventListener" />
      
       <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
       <property name="dataSource">
       <ref local="dataSource"/>
       </property>
      
       <property name="mappingLocations">
       <list>
       <value>classpath*:/com/foo/**/*.hbm.xml</value>
       </list>
       </property>
      
       <property name="annotatedClasses" value="com.foo.NP" />
      
       <property name="hibernateProperties">
       .
       .
       .
       </property>
      
       <property name="eventListeners">
       <map>
       <entry key="post-insert">
       <ref local="historicalAuditEventListener"/>
       </entry>
       <entry key="post-update">
       <ref local="historicalAuditEventListener"/>
       </entry>
       <entry key="post-delete">
       <ref local="historicalAuditEventListener"/>
       </entry>
       <entry key="pre-collection-update">
       <ref local="historicalAuditEventListener"/>
       </entry>
       <entry key="pre-collection-remove">
       <ref local="historicalAuditEventListener"/>
       </entry>
       <entry key="post-collection-recreate">
       <ref local="historicalAuditEventListener"/>
       </entry>
       </map>
       </property>
       </bean>
      

      Then, I added the @Audited annotation to the NP class, the AbstractNP class it inherits from, & the NPCapability class it maps as a component.

      However, when I run my integration test, which starts-up Spring, which creates the Hibernate SessionFactory, I'm getting the following:

      [junit] Caused by: java.lang.NullPointerException
      [junit] at org.hibernate.envers.configuration.metadata.reader.AuditedPropertiesReader.addPropertiesFromClass(AuditedPropertiesReader.java:85)
      [junit] at org.hibernate.envers.configuration.metadata.reader.AuditedPropertiesReader.read(AuditedPropertiesReader.java:68)
      [junit] at org.hibernate.envers.configuration.metadata.reader.AuditedPropertiesReader.addFromProperties(AuditedPropertiesReader.java:108)
      [junit] at org.hibernate.envers.configuration.metadata.reader.AuditedPropertiesReader.addPropertiesFromClass(AuditedPropertiesReader.java:89)
      [junit] at org.hibernate.envers.configuration.metadata.reader.AuditedPropertiesReader.read(AuditedPropertiesReader.java:68)
      [junit] at org.hibernate.envers.configuration.metadata.reader.AnnotationsMetadataReader.getAuditData(AnnotationsMetadataReader.java:120)
      [junit] at org.hibernate.envers.configuration.EntitiesConfigurator.configure(EntitiesConfigurator.java:77)
      [junit] at org.hibernate.envers.configuration.AuditConfiguration.<init>(AuditConfiguration.java:86)
      [junit] at org.hibernate.envers.configuration.AuditConfiguration.getFor(AuditConfiguration.java:99)
      [junit] at org.hibernate.envers.event.AuditEventListener.initialize(AuditEventListener.java:249)
      [junit] at org.hibernate.event.EventListeners$1.processListener(EventListeners.java:198)
      [junit] at org.hibernate.event.EventListeners.processListeners(EventListeners.java:181)
      [junit] at org.hibernate.event.EventListeners.initializeListeners(EventListeners.java:194)
      [junit] ... 103 more

      It looks like Envers isn't finding anything to audit? I'm basing this assumption on the fact the same thing happens if I completely remove the @Audited annotation from the three classes mentioned above. However, I know the SessionFactory is finding my NP class because if I change my Spring config and use the name NPFoo it complains that it cannot find it. I also know my regular JPA/Hibernate annotations are correct because my integration tests pass and my app runs just fine (when the Envers listener is not present).

      I looked into turning on some logging, but there does not appear to be any. Any suggestions (solutions would be even better) would be greatly appreciated.

      Thanks,
      Jamie

        • 1. Re: NPE in AuditedPropertiesReader.addPropertiesFromClass()
          adamw

          It's hard to say unfortunately with just a stacktrace. I don't have much experience with Spring (well, none ;) ), but there's a link to a blog in the FAQ on how to use Envers+Spring.

          Regarding the NPE, it's quite weird ;) Maybe you could debug to see what arguments are passed to the addPropertiesFromClass method?

          Adam

          • 2. Re: NPE in AuditedPropertiesReader.addPropertiesFromClass()
            hernanbolido

            Hi!

            We have the same problem using hibernate 3.3.2GA and envers 1.2.1GA.
            We downloaded the source code and debugged the problem and found that the method addPropertiesFromClass(XClass) from class AuditedPropertiesReader is recursive and the base case is when the superclass of the parameter class is java.lang.Object.
            The problem is that if the parameter is an interface rather than a class, the super class is null and...

            private void addPropertiesFromClass(XClass clazz) {
            XClass superclazz = clazz.getSuperclass();
            if (!"java.lang.Object".equals(superclazz.getName())) {
            addPropertiesFromClass(superclazz);
            }

            addFromProperties(clazz.getDeclaredProperties("field"), "field", fieldAccessedPersistentProperties);
            addFromProperties(clazz.getDeclaredProperties("property"), "property", propertyAccessedPersistentProperties);
            }


            We have an association to an mapped interface. We solve the problem patching envers verifying that the superclass is not null too. But we dont know if it is allright.

            Any suggestions? I think that I´ve already read this problem somewhere... But dont remember where...

            Thanks, Hernan.

            • 3. Re: NPE in AuditedPropertiesReader.addPropertiesFromClass()
              adamw

              Ah, this could be a bug. Can you post a JIRA issue?

              Thanks,
              Adam

              • 4. Re: NPE in AuditedPropertiesReader.addPropertiesFromClass()
                hernanbolido

                Hi!

                Adam, we created the jiira issue.

                http://opensource.atlassian.com/projects/hibernate/browse/HHH-4063


                We attached a test case and explained our solucion for the problem.


                Do you know if there is going to be a fix version of envers before the hibernate 3.5 release?


                Thanks for this great module!

                Hernan.

                • 5. Re: NPE in AuditedPropertiesReader.addPropertiesFromClass()
                  hernanbolido

                  We realized that our solution only solves the NullPointerException, but still do not care about interfaces.

                  For example, if B is "subinterface" of A, during the process of extracting the audited metadata, AuditedPropertiesReader do not extract the metadata from interface A as a superinterface of B. So you can loose audited properties...

                  We can extend the AuditedPropertiesReader in order to treat this... What do you think about?

                  • 6. Re: NPE in AuditedPropertiesReader.addPropertiesFromClass()
                    adamw

                    Sure, I guess interfaces should be inspected also. If you can, please create a patch and attach to the jira issue.

                    Adam