Announcement Announcement Module
Collapse
No announcement yet.
How to use an hibernate interceptor with spring Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to use an hibernate interceptor with spring

    I want to use my own hibernate interceptor to achieve history functions in my database tables.

    My question is how to make spring to use the interceptor.

    The messege i get is :'Bean with name 'personDAOTarget' concluding interceptor chain is not an advisor class: treating it as a target or TargetSourc', and the methods of the interceptor are not called.

    The interceptor i created extends org.springframework.orm.hibernate.HibernateInterce ptor

    I added the following to the applicationContext.

    <bean id="myHibernateInterceptor" class="org.appfuse.MyInterceptor">
    <property name="sessionFactory"><ref local="sessionFactory"/></property>
    </bean>

    <bean id="personDAOTarget" class="org.appfuse.dao.hibernate.PersonDAOHibernat e">
    <property name="sessionFactory"><ref local="sessionFactory"/></property>
    </bean>

    <bean id="personDAO" class="org.springframework.aop.framework.ProxyFact oryBean">
    <property name="proxyInterfaces">
    <value>org.appfuse.dao.PersonDAO</value>
    </property>
    <property name="interceptorNames">
    <list>
    <value>myHibernateInterceptor</value>
    <value>personDAOTarget</value>
    </list>
    </property>
    </bean>

    Regards,
    Rene Boere

  • #2
    If you want to use your own HibernateInterceptor, use the entityInterceptor property of Spring's LocalSessionFactoryBean.

    Hibernate interceptors are quite separate from Spring's AOP framework.

    Comment


    • #3
      But is there a way with spring to tell hibernate to use an interceptor each time it opens a session ?

      Comment


      • #4
        Since version 1.1, you can use an entityInterceptorBeanName, and the hibernateInterceptor will request a new Hibernate Interceptor for each request. If you set your entity interceptor to singleton="false", a new entity interceptor will be created for each request.

        Code:
        <beans>
            ...
        
            <bean id="myHibernateInterceptor" 
                class="org.springframework.orm.hibernate.HibernateInterceptor">
                <property name="sessionFactory">
                    <ref bean="mySessionFactory"/>
                </property>
        	<property name="entityInterceptorBeanName">
                    <value>myEntityInterceptor</value>
        	</property>
            </bean>
        
            <bean id="myEntityInterceptor" class="mypackage.MyEntitiyInterceptor" singleton="false"/>
        
            ...
        </beans>
        If you want to access request specific information, I recommend not to follow this approach but instead call a class where that request-specific information, such as the current user, is currently stored in a threadlocal object.

        Cheers, Stefaan

        Comment


        • #5
          There is a naming problem here. I don't want to use spring's HibernateInterceptor but I want to use hibernate's Interceptor which is call on some hibernate events (save/update/delete).

          The hibernate docs says that I have to pass this interceptor to the session when I create it but with spring I have no access to the session creation : this is my problem

          Comment


          • #6
            Yeah, it is really confusing. My reply did indeed speak about hibernate's interceptor, I call it the entity interceptor. You normally configure this entity interceptor (hibernate class) which you define the HibernateInterceptor, which is a Spring AOP interceptor for Hibernate. In that HibernateInterceptor, you set the entityInterceptorBeanName.

            Hope this clearifies

            Comment


            • #7
              Hi,

              I've the same requirement that i would like to record some history information when the a record in the table is inserted/updated/deleted (CRUD). I'm trying to implement as discussed here....the spring way.

              I've the AuditLogInterceptor class that implements Interceptor as follows:

              Code:
              public class AuditLogRecordInterceptor implements Interceptor &#123;
              .....
              ......
              
              	public void postFlush&#40;Iterator arg0&#41; throws CallbackException &#123;
              		try &#123;
              			for&#40;Iterator itr = inserts.iterator&#40;&#41;; itr.hasNext&#40;&#41;; &#41; &#123;
              				Auditable entity = &#40;Auditable&#41;itr.next&#40;&#41;;
              				AuditLog.logEvent&#40;"create", entity, "testuser"&#41;;
              			&#125;
              			for&#40;Iterator itr = updates.iterator&#40;&#41;; itr.hasNext&#40;&#41;; &#41; &#123;
              				Auditable entity = &#40;Auditable&#41;itr.next&#40;&#41;;
              				AuditLog.logEvent&#40;"update", entity, "testuser"&#41;;
              			&#125;
              		&#125; catch&#40;HibernateException e&#41; &#123;
              			
              		&#125; finally &#123;
              			inserts.clear&#40;&#41;;
              			updates.clear&#40;&#41;;
              		&#125;
              		
              	&#125;
              &#125;
              In this class i'm implementing the required methods such as OnSave, OnPostFlush etc as per the hibernate requirement.

              I also have a class called AuditLog an utility class as follows:

              Code:
              public class AuditLog &#123;
              	private SessionFactory sessionFactory;
              	
              	public void setSessionFactory&#40;SessionFactory sessionFactory&#41; &#123;
              		this.sessionFactory = sessionFactory;
              	&#125;
              	
              	public SessionFactory getSessionFactory&#40;&#41; &#123;
              		return sessionFactory;
              	&#125;
              	
              	public void logEvent&#40;String message, Auditable entity,
              							Long userId&#41; 
              								throws CallbackException &#123;
              		Session session = null;
              		
              		try &#123;
              			AuditLogRecord record = new AuditLogRecord&#40;message, entity.getId&#40;&#41;,
              								entity.getClass&#40;&#41;, userId&#41;;
              		    session = sessionFactory.openSession&#40;&#41;;
              			session.save&#40;record&#41;;
              			session.flush&#40;&#41;;
              		&#125; catch&#40;Exception ex&#41; &#123;
              			throw new CallbackException&#40;ex&#41;;
              		&#125; finally &#123;
              			try &#123;
              				session.close&#40;&#41;;
              			&#125; catch&#40;HibernateException ex&#41; &#123;
              				throw new CallbackException&#40;ex&#41;;				
              			&#125;
              		&#125;
              		
              	&#125;
              &#125;
              Here is my applicationContext.xml file (partial)

              Code:
              	    <!-- Hibernate SessionFactory 2 used for audit log-->
                  <bean id="sessionFactory2" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
                      <property name="dataSource"><ref local="dataSource"/></property>
               		<property name="mappingResources">
              			<list>
              				<value>com/apple/ermt/model/Project.hbm.xml</value>
              				<value>com/apple/ermt/model/ProjectResource.hbm.xml</value>
              				<value>com/apple/ermt/model/Resource.hbm.xml</value>
              				<value>com/apple/ermt/model/Requirement.hbm.xml</value>	
              				<value>com/apple/ermt/model/TestCase.hbm.xml</value>	
              				<value>com/apple/ermt/model/UseCase.hbm.xml</value>						
              			</list>
              		</property>
                  </bean>
               
              	<bean id="auditLogInterceptor" class="com.apple.ermt.persistence.audit.AuditLogInterceptor" singleton="false"/>
              	
              	<bean id="auditLog" class="com.apple.ermt.persistence.audit.AuditLog">
              		<property name="sessionFactory"><ref local="sessionFactory2"/></property>
              	</bean>
              	
                  <!-- Hibernate SessionFactory -->
                  <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
                      <property name="dataSource"><ref local="dataSource"/></property>
               		<property name="mappingResources">
              			<list>
              				<value>com/apple/ermt/model/Project.hbm.xml</value>
              				<value>com/apple/ermt/model/ProjectResource.hbm.xml</value>
              				<value>com/apple/ermt/model/Resource.hbm.xml</value>
              				<value>com/apple/ermt/model/Requirement.hbm.xml</value>	
              				<value>com/apple/ermt/model/TestCase.hbm.xml</value>	
              				<value>com/apple/ermt/model/UseCase.hbm.xml</value>						
              			</list>
              		</property>
                      <property name="hibernateProperties">
                      <props>
                          <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
                          <prop key="hibernate.hbm2ddl.auto">update</prop>
                      </props>
                      </property>  
                      <property name="entityInterceptor"><ref local="auditLogInterceptor"/></property>
                  </bean>
              ........
              ......
              My problem is that per the Hibernate in Action book, the AuditLog can have a static method called logEvent which can be used from the AuditLogRecord class to actually record the entry in the table. If i make this method STATIC, it can't access the instance variable sessionFactory being injected by Spring. The solution is to make this variable also STATIC. But i feel that this is WRONG. So do i need to have the logEvent method to be STATIC? If not, how else should i implement this?

              Could someone please share your experience?


              Thanks very much in advance.

              Comment


              • #8
                Just one correction.

                I've added the property "entityInterceptor" under the "transactionManager" bean.


                Thanks!

                Comment


                • #9
                  Why do you access AuditLog with static methods ? You've configured it using spring as a singleton, then there is no need to define static methods any more. Just add AuditLog as a property of your AuditLogInterceptor.

                  Actually, you don't need to configure the AuditLogInterceptor as a non-singleton. It's much simpler without singleton="false". If you say you configered it using the entityInterceptor property, there will be only one instance anyway. Only if you define it using the entityInterceptorBeanName, a new entityInterceptor on each new session.

                  If you need to get to the user information, I suggest using a "UserResolver" (interface returing a String getUser()) that looks up in a ThreadLocal the object. You only need to set it into the ThreadLocal by using a Servlet Filter for example. This is the suggested approach in the acegi security framework. This works in my project like a charm.

                  Good luck,
                  Stefaan.

                  Comment


                  • #10
                    Thanks Stefaan.

                    This is what i've done. As you said, i've added AuditLog as a property in the AuditLogRecordInterceptor as follows:

                    Code:
                    public class AuditLogRecordInterceptor implements Interceptor &#123;
                    	private Log log = LogFactory.getLog&#40;HibernateProjectDAO.class&#41;;
                    	
                    	private SessionFactory sessionFactory;
                    	private AuditLog  auditLog;
                    	
                    	private Set inserts = new HashSet&#40;&#41;;
                    	private Set updates = new HashSet&#40;&#41;;
                    	
                    
                    	public void setSessionFactory&#40;SessionFactory sessionFactory&#41; &#123;
                    		this.sessionFactory = sessionFactory;
                    	&#125;
                    	
                    	public SessionFactory getSessionFactory&#40;&#41; &#123;
                    		return this.sessionFactory;
                    	&#125;
                    
                    	public void setAuditLog&#40;AuditLog auditLog&#41; &#123;
                    		this.auditLog = auditLog;
                    	&#125;
                    
                    	public AuditLog getAuditLog&#40;&#41; &#123;
                    		return this.auditLog;
                    	&#125;
                    
                    	
                    	/* &#40;non-Javadoc&#41;
                    	 * @see net.sf.hibernate.Interceptor#onLoad&#40;java.lang.Object, java.io.Serializable, java.lang.Object&#91;&#93;, java.lang.String&#91;&#93;, net.sf.hibernate.type.Type&#91;&#93;&#41;
                    	 */
                    	public boolean onLoad&#40;Object arg0, Serializable arg1, Object&#91;&#93; arg2, String&#91;&#93; arg3, Type&#91;&#93; arg4&#41; throws CallbackException &#123;
                    		// TODO Auto-generated method stub
                    		return false;
                    	&#125;
                    
                    	/* &#40;non-Javadoc&#41;
                    	 * @see net.sf.hibernate.Interceptor#onFlushDirty&#40;java.lang.Object, java.io.Serializable, java.lang.Object&#91;&#93;, java.lang.Object&#91;&#93;, java.lang.String&#91;&#93;, net.sf.hibernate.type.Type&#91;&#93;&#41;
                    	 */
                    	public boolean onFlushDirty&#40;Object arg0, Serializable arg1, Object&#91;&#93; arg2, Object&#91;&#93; arg3, String&#91;&#93; arg4, Type&#91;&#93; arg5&#41; throws CallbackException &#123;
                    		if&#40;arg0 instanceof Auditable&#41;
                    			updates.add&#40;arg0&#41;;
                    		return false;
                    	&#125;
                    
                    	/* &#40;non-Javadoc&#41;
                    	 * @see net.sf.hibernate.Interceptor#onSave&#40;java.lang.Object, java.io.Serializable, java.lang.Object&#91;&#93;, java.lang.String&#91;&#93;, net.sf.hibernate.type.Type&#91;&#93;&#41;
                    	 */
                    	public boolean onSave&#40;Object arg0, Serializable arg1, Object&#91;&#93; arg2, String&#91;&#93; arg3, Type&#91;&#93; arg4&#41; throws CallbackException &#123;
                    		if&#40;arg0 instanceof Auditable&#41;
                    			inserts.add&#40;arg0&#41;;
                    		return false;
                    	&#125;
                    
                    	/* &#40;non-Javadoc&#41;
                    	 * @see net.sf.hibernate.Interceptor#onDelete&#40;java.lang.Object, java.io.Serializable, java.lang.Object&#91;&#93;, java.lang.String&#91;&#93;, net.sf.hibernate.type.Type&#91;&#93;&#41;
                    	 */
                    	public void onDelete&#40;Object arg0, Serializable arg1, Object&#91;&#93; arg2, String&#91;&#93; arg3, Type&#91;&#93; arg4&#41; throws CallbackException &#123;
                    		// TODO Auto-generated method stub
                    		
                    	&#125;
                    
                    	/* &#40;non-Javadoc&#41;
                    	 * @see net.sf.hibernate.Interceptor#preFlush&#40;java.util.Iterator&#41;
                    	 */
                    	public void preFlush&#40;Iterator arg0&#41; throws CallbackException &#123;
                    		// TODO Auto-generated method stub
                    		
                    	&#125;
                    
                    	/* &#40;non-Javadoc&#41;
                    	 * @see net.sf.hibernate.Interceptor#postFlush&#40;java.util.Iterator&#41;
                    	 */
                    	public void postFlush&#40;Iterator arg0&#41; throws CallbackException &#123;
                    		log.debug&#40;"In postFlush#########.."&#41;;
                    		
                    		try &#123;
                    			for&#40;Iterator itr = inserts.iterator&#40;&#41;; itr.hasNext&#40;&#41;; &#41; &#123;
                    				Auditable entity = &#40;Auditable&#41;itr.next&#40;&#41;;
                    				auditLog.logEvent&#40;"create", entity, new Long&#40;1&#41;, sessionFactory&#41;;
                    			&#125;
                    			for&#40;Iterator itr = updates.iterator&#40;&#41;; itr.hasNext&#40;&#41;; &#41; &#123;
                    				Auditable entity = &#40;Auditable&#41;itr.next&#40;&#41;;
                    				auditLog.logEvent&#40;"update", entity, new Long&#40;1&#41;, sessionFactory&#41;;
                    			&#125;
                    		&#125; catch&#40;HibernateException e&#41; &#123;
                    			
                    		&#125; finally &#123;
                    			inserts.clear&#40;&#41;;
                    			updates.clear&#40;&#41;;
                    		&#125;
                    		
                    	&#125;
                    
                    	/* &#40;non-Javadoc&#41;
                    	 * @see net.sf.hibernate.Interceptor#isUnsaved&#40;java.lang.Object&#41;
                    	 */
                    	public Boolean isUnsaved&#40;Object arg0&#41; &#123;
                    		// TODO Auto-generated method stub
                    		return null;
                    	&#125;
                    
                    	/* &#40;non-Javadoc&#41;
                    	 * @see net.sf.hibernate.Interceptor#findDirty&#40;java.lang.Object, java.io.Serializable, java.lang.Object&#91;&#93;, java.lang.Object&#91;&#93;, java.lang.String&#91;&#93;, net.sf.hibernate.type.Type&#91;&#93;&#41;
                    	 */
                    	public int&#91;&#93; findDirty&#40;Object arg0, Serializable arg1, Object&#91;&#93; arg2, Object&#91;&#93; arg3, String&#91;&#93; arg4, Type&#91;&#93; arg5&#41; &#123;
                    		// TODO Auto-generated method stub
                    		return null;
                    	&#125;
                    
                    	/* &#40;non-Javadoc&#41;
                    	 * @see net.sf.hibernate.Interceptor#instantiate&#40;java.lang.Class, java.io.Serializable&#41;
                    	 */
                    	public Object instantiate&#40;Class arg0, Serializable arg1&#41; throws CallbackException &#123;
                    		// TODO Auto-generated method stub
                    		return null;
                    	&#125;
                    	
                    	public void logEvent&#40;String message, Auditable entity, Long userId&#41; 
                    				throws CallbackException &#123;
                    		Session session = null;
                    		
                    		try &#123;
                    			AuditLogRecord record = new AuditLogRecord&#40;message, entity.getId&#40;&#41;,
                    							entity.getClass&#40;&#41;, userId&#41;;
                    			session = sessionFactory.openSession&#40;&#41;;
                    			session.save&#40;record&#41;;
                    			session.flush&#40;&#41;;
                    		&#125; catch&#40;Exception ex&#41; &#123;
                    			throw new CallbackException&#40;ex&#41;;
                    		&#125; finally &#123;
                    			try &#123;
                    				session.close&#40;&#41;;
                    			&#125; catch&#40;HibernateException ex&#41; &#123;
                    				throw new CallbackException&#40;ex&#41;;				
                    			&#125;
                    		&#125;
                    	&#125;
                    
                    
                    	
                    &#125;
                    The AuditLog is the util class which has the logEvent method that logs the event in the DB.

                    My Project.java extends Auditable interface.

                    Here's my latest applicationContext.xml.

                    Code:
                    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                    		<property name="driverClassName"><value>$&#123;hibernate.connection.driver_class&#125;</value></property>
                    		<property name="url"><value>$&#123;hibernate.connection.url&#125;</value></property>
                    		<property name="username"><value>$&#123;hibernate.connection.username&#125;</value></property>
                    		<property name="password"><value>$&#123;hibernate.connection.password&#125;</value></property> 
                    	</bean>
                    	
                    	    <!-- Hibernate SessionFactory 2 used for audit log-->
                        <bean id="sessionFactory2" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
                            <property name="dataSource"><ref local="dataSource"/></property>
                     		<property name="mappingResources">
                    			<list>
                    				<value>com/apple/ermt/model/Project.hbm.xml</value>
                    				<value>com/apple/ermt/model/ProjectResource.hbm.xml</value>
                    				<value>com/apple/ermt/model/Resource.hbm.xml</value>
                    				<value>com/apple/ermt/model/Requirement.hbm.xml</value>	
                    				<value>com/apple/ermt/model/TestCase.hbm.xml</value>	
                    				<value>com/apple/ermt/persistence/audit/AuditLogRecord.hbm.xml</value>	
                    				<value>com/apple/ermt/model/UseCase.hbm.xml</value>						
                    			</list>
                    		</property>
                        </bean>
                     
                     
                    	<bean id="auditLog" class="com.apple.ermt.persistence.audit.interceptor.AuditLog"/>
                    
                    	<bean id="auditLogRecord" class="com.apple.ermt.persistence.audit.AuditLogRecord"/>
                    
                        <!-- Hibernate SessionFactory -->
                        <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
                            <property name="dataSource"><ref local="dataSource"/></property>
                     		<property name="mappingResources">
                    			<list>
                    				<value>com/apple/ermt/model/Project.hbm.xml</value>
                    				<value>com/apple/ermt/model/ProjectResource.hbm.xml</value>
                    				<value>com/apple/ermt/model/Resource.hbm.xml</value>
                    				<value>com/apple/ermt/model/Requirement.hbm.xml</value>	
                    				<value>com/apple/ermt/model/TestCase.hbm.xml</value>	
                    				<value>com/apple/ermt/persistence/audit/AuditLogRecord.hbm.xml</value>	
                    				<value>com/apple/ermt/model/UseCase.hbm.xml</value>								</list>
                    		</property>
                            <property name="hibernateProperties">
                    		<props>
                    		    <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
                    		    <prop key="hibernate.hbm2ddl.auto">create</prop>
                    		</props>
                            </property>  
                        </bean>
                    
                    <!--
                    	<bean id="myHibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor">
                    	      <property name="sessionFactory"><ref local="sessionFactory2"/></property>
                    	      <property name="entityInterceptorBeanName"><value>auditLogInterceptor</value></property>
                    	</bean>
                     -->
                     
                    	<bean id="auditLogInterceptor" class="com.apple.ermt.persistence.audit.interceptor.AuditLogRecordInterceptor" singleton="false">
                    		<property name="auditLog"><ref local="auditLog"/></property>
                    	</bean>
                    
                        <!-- Transaction manager for a single Hibernate SessionFactory &#40;alternative to JTA&#41; -->
                        <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
                            <property name="sessionFactory"><ref local="sessionFactory"/></property>
                       		<property name="entityInterceptor"><ref local="auditLogInterceptor"/></property>    
                        </bean>

                    Please note that i'm wiring the interceptor through the transaction manager.

                    My problem is that, when i save the project, the interceptor never gets called.


                    Could someone please let me know what is that i'm missing?

                    Thanks in advance!

                    Comment


                    • #11
                      I fixed this problem by moving the "entityInterceptor" definition from "transactionManager" to "sessionFactory" bean! I passed the second sessionFactory to the auditLogInterceptor as follows:

                      Code:
                      	<bean id="auditLogInterceptor" class="com.apple.ermt.persistence.audit.interceptor.AuditLogRecordInterceptor">
                              <property name="sessionFactory"><ref local="sessionFactory2"/></property>
                      		<property name="auditLog"><ref local="auditLog"/></property>
                      	</bean>
                      My interceptor is getting called which in turn calls the AuditLog to log the event. In this, when it writes the record, i'm getting the following exception.

                      Code:
                      TableGenerator.generate&#40;103&#41; | could not read a hi value
                          &#91;junit&#93; java.sql.SQLException&#58; General error message from server&#58; "Table 'rmtdb.hibernate_unique_key' doesn't exist"
                          &#91;junit&#93;     at com.mysql.jdbc.MysqlIO.checkErrorPacket&#40;MysqlIO.java&#58;1997&#41;
                          &#91;junit&#93;     at com.mysql.jdbc.MysqlIO.sendCommand&#40;MysqlIO.java&#58;1167&#41;
                          &#91;junit&#93;     at com.mysql.jdbc.MysqlIO.sqlQueryDirect&#40;MysqlIO.java&#58;1278&#41;
                          &#91;junit&#93;     at com.mysql.jdbc.Connection.execSQL&#40;Connection.java&#58;2247&#41;
                          &#91;junit&#93;     at com.mysql.jdbc.PreparedStatement.executeQuery&#40;PreparedStatement.java&#58;1586&#41;
                          &#91;junit&#93;     at net.sf.hibernate.id.TableGenerator.generate&#40;TableGenerator.java&#58;93&#41;
                          &#91;junit&#93;     at net.sf.hibernate.id.TableHiLoGenerator.generate&#40;TableHiLoGenerator.java&#58;59&#41;
                          &#91;junit&#93;     at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier&#40;SessionImpl.java&#58;765&#41;
                          &#91;junit&#93;     at net.sf.hibernate.impl.SessionImpl.save&#40;SessionImpl.java&#58;738&#41;
                          &#91;junit&#93;     at com.apple.ermt.persistence.audit.interceptor.AuditLog.logEvent&#40;AuditLog.java&#58;30&#41;
                          &#91;junit&#93;     at com.apple.ermt.persistence.audit.interceptor.AuditLogRecordInterceptor.postFlush&#40;AuditLogRecordInterceptor.java&#58;103&#41;
                          &#91;junit&#93;     at net.sf.hibernate.impl.SessionImpl.postFlush&#40;SessionImpl.java&#58;2833&#41;
                          &#91;junit&#93;     at net.sf.hibernate.impl.SessionImpl.flush&#40;SessionImpl.java&#58;2237&#41;
                          &#91;junit&#93;     at com.apple.ermt.dao.test.BaseDAOTestCase.tearDown&#40;BaseDAOTestCase.java&#58;69&#41;
                          &#91;junit&#93;     at com.apple.ermt.dao.test.ProjectDAOTest.tearDown&#40;ProjectDAOTest.java&#58;24&#41;
                          &#91;junit&#93;     at junit.framework.TestCase.runBare&#40;TestCase.java&#58;130&#41;
                          &#91;junit&#93;     at junit.framework.TestResult$1.protect&#40;TestResult.java&#58;106&#41;
                          &#91;junit&#93;     at junit.framework.TestResult.runProtected&#40;TestResult.java&#58;124&#41;
                          &#91;junit&#93;     at junit.framework.TestResult.run&#40;TestResult.java&#58;109&#41;
                          &#91;junit&#93;     at junit.framework.TestCase.run&#40;TestCase.java&#58;118&#41;
                          &#91;junit&#93;     at junit.framework.TestSuite.runTest&#40;TestSuite.java&#58;208&#41;
                          &#91;junit&#93;     at junit.framework.TestSuite.run&#40;TestSuite.java&#58;203&#41;
                          &#91;junit&#93;     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run&#40;JUnitTestRunner.java&#58;289&#41;
                          &#91;junit&#93;     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch&#40;JUnitTestRunner.java&#58;656&#41;
                          &#91;junit&#93;     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main&#40;JUnitTestRunner.java&#58;558&#41;
                      My AuditLogRecord class is as follows:

                      Code:
                      /**
                       * * @hibernate.class
                       *  table="AUDIT_LOG"
                       *  mutable="false"
                       *
                       */
                      public class AuditLogRecord &#123;
                      	public String message;
                      	public Long entityId;
                      	public Class entityClass;
                      	public Long userId;
                      	public Date created;
                      	public Long id;
                      	
                      	/**
                      	 * @hibernate.id
                      	 *  column="AUDIT_LOG_ID"
                      	 *  generator-class="native"
                      	 *  unsaved-value="null"
                      	 *  type="long"
                      	 * 
                      	 * @return
                      	 */
                      	public Long getId&#40;&#41; &#123;
                      		return id;
                      	&#125;
                      	
                      	public void setId&#40;Long id&#41; &#123;
                      		this.id = id;
                      	&#125;
                      	/*
                      	 * @hibernate.property 
                      	 *  column="CREATED"
                      	 *  not-null="true"
                      	 *  type="java.util.Date"  
                      	 */
                      	public Date getCreated&#40;&#41; &#123;
                      		return created;
                      	&#125;
                      	
                      	public void setCreated&#40;Date created&#41; &#123;
                      		this.created = created;
                      	&#125;
                      	
                      	/**
                      	 * @hibernate.property
                      	 * column="ENTITY_CLASS"
                      	 * not-null="true"
                      	 * @return
                      	 */
                      	public Class getEntityClass&#40;&#41; &#123;
                      		return entityClass;
                      	&#125;
                      	public void setEntityClass&#40;Class entityClass&#41; &#123;
                      		this.entityClass = entityClass;
                      	&#125;
                      	
                      	/**
                      	 * @hibernate.property
                      	 * column="ENTITY_ID"
                      	 * not-null="true"
                      	 * @return
                      	 */
                      	public Long getEntityId&#40;&#41; &#123;
                      		return entityId;
                      	&#125;
                      	
                      	public void setEntityId&#40;Long entityId&#41; &#123;
                      		this.entityId = entityId;
                      	&#125;
                      	
                      	/**
                      	 * @hibernate.property
                      	 * column="MESSAGE"
                      	 * not-null="true"
                      	 * @return
                      	 */
                      	public String getMessage&#40;&#41; &#123;
                      		return message;
                      	&#125;
                      	public void setMessage&#40;String message&#41; &#123;
                      		this.message = message;
                      	&#125;
                      	
                      	/**
                      	 * @hibernate.property
                      	 * column="USER_ID"
                      	 * not-null="true"
                      	 * @return
                      	 */
                      	public Long getUserId&#40;&#41; &#123;
                      		return userId;
                      	&#125;
                      	public void setUserId&#40;Long userId&#41; &#123;
                      		this.userId = userId;
                      	&#125;
                      	AuditLogRecord&#40;&#41; &#123;&#125;
                      	
                      	public AuditLogRecord&#40;String message, 
                      							Long entityId,
                      									Class entityClass,
                      											Long userId&#41; &#123;
                      		this.message = message;
                      		this.entityId = entityId;
                      		this.entityClass = entityClass;
                      		this.userId = userId;
                      	&#125;
                      													
                      	
                      &#125;
                      In the Hibernate in Action book, it was recommended that i should NOT define the id property in this class. But as i'm using XDoclet to generate the hbm mapping file, i should have this property defined.


                      Could someone please let me know why i'm getting this exception?

                      Thanks!

                      Comment


                      • #12
                        I fixed this issue. The problem was that the sessionFactory2 bean definition didn't have the "hibernateProperties" property defined. Once i added, it worked.

                        Thanks!

                        Comment


                        • #13
                          Now that i've implemented the auditLogInterceptor, i would like to chain more than one interceptors in my Application. If i want to chain more than one interceptors, where should i wire them? Currently, i'm using the property "entityInterceptor".

                          Could someone please let me know how should i chain more than one interceptors?

                          Thanks!

                          Comment


                          • #14
                            Rene,

                            You probably need to use the composite pattern. Create a "CompositeInterceptor" that has as property a list of "interceptors". Then in all methods of the interface, delegate to the interceptors one by one in the sequence of the list.

                            BTW. Your "auditLogInterceptor" is still configured with singleton="false". There's no point in that.

                            Cheers, Stefaan.

                            Comment


                            • #15
                              Thanks Stefaan. Let me try this out.

                              p.s. I also removed the "single="false"" in the auditLogInterceptor

                              Comment

                              Working...
                              X