Search code examples
javahibernateentitytimertask

How to update Entity in TimerTask in Hibernate


I want to update an Entity Field after 2min (10sec in the code below for testing). The code runs without any exception and the message there is printed but the entity is not really updated. What may be the problem? Here's the code I used:

 @Transactional
public void scheduleTimer(UserSMSEntity userSMSEntity) {
    Timer timer = new Timer();
    TimerTask timerTask = new TimerTask() {
        @Override
        @Transactional
        public void run() {
            userSMSEntity.lastSMSCode = -1;
            update(userSMSEntity);
            System.out.println("TIMER TASK");
        }
    };
    timer.schedule(timerTask, 10000);
}

and here's the code for "update" method:

@Transactional
public void update(T entity) {
    entity.setLastModificationDate(new Date());
    entityManager.merge(entity);
    logger.debug(entity.toString() + " Updated!");
}

EDIT : I fixed it using bellow code inside the Timer Task

 Session session = sessionFactory.openSession();
            session.beginTransaction();
            UserSMSEntity userSMSEntity = getEntityByUserId(userId);
            UserSMSEntity userSMSEntity1 = entityManager.find(UserSMSEntity.class, userSMSEntity.getId());
            userSMSEntity1.lastSMSCode = -1;
            session.update(userSMSEntity1);
            session.getTransaction().commit();
            session.close();

here's how I used sessionFactory with autowired :

@Autowired
 SessionFactory session;

and in applicationContext I Declared a Bean as bellow :

 <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="moduleDataSource" />
    <property name="hibernateProperties">
        <props>

            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
        </props>
    </property>


    <property name="packagesToScan"
              value="you package"/>
</bean>

Solution

  • 1) you work inside one transaction , method update() not transactional for method scheduleTimer(). @Transactional is not applied for update() - as it selfinvocation inside one proxy.

    2) entity is updated only at the end of method scheduleTimer() when trasaction is committed and you can't see changes till the transaction is commited. So if you try read parallel userSMSEntity you don't see this changes.

    Also if UserSMSEntity is coming into scheduleTimer method as persistent, then this entityManager.merge(entity) method call does not have effect on it