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]

_______________________________________________
jboss-user mailing list
jboss-user@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to