Announcement Announcement Module
Collapse
No announcement yet.
Using Hibernate Configuration to register an EventListener Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using Hibernate Configuration to register an EventListener

    I'm trying to use the Hibernate Configuration class to register a LoadEventListener, however I'm having trouble getting the configuration from the LocalSessionFactoryBean.

    I've tried the solution in this post,
    http://forum.springframework.org/showthread.php?t=12871


    When I run my test case I get a BeanCreationException (trace below)

    Code:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateConfiguration' defined in class path resource [WEB-INF/applicationContextHibernate.xml]: Cannot find matching factory method 'getConfiguration' on class [$Proxy0]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:479)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:314)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:223)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:147)
    	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:536)
    	at au.com.groupware.dao.BaseDAOTestCase.setUp(BaseDAOTestCase.java:56)
    	at au.com.groupware.dao.PlaceNameDAOTest.setUp(PlaceNameDAOTest.java:17)
    	at junit.framework.TestCase.runBare(TestCase.java:125)
    	at junit.framework.TestResult$1.protect(TestResult.java:106)
    	at junit.framework.TestResult.runProtected(TestResult.java:124)
    	at junit.framework.TestResult.run(TestResult.java:109)
    	at junit.framework.TestCase.run(TestCase.java:118)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:421)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:305)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:186)
    Has anyone come across this before? Essentially what I want to do is register Hibernate events and event listeners within spring.

    This is my hibernate application context mappings....

    Code:
    <!-- Hibernate SessionFactory -->
    	<bean id="sessionFactory"
    		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource">
    			<ref bean="dataSource" />
    		</property>
    		<property name="mappingResources">
    			<list>
    				<value>User.hbm.xml</value>
    				<value>Role.hbm.xml</value>
    			</list>
    		</property>
    		<!-- Define Hibernate and C3P0 connection pooling properties-->
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
    <!--				<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>-->
    				<prop key="hibernate.hbm2ddl.auto">update</prop>
    				<prop key="hibernate.show_sql">false</prop>
    				<prop key="hibernate.c3p0.minPoolSize">5</prop>
    				<prop key="hibernate.c3p0.maxPoolSize">20</prop>
    				<prop key="hibernate.timeout">300</prop>
    				<prop key="hibernate.max_statement">50</prop>
    			</props>
    		</property>
    		<property name="entityInterceptor"><ref local="auditLogInterceptor"/></property> 
    	</bean>
    	
    	<bean
          id="hibernateConfiguration"
          factory-bean="sessionFactory"
          factory-method="getConfiguration"
       	/>
    Last edited by robyn; May 16th, 2006, 03:19 AM.

  • #2
    Re: Using Hibernate Configuration to register an EventListen

    AFAIK the method is not declared by SessionFactory, but on the Factory bean. So you have to reference the factory bean itself, which can be done by prefixing the bean name with a "&".

    This should work:

    Code:
    	<bean
          id="hibernateConfiguration"
          factory-bean="&amp;sessionFactory"
          factory-method="getConfiguration"
       	/>
    Regards,
    Andreas

    Comment


    • #3
      Re: Using Hibernate Configuration to register an EventListen

      Thanks Andreas - that solved the problem and my event listener is being set in the hibernate configuration. Well it at least appears to have been!

      Even though the listeners are being set, they don't seem to be listening!.

      I have a BaseDAOTestCase that registers the event listeners in the hibernate configuration via the setUp() method. See below:

      Code:
      // Get configuration to set up event listeners        
              Configuration configuration = &#40;Configuration&#41;ctx.getBean&#40;"hibernateConfiguration"&#41;;       
              configuration.getSessionEventListenerConfig&#40;&#41;.setLoadEventListener&#40;new LoadListener&#40;&#41;&#41;;
              configuration.getSessionEventListenerConfig&#40;&#41;.setSaveOrUpdateEventListener&#40;new SaveListener&#40;&#41;&#41;;      
              configuration.getSessionEventListenerConfig&#40;&#41;.setPreDeleteEventListener&#40;new AuditPreDeleteEventListener&#40;&#41;&#41;;

      I then have various DAO test cases that extend the BaseDAOTestCase. These make load, save and delete calls and I'm expecting the listeners to be called on these events, however at the moment nothing seems to be happening...

      These are two if the listener classes


      Code:
      public class LoadListener extends DefaultLoadEventListener
      &#123;
         protected static Log log = LogFactory.getLog&#40;LoadListener.class&#41;;
         
         public Object onLoad&#40;LoadEvent event, LoadEventListener.LoadType loadType&#41;
         						throws HibernateException &#123;
            
            log.debug&#40;"Load event called" + event.toString&#40;&#41;&#41;;
                  
            return super.onLoad&#40;event, loadType&#41;;
         &#125;
            
      &#125;
      Code:
      public class AuditPreDeleteEventListener extends
            DefaultPreDeleteEventListener &#123;
      
         public boolean onPreDelete&#40;final PreDeleteEvent e&#41; &#123;
            
            System.out.println&#40;"onPreDeleteEvent triggered" + e.toString&#40;&#41;&#41;;
            super.onPreDelete&#40;e&#41;;
            
            return false;
         &#125;
      &#125;
      Am I missing something ??? :oops:

      Thanks, Jon

      Comment


      • #4
        I'm not sure about this. But as far as I remember, changes to the Configuration will have no impact on a SessionFactory that has already been created. So I would guess you need to register the listeners first and create the SessionFactory afterwards.

        Regards,
        Andreas

        Comment


        • #5
          Thanks Adreas, I'm making progress. What you said makes sense.

          So now I'm going back to trying to declare the listeners in the applicationContect.xml by declaring a map of listeners and then giving that to the setEventListeners() method of the LocalSessionFactoryBean.

          This is my sessionFactory mapping along with a loadListener bean definition that is being set in the map.

          Code:
          <bean id="loadListener" class="org.hibernate.event.def.DefaultLoadEventListener" />
          		
              <!-- Hibernate SessionFactory -->
          	<bean id="sessionFactory"
          		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
          		<property name="eventListeners">
          			<map>
          				<entry key="loadEventListener"><ref local="loadListener" /></entry>
          			</map>
          		</property>
          		
          		<property name="dataSource">
          			<ref bean="dataSource" />
          		</property>
          		<property name="mappingResources">
          			<list>
          				<value>au/com/groupware/model/User.hbm.xml</value>
          				<value>au/com/groupware/model/Role.hbm.xml</value>
          
          			</list>
          		</property>
          		<!-- Define Hibernate and C3P0 connection pooling properties-->
          		<property name="hibernateProperties">
          			<props>
          				<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
          <!--				<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>-->
          				<prop key="hibernate.hbm2ddl.auto">update</prop>
          				<prop key="hibernate.show_sql">false</prop>
          				<prop key="hibernate.c3p0.minPoolSize">5</prop>
          				<prop key="hibernate.c3p0.maxPoolSize">20</prop>
          				<prop key="hibernate.timeout">300</prop>
          				<prop key="hibernate.max_statement">50</prop>
          			</props>
          		</property>
          		<property name="entityInterceptor"><ref local="auditLogInterceptor"/></property> 
          	</bean>
          When I reload my application it seems like hibernate is trying to load the listener, however it doesn't recognise the listener type. This is the start up message...see the last line...

          Code:
          INFO&#58; Reloading this Context has started
          log4j&#58;WARN No appenders could be found for logger &#40;net.sf.ehcache.CacheManager&#41;.
          log4j&#58;WARN Please initialize the log4j system properly.
          14/07/2005 09&#58;13&#58;45 org.apache.catalina.loader.WebappClassLoader validateJarFile
          INFO&#58; validateJarFile&#40;C&#58;\Apache\Tomcat\webapps\gnr\WEB-INF\lib\servlet.jar&#41; - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class&#58; javax/servlet/Servlet.class
          WARN - Configurator.configure&#40;126&#41; | No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath&#58; file&#58;/C&#58;/Apache/Tomcat/work/Catalina/localhost/gnr/loader/ehcache-failsafe.xml
          WARN - Configuration.setListener&#40;1389&#41; | Unrecognized listener type &#91;loadEventListener&#93;
          The spring API for the setEventListeners() method states that the map needs to be set with the listener type as the key and the listener object as the value

          Specify the Hibernate event listeners to register, with listener types as keys and listener objects as values.

          See the Hibernate documentation for further details on listener types and associated listener interfaces.
          I'm struggling to find the right values to place in the map to get hibernate to recognise the listeners...any ideas?

          Thanks, Jon

          Comment


          • #6


            Well pretty much straight after posting that last reply the answer dawned on me and as usual it was staring me in the face.

            The listener type is simply "load" (as stated in the hibernate reference) and the object is an instance of my load listener implementation (or a default).

            I was originally thinking that the type is the name of the listener class, but it's not, it's just "load".

            I can't find any reference that lists these types, i.e, "delete", "save" etc but I'll keep looking.

            For those interested, below is my final applicationContext that registers a hibernate load event listener...

            Code:
            <bean id="loadListener" class="org.hibernate.event.def.DefaultLoadEventListener" />
            		
            		
                <!-- Hibernate SessionFactory -->
            	<bean id="sessionFactory"
            		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            		<property name="eventListeners">
            			<map>
            				<entry key="load"><ref local="loadListener" /></entry>
            			</map>
            		</property>
            		
            		<property name="dataSource">
            			<ref bean="dataSource" />
            		</property>
            		<property name="mappingResources">
            			<list>
            				<value>au/com/groupware/model/User.hbm.xml</value>
            				<value>au/com/groupware/model/Role.hbm.xml</value>
            
            			</list>
            		</property>
            		<!-- Define Hibernate and C3P0 connection pooling properties-->
            		<property name="hibernateProperties">
            			<props>
            				<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
            				<prop key="hibernate.hbm2ddl.auto">update</prop>
            				<prop key="hibernate.show_sql">false</prop>
            				<prop key="hibernate.c3p0.minPoolSize">5</prop>
            				<prop key="hibernate.c3p0.maxPoolSize">20</prop>
            				<prop key="hibernate.timeout">300</prop>
            				<prop key="hibernate.max_statement">50</prop>
            			</props>
            		</property>
            		<property name="entityInterceptor"><ref local="auditLogInterceptor"/></property> 
            	</bean>

            Comment

            Working...
            X