Announcement Announcement Module
Collapse
No announcement yet.
Hibernate 3.2 Persistent Lifecycle annotations not work Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hibernate 3.2 Persistent Lifecycle annotations not work

    Hi Guys

    I experience some strange problem with the
    @PrePersist @PreUpdate ... @Post* ... annotations on my persistent entities.
    The annotated methods are just not invoked.

    I think i have configured them correctly , i have run my application with TopLink , and everything worked fine , then i switched to Hibernate and suddenly they stopped working.
    I tried to search the web in order to find a solution to this mysterious problem , but it seems i am the only one in the whole world that has this problem.
    Maybe you guys have heard about something like this.

    I will include one of my entities and the appcontext , you might find a problem in it.


    HTML Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    				http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
    				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
    				default-autowire="byName">
    
    	<!-- +++++++++++++++++++++++++++++++++++++++++ -->
    	<!-- dataSource initialization -->
    	<!-- +++++++++++++++++++++++++++++++++++++++++ -->
    
    	<bean id="dataSource"
    		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName" value="${database.driver}" />
    		<property name="url" value="${database.url}" />
    		<property name="username" value="${database.user}" />
    		<property name="password" value="${database.password}" />
    	</bean>
    
    	<bean
    		class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
    
    	<!-- +++++++++++++++++++++++++++++++++++++++++ -->
    	<!-- Definition of the TransactionManager -->
    	<!-- +++++++++++++++++++++++++++++++++++++++++ -->
    	 
    	<tx:annotation-driven transaction-manager="transactionManager"/>
    
       
    	<bean id="transactionManager"
    		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory">
    			<ref local="sessionFactory" />
    		</property>
    		<property name="dataSource" ref="dataSource" />
    
    	</bean>
    
    	<bean id="testBean" class="testPack.TestBean" >
    		<property name="dao" ref="jpaDao" />
    	</bean>
    
    
    
    	<bean id="sessionFactory"
    		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    		<property name="annotatedClasses">
    			<list>
    				<value>entities.Event</value>
    			</list>
    		</property>
    		<property name="annotatedPackages">
    			<list>
    				<value>entities</value>
    			</list>
    		</property>
    
    		<property name="dataSource" ref="dataSource" />
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">
    					${hibernate.dialect}
    				</prop>
    				<prop key="hibernate.hbm2ddl.auto">
    					${hibernate.hbm2ddl.auto}
    				</prop>
    				<prop key="hibernate.show_sql">
    					${hibernate.show_sql}
    				</prop>
    				<prop key="hibernate.format_sql">
    					${hibernate.format_sql}
    				</prop>
    				<prop key="hibernate.use_sql_comments">
    					${hibernate.use_sql_comments}
    				</prop>
    				<prop key="hibernate.generate_statistics">
    					${hibernate.generate_statistics}
    				</prop>
    				<prop key="hibernate.transaction.factory_class">
    					org.hibernate.transaction.JDBCTransactionFactory
    				</prop>
    				<prop key="hibernate.current_session_context_class">
    					${hibernate.current_session_context_class}
    				</prop>
    				
    			</props>
    		</property>
    	</bean>
    
    
    	<bean id="dao" class="testPack.EventSpringDao">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    	
    	<bean id="jpaDao" class="testPack.JpaCommonDao"/>
    
    	<bean id="propertyConfigurator"
    		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    		<property name="location">
    			<value>classpath:/META-INF/config/project.properties</value>
    		</property>
    	</bean>
    
    </beans>
    HTML Code:
    package entities;
    
    import java.io.Serializable;
    import java.util.Date;
    
    import javax.persistence.Entity;
    import javax.persistence.Table;
    
    import org.springframework.beans.factory.annotation.Configurable;
    
    @Entity
    @Table(name = "EVENT")
    public class Event extends PersistentEntity implements Serializable {
        
    	private int duration;
        
        private String name;
        
        private Date startDate;
    
        private Event(){}
    
        public Event(int duarion) {
            this.duration = duarion;
        }
    
        public String getName() { return name; }
        public void setName(String name) { this.name = name;   }
        public Date getStartDate() { return startDate; }
        public void setStartDate(Date startDate) { this.startDate = startDate; }
    
        public int getDuration() { return duration; }
        public void setDuration(int duration) { this.duration = duration; }
    
    
    	@PostPersist
    	public void kuku(){
    		System.out.println("JUST PRINT THIS !!!! : " + duration);
    
    	}
    
    }

    Thanks a lot in advance ....

  • #2
    did you find your problem ? I have exactly the same problem

    Comment


    • #3
      As much as i understood Hibernate has no native support for these annotations
      you will have to register a event listener to hibernates events listerners

      HTML Code:
      	<bean id="sessionFactory"
      		class="com.siemens.aci.extensions.server.configurationmgmt.session.CustomAnnotationSessionFactoryBean">
      		<property name="dataSource">
      			<ref local="dataSource" />
      		</property>
      		
      		<property name="persistentPackages">
      			<list>
      				<value>${persistent.pack}</value>
      				<value>com.siemens.aci.extensions.server.configurationmgmt.services.access.impl</value>
      			</list>		
      		</property>
      		<property name="entityCallbackHandler" ref="entityCallbackHandler"/>
      		
      
      		<property name="hibernateProperties">
      			<props>
      				<prop key="hibernate.dialect">
      					${hibernate.dialect}
      				</prop>
      				<prop key="hibernate.hbm2ddl.auto">
      					${hibernate.hbm2ddl.auto}
      				</prop>
      				<prop key="hibernate.show_sql">
      					${hibernate.show_sql}
      				</prop>
      				<prop key="hibernate.format_sql">
      					${hibernate.format_sql}
      				</prop>
      				<prop key="hibernate.use_sql_comments">
      					${hibernate.use_sql_comments}
      				</prop>
      				<prop key="hibernate.generate_statistics">
      					${hibernate.generate_statistics}
      				</prop>
      				<prop key="hibernate.current_session_context_class">
      					${hibernate.current_session_context_class}
      				</prop>
      				
      				
      			</props>
      		</property>
          	<property name="eventListeners">
            	<map>
              	<entry key="create" 		value-ref="persistEventListener" />
              	<entry key="save" 			value-ref="saveEventListener" />
              	<entry key="delete" 		value-ref="deleteEventListener" />
              	<entry key="flush" 			value-ref="flushEventListener" />
              	<entry key="auto-flush" 	value-ref="autoFlushEventListener" />
              	<entry key="flush-entity" 	value-ref="flushEntityEventListener" />
              	<entry key="merge" 			value-ref="mergeEventListener" />
              	<entry key="create-onflush" value-ref="createOnFlushEventListener" />
              	<entry key="save-update" 	value-ref="saveUpdateEventListener" />
            	</map>
          	</property>
      	</bean>
      	
      	
      	<!-- +++++++++++++++++++++++++++++++++++++++++ -->
      	<!-- Hibernate event listeners initialization -->
      	<!-- +++++++++++++++++++++++++++++++++++++++++ -->
      	<bean id="persistEventListener" 
      		class="org.hibernate.ejb.event.EJB3PersistEventListener">
      		<property name="callbackHandler" ref="entityCallbackHandler"/>
      	</bean>
      
      	<bean id="saveEventListener" 
      		class="org.hibernate.ejb.event.EJB3SaveEventListener">
      		<property name="callbackHandler" ref="entityCallbackHandler"/>
      	</bean>
      	
      	<bean id="deleteEventListener" 
      		class="org.hibernate.ejb.event.EJB3DeleteEventListener">
      		<property name="callbackHandler" ref="entityCallbackHandler"/>
      	</bean>
      	
      	<bean id="flushEventListener" 
      		class="org.hibernate.ejb.event.EJB3FlushEventListener">
      	</bean>
      	
      	
      	<bean id="autoFlushEventListener" 
      		class="org.hibernate.ejb.event.EJB3AutoFlushEventListener">
      	</bean>
      	
      	<bean id="flushEntityEventListener" 
      		class="org.hibernate.ejb.event.EJB3FlushEntityEventListener">
      		<property name="callbackHandler" ref="entityCallbackHandler"/>
      	</bean>
      	
      	
      	<bean id="mergeEventListener" 
      		class="org.hibernate.ejb.event.EJB3MergeEventListener">
      		<property name="callbackHandler" ref="entityCallbackHandler"/>
      	</bean>
      	
      	
      	<bean id="createOnFlushEventListener" 
      		class="org.hibernate.ejb.event.EJB3PersistOnFlushEventListener">
      		<property name="callbackHandler" ref="entityCallbackHandler"/>
      	</bean>
      	
      	<bean id="saveUpdateEventListener" 
      		class="org.hibernate.ejb.event.EJB3SaveOrUpdateEventListener">
      		<property name="callbackHandler" ref="entityCallbackHandler"/>
      	</bean>
      	
      	<bean id="entityCallbackHandler" 
      		class="org.hibernate.ejb.event.EntityCallbackHandler">
      	</bean>
      	
      dont pay attention to the my sessionfactory implementation , it extends the normal AnnotationSessionFactory

      Comment


      • #4
        entityCallbackHandler property in AnnotationSessionFactoryBean

        Hi

        There is no property entityCallbackHandler in AnnotationSessionFactoryBean

        Code:
        <property name="entityCallbackHandler" ref="entityCallbackHandler"/>
        is it the reason with you have a custom AnnotationSessionFactoryBean

        Regards

        Comment


        • #5
          I've been struggling with this couple days and finally i have pretty ellegant solution. Just configure Hibernate as EntityManager and then create simple wrapper bean that calls entityManagerFactory.getSessionFactory():
          Code:
          public class EntityManagerSessionFactoryFactory implements FactoryBean {
          
              private HibernateEntityManagerFactory entityManagerFactory;
          
              @Override
              public Object getObject() throws Exception {
                  return (entityManagerFactory).getSessionFactory();
              }
           
              @Override
              public Class getObjectType() {
                  return SessionFactory.class;
              }
          
              @Override
              public boolean isSingleton() {
                  return true;
              }
          
              @Required
              public void setEntityManagerFactory(HibernateEntityManagerFactory entityManagerFactory) {
                  this.entityManagerFactory = entityManagerFactory;
              }
          }
          And the application context:
          HTML Code:
              <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
                  <property name="dataSource" ref="dataSource" />
                  <property name="persistenceUnitName" value="${persistence.unit}" />
                  <property name="jpaVendorAdapter">
                      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                          <property name="showSql" value="${show.sql}" />
                          <property name="databasePlatform" value="cz.mycompany.orm.hibernate.dialects.OurOracle10GDialect" />
                      </bean>
                  </property>
              </bean>
          
              <bean id="sessionFactory" class="cz.mycompany.orm.hibernate.EntityManagerSessionFactoryFactory">
                  <property name="entityManagerFactory" ref="entityManagerFactory" />
              </bean>
          And that's it.
          OK, maybe this is not universal solution, because you need to configure the persistence unit, but we already use JPA for other projects with the same domain objects so I've got it for free.

          Comment


          • #6
            Hi,

            I just tried pavel.zupa solution but I get the No CurrentSessionContext configured! HibernateException when accessing the database.

            Code:
            org.hibernate.HibernateException: No CurrentSessionContext configured!
            	at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:693)
            	at com.myapp.dao.hibernate.UserDaoImpl.getUserByLoginAndPasswd(UserDaoImpl.java:78)
            	at com.myapp.dao.hibernate.SmsDaoImpl.saveSms(SmsDaoImpl.java:82)
            	at com.myapp.service.SmsService.saveSms(SmsService.java:20)
            	at com.myapp.service.SmsService$$FastClassByCGLIB$$e3d31140.invoke(<generated>)
            	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
            	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
            	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
            	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
            	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
            	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
            	at com.myapp.service.SmsService$$EnhancerByCGLIB$$56318952.saveSms(<generated>)
            	at com.myapp.service.SmsServiceTest.testSaveSms(SmsServiceTest.java:49)
            	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            	at java.lang.reflect.Method.invoke(Method.java:597)
            	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
            	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
            	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
            	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
            	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
            	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
            	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
            	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
            	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
            	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
            	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
            	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
            	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
            	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
            	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
            	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
            	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
            	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
            	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
            	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

            Comment

            Working...
            X