在EntityManager查询上设置超时

我目前正从EntityManager查询中获取连接超时错误。 是否可以为这些设置超时?

persistence.xml中

   org.eclipse.persistence.jpa.PersistenceProvider call.structure.Task call.structure.Installation call.structure.Contents call.structure.Recipient call.structure.CallTask call.structure.SmsTask call.structure.EmailTask call.security.User call.structure.content.Content call.structure.content.RecordContent call.structure.content.WaitContent call.structure.content.TextContent call.structure.content.VariableContent call.structure.content.SoundContent call.structure.content.SubjectContent call.structure.content.FileContent call.structure.Bounce         

代码在我的线程的run函数中超时:

 private class TaskDB extends Thread { private final long WAITING_TIME = 20000L; @Override public void run() { Set remove = SMSManager.this.getRemoveTask(); Set normal = SMSManager.this.getNormalTask(); try { while(true){ EntityManager em = DB.getEM(); //Calls EntityManagerFactory.createEntityManager() em.getTransaction().begin(); Set normalClone = new HashSet(normal); // Abort task in futur. List taskToRemove = new ArrayList(); 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) 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 taskResults = (List) 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(); } } 

我得到的超时错误:

 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 [...] 

是的,有javax.persistence.query.timeout 。 根据JPA 2.0规范支持此查询提示是可选的:

便携式应用程序不应该依赖这个提示。 根据使用的持久性提供程序和数据库,可能会也可能不会显示提示。

对于所有查询,可以将缺省值(以毫秒为单位)设置为persistence.xml:

  

通过Persistence创建EntityManagerFactory时也可以给出相同的属性。 createEntityManagerFactory 。

它也可以为每个查询覆盖/设置:

 query.setHint("javax.persistence.query.timeout", 2000); 

可以通过NamedQuery中的属性提示获得相同的function。