如何在JPA EntityManager查询上设置超时期限

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

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>

代码在我的线程的运行功能中超时:

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();

}

}

我收到的超时错误:

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:

<property name="javax.persistence.query.timeout" value="1000"/>

通过持久性创建EntityManagerFactory时,也可以赋予相同的属性。createEntityManagerFactory。

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

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

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

以上是 如何在JPA EntityManager查询上设置超时期限 的全部内容, 来源链接: utcz.com/qa/410712.html

回到顶部