1 2 Previous Next 25 Replies Latest reply: Sep 29, 2011 3:48 PM by Izabella Kleynshteyn RSS

CustomEnversListener and Spring

Izabella Kleynshteyn Newbie

I'm new to Envers, but was able to implement the basic auditing without problems. Now I'm trying to use my own table instead of REVINFO for saving the username. But no success !

 

My environment :

 

Hibernate 3.3.1  (not using config, but annotations instead)

Spring 2.6

Envers 1.2.2.GA

 

I created CustomEnversListener.java and  CustomRevisionEntity.java as suggested by specs, but auditing process is still looking for REVINFO.

What changes should I make in Spring application-config.xml under sessionFactory bean to register CustomEnversListener.java ?

 

 

   <property name="eventListeners">

            <map>

                <entry key="post-update">

                    <bean class="org.hibernate.envers.event.AuditEventListener">   ?????   

                           should I add  settings for CustomEnversListener here ?  If, yes, how ?

                    </bean>           
                </entry>
            </map>
        </property>

 

CustomRevisionEntity.java


package com.company.audit;


import org.hibernate.envers.RevisionEntity;
import org.hibernate.envers.RevisionNumber;
import org.hibernate.envers.RevisionTimestamp;

import javax.persistence.*;

@Entity
@Table(name = "revision_info")
@RevisionEntity(CustomEnversListener.class)
public class CustomRevisionEntity
{
    private int id;
    private long timestamp;    private String username = "test";

    @Id
    @RevisionNumber
    @Column(name = "revision_id", nullable = false, updatable = false)
    public int getId()
    {
        return id;
    }

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

    @RevisionTimestamp
    @Column(name = "revision_timestamp")
    public long getTimestamp()
    {
        return timestamp;
    }

    public void setTimestamp(long timestamp)
    {
        this.timestamp = timestamp;
    }

    @Column(name = "username")
    public String getUsername()
    {
        return username;
    }

    public void setUsername(String username)
    {
        this.username = username;
    }
}

CustomEnversListener.java

 

package com.company.audit;

 

import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContextHolder;
import org.hibernate.envers.RevisionListener;

public class CustomEnversListener implements RevisionListener
{
    public void newRevision(Object revisionEntity)
    {
        CustomRevisionEntity customRevisionEntity = (CustomRevisionEntity) revisionEntity;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        customRevisionEntity.setUsername(authentication.getName());
    }
}

 

The output looks like :

 

Hibernate: insert into REVINFO (REVTSTMP, REV) values (?, ?)

[ERROR] JDBCExceptionReporter GDS Exception. 335544569. Dynamic SQL Error

SQL error code = -204

Table unknown

 

 

REVINFO doesn't exist and revision_info (see at the top) has been created in Firebird 2.1.

 

