Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set the timeout period on a JPA EntityManager query

I'm currently getting connection timeout errors from my EntityManager queries. Is it possible to set a timeout for these?

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="CallPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>call.structure.Task</class>
    <class>call.structure.Installation</class>
    <class>call.structure.Contents</class>
    <class>call.structure.Recipient</class>
    <class>call.structure.CallTask</class>
    <class>call.structure.SmsTask</class>
    <class>call.structure.EmailTask</class>
    <class>call.security.User</class>
    <class>call.structure.content.Content</class>
    <class>call.structure.content.RecordContent</class>
    <class>call.structure.content.WaitContent</class>
    <class>call.structure.content.TextContent</class>
    <class>call.structure.content.VariableContent</class>
    <class>call.structure.content.SoundContent</class>
    <class>call.structure.content.SubjectContent</class>
    <class>call.structure.content.FileContent</class>
    <class>call.structure.Bounce</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@127.0.0.1:1521:TEST"/>
      <property name="javax.persistence.jdbc.password" value="userpassword"/>
      <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
      <property name="javax.persistence.jdbc.user" value="username"/>
    </properties>
   </persistence-unit>
</persistence>

Code times out in the run function of my thread:

private class TaskDB extends Thread {

    private final long WAITING_TIME = 20000L;

    @Override
    public void run() {

        Set<SmsTask> remove = SMSManager.this.getRemoveTask();
        Set<SmsTask> normal = SMSManager.this.getNormalTask();

        try {
            while(true){
                EntityManager em = DB.getEM();  //Calls EntityManagerFactory.createEntityManager()
                em.getTransaction().begin();

                Set<SmsTask> normalClone = new HashSet<SmsTask>(normal);
                // Abort task in futur.
                List<SmsTask> taskToRemove = new ArrayList<SmsTask>();
                if (!remove.isEmpty()) {

                    String queryString = "SELECT t FROM SmsTask t WHERE t.id IN :remove ";
                    if (!normalClone.isEmpty())
                        queryString += "AND t.id NOT IN :normal ";

                    Query query = em.createQuery(queryString);
                    query.setParameter("remove", Utils.taskToIdList(remove));
                    if (!normalClone.isEmpty())
                        query.setParameter("normal", Utils.taskToIdList(normalClone));

                    taskToRemove = (List<SmsTask>) query.getResultList();
                    for (SmsTask task : taskToRemove) {
                        removedTask.add(task);
                        remove.remove(task);
                    }
                }

                String queryString = "SELECT t FROM SmsTask t WHERE (t.scheduleTime IS NULL OR t.scheduleTime < :dateNow) AND t.status = co.dium.call.structure.Task.StatusTask.NOT_START ";
                if (!taskToRemove.isEmpty())
                    queryString += "AND t.id NOT IN :toRemove ";

                Query query = em.createQuery(queryString);
                query.setParameter("dateNow", Utils.obtainUniversalTime());
                if (!taskToRemove.isEmpty())
                    query.setParameter("toRemove", Utils.taskToIdList(taskToRemove));
                List<SmsTask> taskResults = (List<SmsTask>) query.getResultList();

                em.getTransaction().commit();

                for (SmsTask task : taskResults) 
                    addTask(task);

                SMSManager.TaskRemove.sleep(WAITING_TIME);
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(SMSManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println("Thread interrompu !");
        Thread.currentThread().interrupt();
    }
}

The timeout errors that I get:

org.clipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLRecoverableException: I/O error: Socket read timed out
Error Code: 17002
Call: [....sql query...]
[...]
at org.eclipse.persistence.internal.EJBQueryImpl.getResultList(EJBQueryImpl.java:742)
at call.manager.sms.SMSManager$TaskDB.run(SMSManager.java:367)
Caused by: java.sql.SQLRecoverableException: I/O Error: Scoket read timed out
[...]
like image 461
James Avatar asked Jun 16 '14 13:06

James


People also ask

What is default timeout JPA?

The JPA query hint is a Java Persistence provider customization option. . getResultList(); The timeout value is defined in milliseconds, so the JPQL query above will time out after 50 milliseconds unless the result set is being fetched prior to the timeout threshold.

How to set Flush mode in JPA?

If you want to use the FlushModeTypes AUTO or COMMIT, which are defined by the JPA specification, you can call the setFlushMode method on your Query or TypedQuery interface. Query q = em. createQuery( "SELECT p from ChessPlayer p" ); q.

What is Hibernate timeout?

Hibernate Timeout lets you set the amount of time the printer waits after a print job is processed before it goes into a reduced power state.


1 Answers

There are two ways you can set up the query timeout period with Hibernate.

The Hibernate-specific way

If you are bootstrapping Hibernate natively or if you are unwrapping the JPA java.persistence.Query to its org.hibernate.query.Query equivalent, then you can just use the setTimeout method:

List<Post> posts = entityManager
.createQuery(
    "select p " +
    "from Post p " +
    "where lower(p.title) like lower(:titlePattern)", Post.class)
.setParameter("titlePattern", "%Hibernate%")
.unwrap(org.hibernate.query.Query.class)
.setTimeout(1)
.getResultList();

Notice that the setTimeout method takes an int argument which specifies the timeout value in seconds.

The JPA query hint way

You can also use a JPA query hint, as illustrated in the following example:

List<Post> posts = entityManager
.createQuery(
    "select p " +
    "from Post p " +
    "where lower(p.title) like lower(:titlePattern)", Post.class)
.setParameter("titlePattern", "%Hibernate%")
.setHint("javax.persistence.query.timeout", 50)
.getResultList();

Notice that the javax.persistence.query.timeout query hint takes the timeout value in milliseconds.

The Hibernate query hint way

You can also use the org.hibernate.timeout query hint:

List<Post> posts = entityManager
.createQuery(
    "select p " +
    "from Post p " +
    "where lower(p.title) like lower(:titlePattern)", Post.class)
.setParameter("titlePattern", "%Hibernate%")
.setHint("org.hibernate.timeout", 1)
.getResultList();

Notice that the org.hibernate.timeout query hint takes the timeout value in seconds.

like image 103
Vlad Mihalcea Avatar answered Sep 22 '22 16:09

Vlad Mihalcea