[jboss-user] [EJB 3.0] - Possible Bug with EJB 3 Timers

Andrig Miller do-not-reply at jboss.com
Thu Apr 29 12:42:26 EDT 2010


Andrig Miller [http://community.jboss.org/people/andy.miller%40jboss.com] created the discussion

"Possible Bug with EJB 3 Timers"

To view the discussion, visit: http://community.jboss.org/message/540195#540195

--------------------------------------------------------------
I have recently added an EJB 3 Timer to my application, and in testing it out, the timer never expired, and called the method in the stateless session bean that has the @Timeout annotation.

Here is the code:

package services.ejb;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import services.ejb.OrderManager;
import services.entities.Address;
import services.entities.Customer;
import services.entities.Order;
import services.entities.OrderLine;
import services.exceptions.CreateDataException;

@Stateless
public class OrderManagerBean implements OrderManager {

    @Resource
    TimerService timerService;
    
    @PersistenceContext (unitName="services")
    protected EntityManager entityManager;

...
public void createOrderPurgeTimer(boolean runWithTimer) throws CreateDataException {
        
        for (Object object : timerService.getTimers()) {
            Timer timer = (Timer) object;
            timer.cancel();
        }
        
        if (runWithTimer) {
            long twentyFourHours = 1000 * 60 * 60 * 24;
            timerService.createTimer(twentyFourHours, twentyFourHours, null);
        }
        
        return;
        
    }
    
    @Timeout
    public void purgeOldOrders(Timer timer) {
        
        // Delete the previous days worth of orders
        
        Query query = entityManager.createNativeQuery("delete from Order where orderDate < :date");
        
        Calendar now = Calendar.getInstance();
        
        // Back up to the top of the hour, so we only delete orders from the previous period'
        
        now.set(Calendar.MINUTE, 0);
        now.set(Calendar.SECOND, 0);
        
        query.setParameter("date", new Date(now.getTimeInMillis()));
        query.executeUpdate();
        
        return;
        
    }

}

In the above stateless session bean, I have a method to create the timer, and the one that is the callback when the timer should expire.  It creates a single timer that should expire every twenty four hours, so the initial expiration, and the interval are both set to 24 hours.  I have a servlet that calls the method to create the timer, along with other reference data needed for the application, and I can see the timer has been persisted in the database, and here is what it looks like:

TIMERID = 1272464496401, TARGETID = [target=jboss.j2ee:ear=OrderManagerApp.ear,jar=OrderManagerEJB.jar,name=OrderManagerBean,service=EJB3], INITIALDATE=2010-04-29 08:26:29, TIMERINTERVAL=86400000, INSTANCEPK=NULL, INFO=NULL

So, I created the timer through the createOrderPurgeTimer method on the OrderManagerBean, and everything looks correct.  The INITIALDATE is 24 hours after I created it, and the TIMERINTERVAL is 24 hours in milliseconds, as I would expect.

So, I was expecting, after allowing the application to run all day and night, that at 8:26:49 this morning (the INITIALDATE) the timer would expire, and call the purgeOldOrders method on the OrderManagerBean.

I know this didn't happen, because there is no error created from the method (maybe it failed), and because in looking at the invocation statistics from the JMX Console I see the following:

InvocationStatistics concurrentCalls='0'
method name='createOrderPurgeTimer' count='1' minTime='78' maxTime='78' totalTime='78' 
method name='createOrder' count='15' minTime='0' maxTime='4' totalTime='18'

As you can see, the only two methods called on the bean are the createOrderPurgeTimer, and the createOrder (I didn't include that method in the above code snippet).  No call to the purgeOldOrders method at all, and its more than 2 hours after the INITIALDATE that is in the TIMER table.

I don't believe I have done anything wrong in the code. 

--------------------------------------------------------------

Reply to this message by going to Community
[http://community.jboss.org/message/540195#540195]

Start a new discussion in EJB 3.0 at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2029]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-user/attachments/20100429/9d59fbe0/attachment.html 


More information about the jboss-user mailing list