use of jakarta.persistence.QueryTimeoutException in project hibernate-orm by hibernate.
the class LockTest method testQueryTimeoutEMProps.
@Test
@RequiresDialect(OracleDialect.class)
@RequiresDialectFeature(DialectChecks.SupportsLockTimeouts.class)
public void testQueryTimeoutEMProps() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final Map<String, Object> timeoutProps = new HashMap<String, Object>();
// 1 sec timeout (should round up)
timeoutProps.put(HINT_SPEC_QUERY_TIMEOUT, 500);
final Lock lock = new Lock();
FutureTask<Boolean> bgTask = new FutureTask<>(() -> {
try {
// true (success) if LockTimeoutException occurred
AtomicBoolean timedOut = new AtomicBoolean();
doInJPA(this::entityManagerFactory, _entityManager -> {
log.info("testQueryTimeout: (BG) about to read write-locked entity");
// we should block on the following read
Lock lock2 = _entityManager.getReference(Lock.class, lock.getId());
// force entity to be read
lock2.getName();
log.info("testQueryTimeout: (BG) read write-locked entity");
try {
// we should block on the following read
Query query = _entityManager.createQuery("select L from Lock_ L where L.id < 10000 ");
query.setLockMode(LockModeType.PESSIMISTIC_READ);
List<Lock> resultList = query.getResultList();
// force entity to be read
String name = resultList.get(0).getName();
log.info("testQueryTimeout: name read =" + name);
} catch (QueryTimeoutException e) {
// success
log.info("testQueryTimeout: (BG) got expected timeout exception");
timedOut.set(true);
} catch (Throwable e) {
log.info("Expected LockTimeoutException but got unexpected exception", e);
}
}, timeoutProps);
return timedOut.get();
} finally {
// signal that we finished
latch.countDown();
}
});
Thread t = new Thread(bgTask);
t.setDaemon(true);
t.setName("Lock timeout Test (bg)");
try {
lock.setName("testQueryTimeout");
doInJPA(this::entityManagerFactory, em -> {
em.persist(lock);
});
doInJPA(this::entityManagerFactory, em -> {
Lock _lock = em.getReference(Lock.class, lock.getId());
em.lock(_lock, LockModeType.PESSIMISTIC_WRITE);
final Integer id = _lock.getId();
// force entity to be read
_lock.getName();
log.info("testQueryTimeout: got write lock");
try {
t.start();
// should return quickly on success
boolean latchSet = latch.await(20, TimeUnit.SECONDS);
assertTrue("background test thread finished (lock timeout is broken)", latchSet);
assertTrue("background test thread timed out on lock attempt", bgTask.get());
} catch (InterruptedException e) {
Thread.interrupted();
} catch (ExecutionException e) {
throw new AssertionError(e);
}
});
} finally {
awaitThenDelete("testQueryTimeoutEMProps", t, lock.getId());
}
}
use of jakarta.persistence.QueryTimeoutException in project hibernate-orm by hibernate.
the class LockTest method testQueryTimeout.
@Test
@RequiresDialect(OracleDialect.class)
@RequiresDialectFeature(DialectChecks.SupportsLockTimeouts.class)
public void testQueryTimeout() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final Lock lock = new Lock();
FutureTask<Boolean> bgTask = new FutureTask<>(() -> {
try {
// true (success) if LockTimeoutException occurred
AtomicBoolean timedOut = new AtomicBoolean();
doInJPA(this::entityManagerFactory, _entityManager -> {
log.info("testQueryTimeout: (BG) about to read write-locked entity");
// we should block on the following read
Lock lock2 = _entityManager.getReference(Lock.class, lock.getId());
// force entity to be read
lock2.getName();
log.info("testQueryTimeout: (BG) read write-locked entity");
try {
// we should block on the following read
Query query = _entityManager.createQuery("select L from Lock_ L where L.id < 10000 ");
query.setLockMode(LockModeType.PESSIMISTIC_READ);
// 1 sec timeout
query.setHint(HINT_SPEC_QUERY_TIMEOUT, 500);
List<Lock> resultList = query.getResultList();
// force entity to be read
String name = resultList.get(0).getName();
log.info("testQueryTimeout: name read =" + name);
} catch (QueryTimeoutException e) {
// success
log.info("testQueryTimeout: (BG) got expected timeout exception");
timedOut.set(true);
} catch (Throwable e) {
log.info("Expected LockTimeoutException but got unexpected exception", e);
}
});
return timedOut.get();
} finally {
// signal that we finished
latch.countDown();
}
});
Thread t = new Thread(bgTask);
t.setDaemon(true);
t.setName("Lock timeout Test (bg)");
try {
lock.setName("testQueryTimeout");
doInJPA(this::entityManagerFactory, em -> {
em.persist(lock);
});
doInJPA(this::entityManagerFactory, em -> {
Lock _lock = em.getReference(Lock.class, lock.getId());
em.lock(_lock, LockModeType.PESSIMISTIC_WRITE);
final Integer id = _lock.getId();
// force entity to be read
_lock.getName();
log.info("testQueryTimeout: got write lock");
try {
t.start();
// should return quickly on success
boolean latchSet = latch.await(20, TimeUnit.SECONDS);
assertTrue("background test thread finished (lock timeout is broken)", latchSet);
assertTrue("background test thread timed out on lock attempt", bgTask.get());
} catch (InterruptedException e) {
Thread.interrupted();
} catch (ExecutionException e) {
throw new AssertionError(e);
}
});
} finally {
awaitThenDelete("testQueryTimeout", t, lock.getId());
}
}
use of jakarta.persistence.QueryTimeoutException in project hibernate-orm by hibernate.
the class ExceptionConverterImpl method convert.
@Override
public RuntimeException convert(HibernateException exception, LockOptions lockOptions) {
if (exception instanceof StaleStateException) {
final PersistenceException converted = wrapStaleStateException((StaleStateException) exception);
handlePersistenceException(converted);
return converted;
} else if (exception instanceof LockAcquisitionException) {
final PersistenceException converted = wrapLockException(exception, lockOptions);
handlePersistenceException(converted);
return converted;
} else if (exception instanceof LockingStrategyException) {
final PersistenceException converted = wrapLockException(exception, lockOptions);
handlePersistenceException(converted);
return converted;
} else if (exception instanceof org.hibernate.PessimisticLockException) {
final PersistenceException converted = wrapLockException(exception, lockOptions);
handlePersistenceException(converted);
return converted;
} else if (exception instanceof org.hibernate.QueryTimeoutException) {
final QueryTimeoutException converted = new QueryTimeoutException(exception.getMessage(), exception);
handlePersistenceException(converted);
return converted;
} else if (exception instanceof ObjectNotFoundException) {
final EntityNotFoundException converted = new EntityNotFoundException(exception.getMessage());
handlePersistenceException(converted);
return converted;
} else if (exception instanceof org.hibernate.NonUniqueObjectException) {
final EntityExistsException converted = new EntityExistsException(exception.getMessage());
handlePersistenceException(converted);
return converted;
} else if (exception instanceof org.hibernate.NonUniqueResultException) {
final NonUniqueResultException converted = new NonUniqueResultException(exception.getMessage());
handlePersistenceException(converted);
return converted;
} else if (exception instanceof UnresolvableObjectException) {
final EntityNotFoundException converted = new EntityNotFoundException(exception.getMessage());
handlePersistenceException(converted);
return converted;
} else if (exception instanceof SemanticException) {
return new IllegalArgumentException(exception);
} else if (exception instanceof QueryException) {
return new IllegalArgumentException(exception);
} else if (exception instanceof InterpretationException) {
return new IllegalArgumentException(exception);
} else if (exception instanceof ParsingException) {
return new IllegalArgumentException(exception);
} else if (exception instanceof MultipleBagFetchException) {
return new IllegalArgumentException(exception);
} else if (exception instanceof TransientObjectException) {
try {
sharedSessionContract.markForRollbackOnly();
} catch (Exception ne) {
// we do not want the subsequent exception to swallow the original one
log.unableToMarkForRollbackOnTransientObjectException(ne);
}
// Spec 3.2.3 Synchronization rules
return new IllegalStateException(exception);
} else {
final PersistenceException converted = new PersistenceException("Converting `" + exception.getClass().getName() + "` to JPA `PersistenceException` : " + exception.getMessage(), exception);
handlePersistenceException(converted);
return converted;
}
}
Aggregations