title: How to set the timeout period on a JPA EntityManager query
body: <p>I'm currently getting connection timeout errors from my EntityManager queries. Is it possible to set a timeout for these?</p>
  
  <p>persistence.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;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"&gt;
    &lt;persistence-unit name="CallPU" transaction-type="RESOURCE_LOCAL"&gt;
      &lt;provider&gt;org.eclipse.persistence.jpa.PersistenceProvider&lt;/provider&gt;
      &lt;class&gt;call.structure.Task&lt;/class&gt;
      &lt;class&gt;call.structure.Installation&lt;/class&gt;
      &lt;class&gt;call.structure.Contents&lt;/class&gt;
      &lt;class&gt;call.structure.Recipient&lt;/class&gt;
      &lt;class&gt;call.structure.CallTask&lt;/class&gt;
      &lt;class&gt;call.structure.SmsTask&lt;/class&gt;
      &lt;class&gt;call.structure.EmailTask&lt;/class&gt;
      &lt;class&gt;call.security.User&lt;/class&gt;
      &lt;class&gt;call.structure.content.Content&lt;/class&gt;
      &lt;class&gt;call.structure.content.RecordContent&lt;/class&gt;
      &lt;class&gt;call.structure.content.WaitContent&lt;/class&gt;
      &lt;class&gt;call.structure.content.TextContent&lt;/class&gt;
      &lt;class&gt;call.structure.content.VariableContent&lt;/class&gt;
      &lt;class&gt;call.structure.content.SoundContent&lt;/class&gt;
      &lt;class&gt;call.structure.content.SubjectContent&lt;/class&gt;
      &lt;class&gt;call.structure.content.FileContent&lt;/class&gt;
      &lt;class&gt;call.structure.Bounce&lt;/class&gt;
      &lt;properties&gt;
        &lt;property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@127.0.0.1:1521:TEST"/&gt;
        &lt;property name="javax.persistence.jdbc.password" value="userpassword"/&gt;
        &lt;property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/&gt;
        &lt;property name="javax.persistence.jdbc.user" value="username"/&gt;
      &lt;/properties&gt;
     &lt;/persistence-unit&gt;
  &lt;/persistence&gt;
  </code></pre>
  
  <p>Code times out in the run function of my thread:</p>
  
  <pre><code>private class TaskDB extends Thread {
  
      private final long WAITING_TIME = 20000L;
  
      @Override
      public void run() {
  
          Set&lt;SmsTask&gt; remove = SMSManager.this.getRemoveTask();
          Set&lt;SmsTask&gt; normal = SMSManager.this.getNormalTask();
  
          try {
              while(true){
                  EntityManager em = DB.getEM();  //Calls EntityManagerFactory.createEntityManager()
                  em.getTransaction().begin();
  
                  Set&lt;SmsTask&gt; normalClone = new HashSet&lt;SmsTask&gt;(normal);
                  // Abort task in futur.
                  List&lt;SmsTask&gt; taskToRemove = new ArrayList&lt;SmsTask&gt;();
                  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&lt;SmsTask&gt;) 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 &lt; :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&lt;SmsTask&gt; taskResults = (List&lt;SmsTask&gt;) 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();
      }
  }
  </code></pre>
  
  <p>The timeout errors that I get:</p>
  
  <pre><code>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
  [...]
  </code></pre>