mirror of https://github.com/apache/openjpa.git
OPENJPA-1565,OPENJPA-1578:
Modify tests to raise correct lock/query exception Fill in details in exception Use retreive mode while initializing not store mode git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@924626 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
976508eed2
commit
1b20902b50
|
@ -31,6 +31,7 @@ import org.apache.openjpa.jdbc.sql.SQLBuffer;
|
|||
import org.apache.openjpa.jdbc.sql.SQLExceptions;
|
||||
import org.apache.openjpa.jdbc.sql.SQLFactory;
|
||||
import org.apache.openjpa.jdbc.sql.Select;
|
||||
import org.apache.openjpa.kernel.MixedLockLevels;
|
||||
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
||||
import org.apache.openjpa.kernel.StoreContext;
|
||||
import org.apache.openjpa.kernel.VersionLockManager;
|
||||
|
@ -140,7 +141,8 @@ public class PessimisticLockManager
|
|||
} catch (SQLException se) {
|
||||
LockException e = new LockException(sm.getPersistenceCapable(), timeout, level);
|
||||
e.setCause(se);
|
||||
e.setFatal(dict.isFatalException(StoreException.LOCK, se));
|
||||
e.setFatal(dict.isFatalException(StoreException.LOCK, se)
|
||||
|| level >= MixedLockLevels.LOCK_PESSIMISTIC_READ);
|
||||
throw e;
|
||||
} finally {
|
||||
if (stmnt != null)
|
||||
|
|
|
@ -129,8 +129,7 @@ public class SQLExceptions {
|
|||
/**
|
||||
* Convert the specified exception into a {@link StoreException}.
|
||||
*/
|
||||
public static OpenJPAException getStore(String msg, SQLException se,
|
||||
Object failed, DBDictionary dict, int level) {
|
||||
public static OpenJPAException getStore(String msg, SQLException se, Object failed, DBDictionary dict, int level) {
|
||||
if (msg == null)
|
||||
msg = se.getClass().getName();
|
||||
SQLException[] ses = getSQLExceptions(se);
|
||||
|
|
|
@ -326,7 +326,7 @@ public class DataCacheStoreManager
|
|||
boolean fromDatabase;
|
||||
DataCache cache = _mgr.selectCache(sm);
|
||||
DataCachePCData data = null;
|
||||
boolean updateCache = _ctx.getFetchConfiguration().getCacheStoreMode() != DataCacheStoreMode.BYPASS
|
||||
boolean updateCache = _ctx.getFetchConfiguration().getCacheRetrieveMode() != DataCacheRetrieveMode.BYPASS
|
||||
&& _ctx.getPopulateDataCache();
|
||||
if (cache == null || sm.isEmbedded()
|
||||
|| _ctx.getFetchConfiguration().getCacheRetrieveMode() == DataCacheRetrieveMode.BYPASS
|
||||
|
|
|
@ -30,6 +30,8 @@ import org.apache.openjpa.event.LifecycleEventManager;
|
|||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
import org.apache.openjpa.meta.FieldMetaData;
|
||||
import org.apache.openjpa.meta.ValueMetaData;
|
||||
import org.apache.openjpa.util.Exceptions;
|
||||
import org.apache.openjpa.util.OpenJPAException;
|
||||
import org.apache.openjpa.util.RuntimeExceptionTranslator;
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
@ -103,6 +105,25 @@ public class DelegatingBroker
|
|||
protected RuntimeException translate(RuntimeException re) {
|
||||
return (_trans == null) ? re : _trans.translate(re);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the exception with the failed object.
|
||||
*
|
||||
* @param re exception raised by the delegate.
|
||||
* @param failed the context that failed.
|
||||
*
|
||||
* @return the translated exception. If the given input exception had not set
|
||||
* the failed instance, then sets the given instance as the failed context.
|
||||
*/
|
||||
protected RuntimeException translate(RuntimeException re, Object failed) {
|
||||
if (re instanceof OpenJPAException) {
|
||||
Object o = ((OpenJPAException) re).getFailedObject();
|
||||
if (o == null || "null".equals(o)) {
|
||||
((OpenJPAException) re).setFailedObject(Exceptions.toString(failed));
|
||||
}
|
||||
}
|
||||
return (_trans == null) ? re : _trans.translate(re);
|
||||
}
|
||||
|
||||
public Broker getBroker() {
|
||||
return this;
|
||||
|
@ -200,7 +221,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.find(oid, validate, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, oid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,7 +230,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.findAll(oids, validate, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, oids);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,7 +238,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.findCached(oid, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, oid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,7 +247,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.find(oid, fetch, exclude, edata, flags);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, oid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +256,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.findAll(oids, fetch, exclude, edata, flags);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, oids);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1071,7 +1092,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.delete(obj, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1079,7 +1100,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.deleteAll(objs, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, objs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1087,7 +1108,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.release(obj, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1095,7 +1116,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.releaseAll(objs, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, objs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1103,7 +1124,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.refresh(obj, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1111,7 +1132,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.refreshAll(objs, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, objs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1119,7 +1140,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.evict(obj, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1127,7 +1148,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.evictAll(objs, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, objs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1143,7 +1164,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.evictAll(extent, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, extent.getElementType());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1151,7 +1172,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.detach(obj, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1159,7 +1180,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.detachAll(objs, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, objs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1183,7 +1204,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.attach(obj, copyNew, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1192,7 +1213,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.attachAll(objs, copyNew, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, objs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1201,7 +1222,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.transactional(pc, updateVersion, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, pc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1210,7 +1231,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.transactionalAll(objs, updateVersion, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, objs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1218,7 +1239,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.nontransactional(pc, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, pc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1226,7 +1247,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.nontransactionalAll(objs, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, objs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1234,7 +1255,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.newExtent(cls, subs);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, cls);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1242,7 +1263,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.newQuery(language, cls, query);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, query);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1250,7 +1271,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
return _broker.newQuery(language, query);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, query);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1274,7 +1295,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.lock(obj, level, timeout, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1282,7 +1303,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.lock(obj, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1291,7 +1312,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.lockAll(objs, level, timeout, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, objs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1299,7 +1320,7 @@ public class DelegatingBroker
|
|||
try {
|
||||
_broker.lockAll(objs, call);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
throw translate(re, objs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ public class LockException
|
|||
super(_loc.get("lock-timeout", Exceptions.toString(failed), String.valueOf(timeout)));
|
||||
setFailedObject(failed);
|
||||
setTimeout(timeout);
|
||||
setLockLevel(lockLevel);
|
||||
}
|
||||
|
||||
public int getSubtype() {
|
||||
|
|
|
@ -15,14 +15,11 @@ package org.apache.openjpa.persistence.query;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.LockModeType;
|
||||
import javax.persistence.LockTimeoutException;
|
||||
import javax.persistence.PessimisticLockException;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.QueryTimeoutException;
|
||||
|
||||
|
@ -30,6 +27,7 @@ import junit.framework.AssertionFailedError;
|
|||
|
||||
import org.apache.openjpa.persistence.exception.PObject;
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
import org.apache.openjpa.util.OpenJPAException;
|
||||
|
||||
/**
|
||||
* Tests that correct timeout exceptions are being thrown depending on whether it is a query or a lock operation.
|
||||
|
@ -39,7 +37,7 @@ import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
|||
*/
|
||||
public class TestTimeoutException extends SingleEMFTestCase {
|
||||
private final Class<?> entityClass = PObject.class;
|
||||
private final ExecutorService scheduler = Executors.newCachedThreadPool();
|
||||
|
||||
public void setUp() {
|
||||
super.setUp(entityClass);
|
||||
}
|
||||
|
@ -64,7 +62,7 @@ public class TestTimeoutException extends SingleEMFTestCase {
|
|||
query.getResultList();
|
||||
fail("Expected " + QueryTimeoutException.class.getName());
|
||||
} catch (Throwable t) {
|
||||
assertError(t, QueryTimeoutException.class, timeout);
|
||||
assertError(t, QueryTimeoutException.class);
|
||||
}
|
||||
|
||||
assertTrue(em2.getTransaction().isActive());
|
||||
|
@ -90,9 +88,9 @@ public class TestTimeoutException extends SingleEMFTestCase {
|
|||
Map<String,Object> hint = new HashMap<String, Object>();
|
||||
hint.put("javax.persistence.lock.timeout", timeout);
|
||||
em2.lock(entity2, LockModeType.PESSIMISTIC_WRITE, hint);
|
||||
fail("Expected " + LockTimeoutException.class.getName());
|
||||
fail("Expected " + PessimisticLockException.class.getName());
|
||||
} catch (Throwable t) {
|
||||
assertError(t, LockTimeoutException.class, timeout);
|
||||
assertError(t, PessimisticLockException.class);
|
||||
}
|
||||
assertTrue(em2.getTransaction().isActive());
|
||||
em2.getTransaction().rollback();
|
||||
|
@ -100,6 +98,29 @@ public class TestTimeoutException extends SingleEMFTestCase {
|
|||
em1.getTransaction().rollback();
|
||||
}
|
||||
|
||||
public void testQueryTimeOutExceptionWhileFindWithLocksOnAlreadyLockedEntities() {
|
||||
EntityManager em1 = emf.createEntityManager();
|
||||
EntityManager em2 = emf.createEntityManager();
|
||||
assertNotSame(em1, em2);
|
||||
Object oid = createEntity(em1);
|
||||
|
||||
em1.getTransaction().begin();
|
||||
Object entity = em1.find(entityClass, oid);
|
||||
assertNotNull(entity);
|
||||
em1.lock(entity, LockModeType.PESSIMISTIC_WRITE);
|
||||
|
||||
em2.getTransaction().begin();
|
||||
try {
|
||||
em2.find(entityClass, oid, LockModeType.PESSIMISTIC_WRITE);
|
||||
fail("Expected " + LockTimeoutException.class.getName());
|
||||
} catch (Throwable t) {
|
||||
assertError(t, LockTimeoutException.class);
|
||||
}
|
||||
|
||||
assertTrue(em2.getTransaction().isActive());
|
||||
em2.getTransaction().rollback();
|
||||
em1.getTransaction().rollback();
|
||||
}
|
||||
|
||||
public Object createEntity(EntityManager em) {
|
||||
long id = System.nanoTime();
|
||||
|
@ -113,17 +134,36 @@ public class TestTimeoutException extends SingleEMFTestCase {
|
|||
|
||||
|
||||
/**
|
||||
* Assert that an exception of proper type has been thrown by the given task within the given timeout.
|
||||
* @param t
|
||||
* @param expeceted
|
||||
* Assert that an exception of proper type has been thrown.
|
||||
* Also checks that that the exception has populated the failed object.
|
||||
* @param actual exception being thrown
|
||||
* @param expeceted type of the exception
|
||||
*/
|
||||
void assertError(Throwable actual, Class<? extends Throwable> expected, long timeout) {
|
||||
void assertError(Throwable actual, Class<? extends Throwable> expected) {
|
||||
if (!expected.isAssignableFrom(actual.getClass())) {
|
||||
actual.printStackTrace();
|
||||
throw new AssertionFailedError(actual.getClass().getName() + " was raised but expected " +
|
||||
expected.getName());
|
||||
}
|
||||
|
||||
}
|
||||
Object failed = getFailedObject(actual);
|
||||
assertNotNull("Failed object is null", failed);
|
||||
assertNotEquals("null", failed);
|
||||
}
|
||||
|
||||
Object getFailedObject(Throwable e) {
|
||||
if (e instanceof LockTimeoutException) {
|
||||
return ((LockTimeoutException) e).getObject();
|
||||
}
|
||||
if (e instanceof PessimisticLockException) {
|
||||
return ((PessimisticLockException) e).getEntity();
|
||||
}
|
||||
if (e instanceof QueryTimeoutException) {
|
||||
return ((QueryTimeoutException) e).getQuery();
|
||||
}
|
||||
if (e instanceof OpenJPAException) {
|
||||
return ((OpenJPAException) e).getFailedObject();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ public class TestPessimisticLocks extends SQLListenerTestCase {
|
|||
em2.find(Employee.class, 2, LockModeType.PESSIMISTIC_READ, hints);
|
||||
fail("Unexcpected find succeeded. Should throw a PessimisticLockException.");
|
||||
} catch (Throwable e) {
|
||||
assertError(e, LockTimeoutException.class);
|
||||
assertError(e, PessimisticLockException.class);
|
||||
} finally {
|
||||
if (em1.getTransaction().isActive())
|
||||
em1.getTransaction().rollback();
|
||||
|
@ -155,26 +155,26 @@ public class TestPessimisticLocks extends SQLListenerTestCase {
|
|||
public void testFindAfterQueryOrderByWithPessimisticLocks() {
|
||||
EntityManager em1 = emf.createEntityManager();
|
||||
EntityManager em2 = emf.createEntityManager();
|
||||
try {
|
||||
em1.getTransaction().begin();
|
||||
Query query = em1.createQuery("select e from Employee e where e.id < 10 order by e.id").setFirstResult(1);
|
||||
// Lock all selected Employees, skip the first one, i.e should lock
|
||||
// Employee(2)
|
||||
query.setLockMode(LockModeType.PESSIMISTIC_READ);
|
||||
query.setHint("javax.persistence.query.timeout", 2000);
|
||||
List<Employee> q = query.getResultList();
|
||||
assertEquals("Expected 1 element with emplyee id=2", q.size(), 1);
|
||||
assertEquals("Test Employee first name = 'first.2'", q.get(0).getFirstName(), "first.2");
|
||||
em1.getTransaction().begin();
|
||||
Query query = em1.createQuery("select e from Employee e where e.id < 10 order by e.id").setFirstResult(1);
|
||||
// Lock all selected Employees, skip the first one, i.e should lock
|
||||
// Employee(2)
|
||||
query.setLockMode(LockModeType.PESSIMISTIC_READ);
|
||||
query.setHint("javax.persistence.query.timeout", 2000);
|
||||
List<Employee> q = query.getResultList();
|
||||
assertEquals("Expected 1 element with emplyee id=2", q.size(), 1);
|
||||
assertEquals("Test Employee first name = 'first.2'", q.get(0).getFirstName(), "first.2");
|
||||
|
||||
em2.getTransaction().begin();
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("javax.persistence.lock.timeout", 2000);
|
||||
// find Employee(2) with a lock, should block and expected a
|
||||
// PessimisticLockException
|
||||
em2.getTransaction().begin();
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("javax.persistence.lock.timeout", 2000);
|
||||
// find Employee(2) with a lock, should block and expected a
|
||||
// PessimisticLockException
|
||||
try {
|
||||
em2.find(Employee.class, 2, LockModeType.PESSIMISTIC_READ, map);
|
||||
fail("Unexcpected find succeeded. Should throw a PessimisticLockException.");
|
||||
} catch (LockTimeoutException e) {
|
||||
assertError(e, LockTimeoutException.class);
|
||||
} catch (Exception e) {
|
||||
assertError(e, PessimisticLockException.class);
|
||||
} finally {
|
||||
if (em1.getTransaction().isActive())
|
||||
em1.getTransaction().rollback();
|
||||
|
@ -183,18 +183,18 @@ public class TestPessimisticLocks extends SQLListenerTestCase {
|
|||
}
|
||||
|
||||
em1.getTransaction().begin();
|
||||
Query query = em1.createQuery("select e.department from Employee e where e.id < 10 order by e.department.id")
|
||||
query = em1.createQuery("select e.department from Employee e where e.id < 10 order by e.department.id")
|
||||
.setFirstResult(1);
|
||||
// Lock all selected Departments, skip the first one, i.e should
|
||||
// lock Department(20)
|
||||
query.setLockMode(LockModeType.PESSIMISTIC_READ);
|
||||
query.setHint("javax.persistence.query.timeout", 2000);
|
||||
List<Department> q = query.getResultList();
|
||||
List<Department> result = query.getResultList();
|
||||
assertEquals("Expected 1 element with department id=20", q.size(), 1);
|
||||
assertEquals("Test department name = 'D20'", q.get(0).getName(), "D20");
|
||||
assertEquals("Test department name = 'D20'", result.get(0).getName(), "D20");
|
||||
|
||||
em2.getTransaction().begin();
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.clear();
|
||||
map.put("javax.persistence.lock.timeout", 2000);
|
||||
// find Employee(2) with a lock, no block since only department was
|
||||
// locked
|
||||
|
@ -258,12 +258,12 @@ public class TestPessimisticLocks extends SQLListenerTestCase {
|
|||
// Lock all selected Employees, skip the first one, i.e should lock
|
||||
// Employee(2)
|
||||
query.setLockMode(LockModeType.PESSIMISTIC_READ);
|
||||
query.setHint("javax.persistence.query.timeout", 2000);
|
||||
query.setHint("javax.persistence.query.timeout", 1000);
|
||||
try {
|
||||
List<Employee> q = query.getResultList();
|
||||
fail("Unexcpected find succeeded. Should throw a QueryLockException.");
|
||||
fail("Unexcpected find succeeded. Should throw a PessimisticLockException.");
|
||||
} catch (Exception e) {
|
||||
assertError(e, QueryTimeoutException.class);
|
||||
assertError(e, PessimisticLockException.class);
|
||||
} finally {
|
||||
if (em1.getTransaction().isActive())
|
||||
em1.getTransaction().rollback();
|
||||
|
@ -314,17 +314,16 @@ public class TestPessimisticLocks extends SQLListenerTestCase {
|
|||
em2.find(Employee.class, 2, LockModeType.PESSIMISTIC_READ, map);
|
||||
|
||||
em1.getTransaction().begin();
|
||||
query = em1.createQuery("select e from Employee e where e.id < 10 order by e.department.id")
|
||||
.setFirstResult(1);
|
||||
query = em1.createQuery("select e from Employee e where e.id < 10 order by e.department.id").setFirstResult(1);
|
||||
// Lock all selected Employees, skip the first one, i.e should lock
|
||||
// Employee(2)
|
||||
query.setLockMode(LockModeType.PESSIMISTIC_READ);
|
||||
query.setHint("javax.persistence.query.timeout", 2000);
|
||||
try {
|
||||
List<?> q = query.getResultList();
|
||||
fail("Unexcpected find succeeded. Should throw a QueryLockException.");
|
||||
fail("Unexcpected find succeeded. Should throw a PessimisticLockException.");
|
||||
} catch (Exception e) {
|
||||
assertError(e, QueryTimeoutException.class);
|
||||
assertError(e, PessimisticLockException.class);
|
||||
} finally {
|
||||
if (em1.getTransaction().isActive())
|
||||
em1.getTransaction().rollback();
|
||||
|
@ -359,6 +358,9 @@ public class TestPessimisticLocks extends SQLListenerTestCase {
|
|||
if (e instanceof LockTimeoutException) {
|
||||
return ((LockTimeoutException) e).getObject();
|
||||
}
|
||||
if (e instanceof PessimisticLockException) {
|
||||
return ((PessimisticLockException) e).getEntity();
|
||||
}
|
||||
if (e instanceof QueryTimeoutException) {
|
||||
return ((QueryTimeoutException) e).getQuery();
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public class LockTimeoutException
|
|||
private transient Throwable[] _nested = null;
|
||||
|
||||
public LockTimeoutException(String msg, Throwable[] nested, Object failed) {
|
||||
super(msg);
|
||||
super(msg, nested == null ? null : nested[0], failed);
|
||||
_nested = nested;
|
||||
_failed = failed;
|
||||
}
|
||||
|
|
|
@ -164,14 +164,16 @@ public class PersistenceExceptions
|
|||
} else if (subtype == StoreException.OPTIMISTIC || cause instanceof OptimisticException) {
|
||||
e = new org.apache.openjpa.persistence.OptimisticLockException(msg, nested, failed, fatal);
|
||||
} else if (subtype == StoreException.LOCK || cause instanceof LockException) {
|
||||
LockException lockEx = (LockException) (ke instanceof LockException ? ke : cause);
|
||||
if (!lockEx.isFatal()) {
|
||||
e = new org.apache.openjpa.persistence.LockTimeoutException(msg, nested, failed);
|
||||
} else if (lockEx != null && lockEx.getLockLevel() >= MixedLockLevels.LOCK_PESSIMISTIC_READ) {
|
||||
e = new org.apache.openjpa.persistence.PessimisticLockException(msg, nested, failed);
|
||||
} else {
|
||||
e = new org.apache.openjpa.persistence.OptimisticLockException(msg, nested, failed, fatal);
|
||||
}
|
||||
LockException lockEx = (LockException) (ke instanceof LockException ? ke : cause);
|
||||
if (lockEx != null && lockEx.getLockLevel() >= MixedLockLevels.LOCK_PESSIMISTIC_READ) {
|
||||
if (!lockEx.isFatal()) {
|
||||
e = new org.apache.openjpa.persistence.LockTimeoutException(msg, nested, failed);
|
||||
} else {
|
||||
e = new org.apache.openjpa.persistence.PessimisticLockException(msg, nested, failed);
|
||||
}
|
||||
} else {
|
||||
e = new org.apache.openjpa.persistence.OptimisticLockException(msg, nested, failed, fatal);
|
||||
}
|
||||
} else if (subtype == StoreException.OBJECT_EXISTS || cause instanceof ObjectExistsException) {
|
||||
e = new org.apache.openjpa.persistence.EntityExistsException(msg, nested, failed, fatal);
|
||||
} else if (subtype == StoreException.QUERY || cause instanceof QueryException) {
|
||||
|
|
|
@ -46,9 +46,10 @@ public class PessimisticLockException
|
|||
private transient Throwable[] _nested = null;
|
||||
|
||||
public PessimisticLockException(String msg, Throwable[] nested, Object failed) {
|
||||
super(msg);
|
||||
super(msg, nested == null ? null : nested[0], failed);
|
||||
_nested = nested;
|
||||
_failed = failed;
|
||||
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
|
|
|
@ -98,8 +98,7 @@ public class QueryImpl<X> implements OpenJPAQuerySPI<X>, Serializable {
|
|||
* @param ret Exception translator for this query
|
||||
* @param query The underlying "kernel" query.
|
||||
*/
|
||||
public QueryImpl(EntityManagerImpl em, RuntimeExceptionTranslator ret,
|
||||
org.apache.openjpa.kernel.Query query) {
|
||||
public QueryImpl(EntityManagerImpl em, RuntimeExceptionTranslator ret, org.apache.openjpa.kernel.Query query) {
|
||||
_em = em;
|
||||
_query = new DelegatingQuery(query, ret);
|
||||
_lock = new ReentrantLock();
|
||||
|
@ -110,8 +109,7 @@ public class QueryImpl<X> implements OpenJPAQuerySPI<X>, Serializable {
|
|||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public QueryImpl(EntityManagerImpl em,
|
||||
org.apache.openjpa.kernel.Query query) {
|
||||
public QueryImpl(EntityManagerImpl em, org.apache.openjpa.kernel.Query query) {
|
||||
this(em, null, query);
|
||||
}
|
||||
|
||||
|
@ -1084,4 +1082,9 @@ public class QueryImpl<X> implements OpenJPAQuerySPI<X>, Serializable {
|
|||
}
|
||||
|
||||
// ================== End of Parameter Processing routines ================================
|
||||
|
||||
public String toString() {
|
||||
String result = _query.getQueryString();
|
||||
return result != null ? result : _id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ import java.io.PrintStream;
|
|||
import java.io.PrintWriter;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.apache.openjpa.util.ExceptionInfo;
|
||||
import org.apache.openjpa.util.Exceptions;
|
||||
import org.apache.openjpa.util.StoreException;
|
||||
|
@ -49,7 +51,7 @@ public class QueryTimeoutException
|
|||
}
|
||||
|
||||
public QueryTimeoutException(String msg, Throwable[] nested, Object failed, boolean fatal) {
|
||||
super(msg);
|
||||
super(msg, nested == null ? null : nested[0], failed instanceof Query ? (Query)failed : null);
|
||||
_nested = nested;
|
||||
_failed = failed;
|
||||
_fatal = fatal;
|
||||
|
|
Loading…
Reference in New Issue