Please help to solve this problem !

  • 1. Re: CustomEnversListener and Spring
    Hernán Chanfreau Master

    Hi!

     

    Make sure that your custom revision entity is included in hibernate' session factory. You can enable org.hibernate.cfg category on info level and verify this.

    I'm using spring + hibernate + envers with no problems.

     

    Regards. Hernán.

  • 2. Re: CustomEnversListener and Spring
    Izabella Kleynshteyn Newbie

    Thank you, Hernan !

    I understand I have to insert an entry inside sessionFactory, but can't figure out how it should look.

     

    How to specify AuditEventListener should use CustomEnversListener ?

     

    <bean name="customEnversListener" class="com.company.audit.CustomEnversListener"/>

     

    <sessionFactory ...>

            <property name="eventListeners">

                <map>

                    <entry key="post-update">

                        <bean class="org.hibernate.envers.event.AuditEventListener">

                               <map>

                                     <entry key="?" value-ref="customEnversListener"/>

                                <map>

                        </bean>           
                    </entry>
                </map>
            </property>

    </sessionFactory>

     

    Thank you.

    Izabella.

  • 3. Re: CustomEnversListener and Spring
    Hernán Chanfreau Master

    Hi!

     

    You should add your revision entity as any other normal entity in your system...

     

     

    Regards. Hernán.

  • 4. Re: CustomEnversListener and Spring
    Izabella Kleynshteyn Newbie

    Hi !

     

    I can't figure out the name of the property :

     

    <property name="???" class="org.hibernate.envers.event.CustomRevisionEntity"/>

     

    Thank you,

     

    Izabella.

  • 5. Re: CustomEnversListener and Spring
    Hernán Chanfreau Master

    Hi!

     

    I have the eventListeners like this:

     

    <property name="eventListeners">

        <map>

            <entry key="post-insert">

                <ref bean="enversAuditEventListener" />

            </entry>

            <entry key="post-update">

                <ref bean="enversAuditEventListener" />

            </entry>

            <entry key="post-delete">

                <ref bean="enversAuditEventListener" />

            </entry>

            <entry key="pre-collection-update">

                <ref bean="enversAuditEventListener" />

            </entry>

            <entry key="pre-collection-remove">

                <ref bean="enversAuditEventListener" />

            </entry>

            <entry key="post-collection-recreate">

                <ref bean="enversAuditEventListener" />

            </entry>

        </map>

    </property>

     

    and the enversAuditEventListener bean is:

     

    <bean id="enversAuditEventListener"

        class="bla.bla.MyCustomAuditEventListener">

    </bean>

     

    There is no info about the revision entity there.

     

    Regards. Hernán.

  • 6. Re: CustomEnversListener and Spring
    Izabella Kleynshteyn Newbie

    Hi Hernan,

     

    Before I opened this discussion I tried :

     

        <property name="eventListeners">

                <map>

                    <entry key="post-update">

                        <bean class="com.company.audit.CustomEnversListener">  

                        </bean>           
                    </entry>
                </map>
            </property>

     

    but it didn't work giving error in sessionFactory bean.

     

    Thank you again for sharing your knowledge.

     

    Best regards,

     

    Izabella.

     

    I will tru your way (no difference, but ...)

  • 7. Re: CustomEnversListener and Spring
    Izabella Kleynshteyn Newbie

    I made changes as Hernan suggested, but getting an exception :

     

     

    <bean id="enversAuditEventListener" class="com.company.audit.CustomEnversListener"/>

     

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

    ...

        <property name="eventListeners">

            <map>

                <entry key="post-update">

                    <ref bean="enversAuditEventListener" />

                </entry>

            </map>

        </property>

    ...

    </bean>

     

     

     

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource

    [/WEB-INF/conf/application-context.xml]: Invocation of init method failed; nested exception is java.lang.ArrayStoreException: com.company.audit.CustomEnversListener

    Caused by:

    java.lang.ArrayStoreException: com.company.audit.CustomEnversListener

            at org.hibernate.cfg.Configuration.setListener(Configuration.java:1722)

            at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:734)

  • 8. Re: CustomEnversListener and Spring
    Hernán Chanfreau Master

    Hi!

     

    I remember this exception from somewhere. Here are some posts about the same problem:

     

    http://community.jboss.org/message/527953#527953

    http://community.jboss.org/message/529020#529020

     

     

    I hope it will be helpful.

     

    Regards. Hernán.

  • 9. Re: CustomEnversListener and Spring
    Izabella Kleynshteyn Newbie

    Hi Hernan ! Thank you for links, but looks like my problem is different : I don't work with collections via listener, just simpe fields.

     

    But I have a such question : in my CustomRevisionEntity timestamp is long, and in table itself it's bigint. Could this cause the problem ?

     

    public class ArrayStoreException
    extends RuntimeException

    Thrown to indicate that an attempt has been made to store the wrong type of object into an array of objects. For example, the following code generates an ArrayStoreException:

         Object x[] = new String[3]; x[0] = new Integer(0); 
  • 10. Re: CustomEnversListener and Spring
    Izabella Kleynshteyn Newbie

    In my pom file I have :

     

    <properties>
        <org.apache.lucene.version>2.4.1</org.apache.lucene.version>   
        <org.hibernate.version>3.3.1.GA</org.hibernate.version>
        <org.hibernate.annotations.version>3.4.0.GA</org.hibernate.annotations.version>
        <org.hibernate.search.version>3.1.0.GA</org.hibernate.search.version>
        <org.springframework.version>2.0.6</org.springframework.version>
    </properties>

     

     

            <dependency>
                <groupId>antlr</groupId>
                <artifactId>antlr</artifactId>
                <version>2.7.6</version>
            </dependency>
            <dependency>
                <groupId>asm</groupId>
                <artifactId>asm</artifactId>
                <version>2.2.3</version>
            </dependency>
            <dependency>
                <groupId>asm</groupId>
                <artifactId>asm-attrs</artifactId>
                <version>2.2.3</version>
            </dependency>
            <dependency>
                <groupId>asm</groupId>
                <artifactId>asm-commons</artifactId>
                <version>2.2.3</version>
            </dependency>
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib-nodep</artifactId>           
                <version>2.2</version>
            </dependency>
            <dependency>
                <groupId>net.sourceforge.jexcelapi</groupId>
                <artifactId>jxl</artifactId>
                <version>2.6</version>
            </dependency>
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>3.2</version>
            </dependency>
            <dependency>
                <groupId>commons-beanutils</groupId>
                <artifactId>commons-beanutils</artifactId>
                <version>1.7.0</version>
            </dependency>
            <dependency>
                <groupId>commons-dbcp</groupId>
                <artifactId>commons-dbcp</artifactId>
                <version>1.2.2</version>
            </dependency>
            <dependency>
                <groupId>commons-digester</groupId>
                <artifactId>commons-digester</artifactId>
                <version>1.8.1</version>
            </dependency>
            <dependency>
                <groupId>commons-httpclient</groupId>
                <artifactId>commons-httpclient</artifactId>
                <version>3.0.1</version>
            </dependency>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>1.4</version>
            </dependency>
            <dependency>
                <groupId>commons-lang</groupId>
                <artifactId>commons-lang</artifactId>
                <version>2.3</version>
            </dependency>
            <dependency>
                <groupId>commons-pool</groupId>
                <artifactId>commons-pool</artifactId>
                <version>1.3</version>
            </dependency>

     

            <dependency>
                <groupId>dom4j</groupId>
                <artifactId>dom4j</artifactId>
                <version>1.6.1</version>
            </dependency>
            <dependency>
                <groupId>ehcache</groupId>
                <artifactId>ehcache</artifactId>
                <version>1.3.0</version>
            </dependency>
            <dependency>
                <groupId>firebirdsql</groupId>
                <artifactId>jaybird</artifactId>
                <version>2.1.1</version>
            </dependency>
            <dependency>
                <groupId>hsqldb</groupId>
                <artifactId>hsqldb</artifactId>
                <version>1.8.0.7</version>
            </dependency>
            <dependency>
                <groupId>com.lowagie</groupId>
                <artifactId>itext</artifactId>
                <version>1.3.1</version>
            </dependency>
            <dependency>
                <groupId>jasperreports</groupId>
                <artifactId>jasperreports</artifactId>
                <version>1.3.4</version>
                <exclusions>
                    <exclusion>
                        <groupId>commons-digester</groupId>
                        <artifactId>commons-digester</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>commons-collections</groupId>
                        <artifactId>commons-collections</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>commons-logging</groupId>
                        <artifactId>commons-logging</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>com.lowagie</groupId>
                        <artifactId>itext</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>jfree</groupId>
                        <artifactId>jcommon</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>jfree</groupId>
                        <artifactId>jfreechart</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>eclipse</groupId>
                        <artifactId>jdtcore</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>javassist</groupId>
                <artifactId>javassist</artifactId>
                <version>3.8.0.GA</version>
            </dependency>
            <dependency>
                <groupId>javax.transaction</groupId>
                <artifactId>jta</artifactId>
                <version>1.0.1B</version>
            </dependency>
            <dependency>
                <groupId>javax.persistence</groupId>
                <artifactId>persistence-api</artifactId>
                <version>1.0</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.4</version>
            </dependency>
            <dependency>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
                <version>1.4</version>
            </dependency>
            <dependency>
                <groupId>json</groupId>
                <artifactId>json-lib</artifactId>
                <version>2.0</version>
            </dependency>
            <dependency>
                <groupId>json</groupId>
                <artifactId>ezmorph</artifactId>
                <version>1.0.3</version>
            </dependency>
            <dependency>
                <groupId>org.acegisecurity</groupId>
                <artifactId>acegi-security</artifactId>
                <version>1.0.6</version>
                <exclusions>
                  <exclusion>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-core</artifactId>
                  </exclusion>
                  <exclusion>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-jdbc</artifactId>
                  </exclusion>
                  <exclusion>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-remoting</artifactId>
                  </exclusion>
                  <exclusion>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-support</artifactId>
                  </exclusion>
                  <exclusion>
                       <groupId>log4j</groupId>
                       <artifactId>log4j</artifactId>
                  </exclusion>
                </exclusions>
            </dependency>

     

            <!-- Lucene -->

     

            <dependency>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-core</artifactId>
                <version>${org.apache.lucene.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.lucene</groupId>
                <artifactId>lucene-queries</artifactId>
                <version>${org.apache.lucene.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.wicket.wicket-security</groupId>
                <artifactId>swarm</artifactId>
                <version>1.4.1</version>
            </dependency>
           

     

            <!-- Hibernate -->

     

            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
                <version>${org.hibernate.version}</version>
                <exclusions>
                  <exclusion>
                      <groupId>asm</groupId>
                      <artifactId>asm</artifactId>
                  </exclusion>
                  <exclusion>
                      <groupId>asm</groupId>
                      <artifactId>asm-attrs</artifactId>
                  </exclusion>
                  <exclusion>
                      <groupId>cglib</groupId>
                      <artifactId>cglib</artifactId>
                  </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-annotations</artifactId>
                <version>${org.hibernate.annotations.version}</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-commons-annotations</artifactId>
                <!--version>3.1.0.GA</version-->
                <version>3.3.0.ga</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-search</artifactId>
                <version>${org.hibernate.search.version}</version>
            </dependency>

     

            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.5.2</version>
            </dependency>
           
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.5.2</version>
            </dependency>

     

            <!-- Hibernate Envers -->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
                <version>3.4.0.GA</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-tools</artifactId>
                <version>3.2.3.GA</version>
            </dependency>
            <dependency>
                <groupId>org.testng</groupId>
                <artifactId>testng</artifactId>
                <version>5.8</version>
                <scope>test</scope>
            </dependency>
            <!--dependency>
                <groupId>org.hibernate.java-persistence</groupId>
                <artifactId>jpa-api</artifactId>
                <version>2.0.Beta2</version>
            </dependency-->
            <dependency>
                <groupId>ant</groupId>
                <artifactId>ant</artifactId>
                <version>1.6.5</version>
            </dependency>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <version>1.2.125</version>
                <scope>test</scope>
            </dependency>
            <dependency>
               <groupId>org.jboss.envers</groupId>
               <artifactId>jboss-envers</artifactId>
               <version>1.2.2.GA-hibernate-3.3</version>
            </dependency>

     

            <!-- Spring Framework -->

     

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${org.springframework.version}</version>
                <exclusions>
                  <exclusion>
                      <groupId>cglib</groupId>
                      <artifactId>cglib</artifactId>
                  </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-dao</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-hibernate3</artifactId>
                <version>${org.springframework.version}</version>
                <exclusions>
                  <exclusion>
                      <groupId>org.hibernate</groupId>
                      <artifactId>hibernate</artifactId>
                  </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-ibatis</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.ldap</groupId>
                <artifactId>spring-ldap</artifactId>
                <version>1.2.1</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-mock</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-remoting</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-support</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
  • 11. Re: CustomEnversListener and Spring
    Izabella Kleynshteyn Newbie

    I found an interesting thread on web :

     

    http://webcache.googleusercontent.com/search?q=cache:j_AHzSAf-dAJ:www.javafreedom.org/%3Fp%3D414+java.lang.ArrayStoreException+and+envers&cd=4&hl=en&ct=clnk&gl=us

     

    Inside it  :

     

    your Custom Event Listener should not appear in the Events, e.g. do not do:

    <prop key="hibernate.ejb.event.post-update"> org.hibernate.ejb.event.EJB3PostUpdateEventListener,de.xxx.RevListener </prop> 

    This will lead to an exception like

    Caused by: org.hibernate.MappingException: Unable to instantiate specified event (post-update) listener class: de.xxx.RevListener at org.hibernate.cfg.Configuration.setListeners(Configuration.java:1766) at org.hibernate.ejb.Ejb3Configuration.setListeners(Ejb3Configuration.java:1550) at org.hibernate.ejb.EventListenerConfigurator.setProperties(EventListenerConfigurator.java:183) at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1085) at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:685) at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417) ... 53 more Caused by: java.lang.ArrayStoreException: de.xxx.RevListener at org.hibernate.cfg.Configuration.setListeners(Configuration.java:1763) 
  • 12. Re: CustomEnversListener and Spring
    Izabella Kleynshteyn Newbie

    I tried to check the consistency for jars, and not able to find any conflict. But java.lang.ArrayStoreException persists.

     

    This problem persists only for the listener, created manually. I'm not able to find the problem, so probably will refuse from this nice software.

     

     


  • 13. Re: CustomEnversListener and Spring
    Adam Warski Master

    Hmm, I think you don't need to create a CustomEnversListener. Just create another completely normal entity (CustomRevisionEntity) and annotate it with @RevisionEntity. No changes in xml config should be needed.

     

    Adam

  • 14. Re: CustomEnversListener and Spring
    Izabella Kleynshteyn Newbie

    Thanks, Adam, I will try this way. Do I need to register AuditEventListener in this case ?

1 2 Previous Next