Search code examples
javahibernateexceptionrunnablejta

How do I manage hibernate transactions in a timertask?


I am currently trying to make a hibernate query inside of a TimerTask (Runnable). This task makes no saves or updates to the database. It just retrieves a list of jobs. Anytime I run this task, I get HibernateException: Unable to locate current JTA transaction.

I believe this has to do with the fact that it's being started from a runnable because I use this same query outside of this TimerTask.

I can't share the code I am working with because it is for work and proprietary. My research on this issue has only really led me to solutions with Spring, but I am not able to use Spring for this work.

I will attempt to make some pseudo code.

public class JobManager extends TimerTask {
    @Override
    public void run() {
        ...
        List<String> jobs = Handler.getJobs();
        ...
    }
}

public class Handler {
    public static List<String> getJobs() {
        return DAO.getJobs();
    }
}

public class DAO {
    public List<Object> getJobs() {
        try {
            session = HibernateManager.getSessionFactory().getCurrentSession();
            Query myQuery = session.createQuery("query string");

            List = myQuery.list();

        } catch(HibernateException he) {
            log.error(he);
        }

        return list;
    }
}

The exception occurs when the runnable calls getJobs(). This method work everywhere else outside of the TimerTask.

I understand that this is limited information to work with. I can try to accommodate for any other information if it is needed.


Solution

  • I believe every transaction has some time out, so you can not put the regular timer task code inside the running transaction. As it is just reading the data you wont need to start the transaction, just session is enough

    I have encountered the same problem and solved by creating the new session

    session = sessionFactory.openSession();
    

    EDIT

    session.getCurrentSession() takes the current session from the current thread, so it wont work inside timer task. Use openSession()