use of org.eclipse.persistence.jpa.JpaEntityManagerFactory in project eclipselink by eclipse-ee4j.
the class EntityManagerJUnitTestSuite method internalTestPostAcquirePreReleaseEvents.
public void internalTestPostAcquirePreReleaseEvents(boolean useExternalConnectionPool) {
if (isOnServer()) {
// Uses DefaultConnector.
return;
}
SessionBroker broker = ((JpaEntityManagerFactory) getEntityManagerFactory()).getSessionBroker();
// Testing ExclusiveConnectionMode.Isolated requires a session that has isolated descriptors.
ServerSession ss = (ServerSession) broker.getSessionForClass(Address.class);
if (ss.getPlatform().isSybase()) {
warning("Warning Sybase Driver does not work with DriverWrapper, testPostAcquirePreReleaseEvents can't run on this platform.");
return;
}
if (ss.getPlatform().isSymfoware()) {
warning("Test testPostAcquirePreReleaseEvents skipped for this platform, " + "Symfoware platform doesn't support failover.");
return;
}
// normally false; set to true for debug output for just this single test
boolean shouldForceFinest = false;
int originalLogLevel = -1;
// cache the original driver name and connection string.
String originalDriverName = ss.getLogin().getDriverClassName();
String originalConnectionString = ss.getLogin().getConnectionString();
// cache original connector for external connection pool case
Connector originalConnector = ss.getLogin().getConnector();
// the new driver name and connection string to be used by the test
String newDriverName = DriverWrapper.class.getName();
String newConnectionString = DriverWrapper.codeUrl(originalConnectionString);
// setup the wrapper driver
DriverWrapper.initialize(originalDriverName);
// The test need to connect with the new driver and connection string.
// That could be done in JPA:
// // close the existing emf
// closeEntityManagerFactory();
// HashMap properties = new HashMap(JUnitTestCaseHelper.getDatabaseProperties());
// properties.put(PersistenceUnitProperties.JDBC_DRIVER, newDriverName);
// properties.put(PersistenceUnitProperties.JDBC_URL, newConnectionString);
// emf = getEntityManagerFactory(properties);
// However this only works in case closeEntityManagerFactory disconnects the original ServerSession,
// which requires the factory to be the only one using the persistence unit.
// Alternative - and faster - approach is to disconnect the original session directly
// and then reconnected it with the new driver and connection string.
broker.logout();
if (useExternalConnectionPool) {
ss.getLogin().setConnector(new JNDIConnector(new DataSourceImpl(null, newConnectionString, null, null)));
ss.getLogin().useExternalConnectionPooling();
} else {
ss.getLogin().setDriverClassName(newDriverName);
ss.getLogin().setConnectionString(newConnectionString);
}
if (shouldForceFinest) {
if (broker.getLogLevel() != SessionLog.FINEST) {
originalLogLevel = broker.getLogLevel();
broker.setLogLevel(SessionLog.FINEST);
}
}
// switch off reconnection
boolean originalIsConnectionHealthValidatedOnError = ss.getLogin().isConnectionHealthValidatedOnError();
ss.getLogin().setConnectionHealthValidatedOnError(false);
// Using DriverWrapper the listener will repair connection on postAcquireConnection and break it on preReleaseConnection event.
// Also the listener will verify that neither postAcquireConnection nor preReleaseConnection events not called two in a row.
AcquireRepair_ReleaseBreak_Listener listener = new AcquireRepair_ReleaseBreak_Listener();
ss.getEventManager().addListener(listener);
// Driver's connect method will still work, however any method called on any acquired connection will throw SQLException.
// On postAcquireConnection connection will be repaired; on preReleaseConnection - broken again.
broker.log(SessionLog.FINEST, SessionLog.CONNECTION, "testPostAcquirePreReleaseEvents: DriverWrapper.breakOldConnections(); DriverWrapper.breakNewConnections();", null, null, false);
DriverWrapper.breakOldConnections();
DriverWrapper.breakNewConnections();
broker.login();
// test several configurations:
// all exclusive connection modes
String[] exclusiveConnectionModeArray = new String[] { ExclusiveConnectionMode.Transactional, ExclusiveConnectionMode.Isolated, ExclusiveConnectionMode.Always };
// Normally the user wishing to use not pooled connection would specify user and password properties (and possibly db url, too).
// However if these properties have the same values that those in the logging then no non pooled connection is created and the pooled one used instead.
// In the test we must use the same user as already in the session login (don't know any others) that forces usage of ConnectionPolicy property.
ConnectionPolicy connectionPolicy = (ConnectionPolicy) ss.getDefaultConnectionPolicy().clone();
connectionPolicy.setLogin(ss.getLogin());
connectionPolicy.setPoolName(null);
try {
HashMap emProperties = new HashMap(1);
HashMap mapOfProperties = new HashMap(1);
emProperties.put(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES, mapOfProperties);
HashMap memberProperties = new HashMap();
mapOfProperties.put(ss.getName(), memberProperties);
String mode, pooled = "", exclusiveConnectionMode;
for (int k = 0; k < 2; k++) {
if (k == 1) {
// use non pooled connections
pooled = "non pooled; ";
memberProperties.put(EntityManagerProperties.CONNECTION_POLICY, connectionPolicy);
}
for (int i = 0; i < exclusiveConnectionModeArray.length; i++) {
exclusiveConnectionMode = exclusiveConnectionModeArray[i];
for (int j = 0; j < 3; j++) {
// either beginning early transaction or not
boolean shouldBeginEarlyTransaction = (j == 2);
boolean shouldReadBeforeTransaction = (j == 1);
mode = pooled + exclusiveConnectionMode + (shouldBeginEarlyTransaction ? "; beginEarlyTransaction" : "") + (shouldReadBeforeTransaction ? "; readBeforeTransaction" : "");
broker.log(SessionLog.FINEST, SessionLog.CONNECTION, "testPostAcquirePreReleaseEvents: " + mode, null, null, false);
memberProperties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, exclusiveConnectionMode);
EntityManager em = createEntityManager(emProperties);
if (shouldReadBeforeTransaction) {
em.find(Address.class, 1);
}
Address address = null;
try {
em.getTransaction().begin();
if (shouldBeginEarlyTransaction) {
em.unwrap(UnitOfWorkImpl.class).beginEarlyTransaction();
}
address = new Address();
address.setCountry("testPostAcquirePreReleaseEvents");
em.persist(address);
em.getTransaction().commit();
} finally {
// expected exception - connection is invalid and cannot be reconnected.
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
closeEntityManager(em);
}
if (listener.hasAcquiredConnections()) {
fail(mode + " connection was not passed to preReleaseConnection event");
}
}
}
}
} finally {
// clear the driver wrapper
DriverWrapper.clear();
// reconnect the session using the original driver and connection string
ss.getEventManager().removeListener(listener);
// clean-up
// remove the inserted object
EntityManager em = createEntityManager();
em.getTransaction().begin();
try {
em.createQuery("DELETE FROM Address a WHERE a.country = 'testPostAcquirePreReleaseEvents'");
em.getTransaction().commit();
} finally {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
closeEntityManager(em);
broker.logout();
if (originalLogLevel >= 0) {
broker.setLogLevel(originalLogLevel);
}
if (useExternalConnectionPool) {
ss.getLogin().setConnector(originalConnector);
ss.getLogin().dontUseExternalConnectionPooling();
} else {
ss.getLogin().setDriverClassName(originalDriverName);
ss.getLogin().setConnectionString(originalConnectionString);
}
ss.getLogin().setConnectionHealthValidatedOnError(originalIsConnectionHealthValidatedOnError);
broker.login();
}
}
}
use of org.eclipse.persistence.jpa.JpaEntityManagerFactory in project eclipselink by eclipse-ee4j.
the class EntityManagerJUnitTestSuite method testDeadPoolFailover.
/**
* Tests that a dead connection pool can fail over.
*/
public void testDeadPoolFailover() {
if (isOnServer()) {
// Uses DefaultConnector.
return;
}
if (getPlatform(Address.class).isSybase()) {
warning("Test testDeadConnectionFailover skipped for this platform, Sybase Driver does not work with DriverWrapper.");
return;
}
if (getPlatform(Address.class).isSymfoware()) {
warning("Test testDeadConnectionFailover skipped for this platform, Symfoware platform doesn't support failover.");
return;
}
SessionBroker broker = ((JpaEntityManagerFactory) getEntityManagerFactory()).getSessionBroker();
// Testing ExclusiveConnectionMode.Isolated requires a session that has isolated descriptors.
ServerSession server = (ServerSession) broker.getSessionForClass(Address.class);
// cache the original driver name and connection string.
DatabaseLogin originalLogin = (DatabaseLogin) server.getLogin().clone();
// the new driver name and connection string to be used by the test
String newDriverName = DriverWrapper.class.getName();
String newConnectionString = DriverWrapper.codeUrl(originalLogin.getConnectionString());
// setup the wrapper driver
DriverWrapper.initialize(originalLogin.getDriverClassName());
broker.logout();
server.getLogin().setDriverClassName(newDriverName);
server.getLogin().setConnectionHealthValidatedOnError(true);
server.getLogin().setConnectionString(newConnectionString);
server.addConnectionPool("backup", originalLogin, 2, 4);
server.getDefaultConnectionPool().addFailoverConnectionPool("backup");
server.getReadConnectionPool().addFailoverConnectionPool("backup");
broker.login();
try {
EntityManager em = createEntityManager();
em.createQuery("Select a from Address a").getResultList();
em.getTransaction().begin();
em.persist(new Address());
em.getTransaction().commit();
// test several configurations:
// all exclusive connection modes
String[] exclusiveConnectionModes = new String[] { ExclusiveConnectionMode.Transactional, ExclusiveConnectionMode.Isolated, ExclusiveConnectionMode.Always };
for (String exclusiveConnectionMode : exclusiveConnectionModes) {
try {
HashMap emProperties = new HashMap(1);
HashMap mapOfProperties = new HashMap(1);
emProperties.put(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES, mapOfProperties);
HashMap memberProperties = new HashMap(1);
mapOfProperties.put(server.getName(), memberProperties);
memberProperties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, exclusiveConnectionMode);
em = createEntityManager(emProperties);
List<Address> addresses = em.createQuery("Select a from Address a").getResultList();
DriverWrapper.breakAll();
List<Address> addresses2 = em.createQuery("Select a from Address a").getResultList();
if (addresses.size() != addresses2.size()) {
fail("Query results not the same after failure.");
}
em.getTransaction().begin();
em.persist(new Address());
em.getTransaction().commit();
em.getTransaction().begin();
em.persist(new Address());
em.flush();
em.getTransaction().commit();
} catch (Exception failed) {
fail("Retry did not work, mode:" + exclusiveConnectionMode + " error:" + failed);
} finally {
try {
em.close();
} catch (Exception ignore) {
}
}
}
} finally {
// clear the driver wrapper
DriverWrapper.clear();
// reconnect the session using the original driver and connection string
broker.logout();
server.getConnectionPools().remove("backup");
server.getDefaultConnectionPool().setFailoverConnectionPools(new ArrayList());
server.getReadConnectionPool().setFailoverConnectionPools(new ArrayList());
server.getLogin().setDriverClassName(originalLogin.getDriverClassName());
server.getLogin().setConnectionString(originalLogin.getConnectionString());
broker.login();
}
}
use of org.eclipse.persistence.jpa.JpaEntityManagerFactory in project eclipselink by eclipse-ee4j.
the class EntityManagerJUnitTestSuite method testEMCloseAndOpen.
public void testEMCloseAndOpen() {
if (isOnServer()) {
// Uses DefaultConnector.
return;
}
// Assert.assertFalse("Warning Sybase Driver does not work with DriverWrapper, testEMCloseAndOpen can't run on this platform.", getPlatform(Address.class).isSybase());
if (getPlatform(Address.class).isSymfoware()) {
getDatabaseSession().logMessage("Test testEMCloseAndOpen skipped for this platform, " + "Symfoware platform doesn't support failover.");
return;
}
// normally false; set to true for debug output for just this single test
boolean shouldForceFinest = false;
int originalLogLevel = -1;
SessionBroker broker = ((JpaEntityManagerFactory) getEntityManagerFactory()).getSessionBroker();
// Testing ExclusiveConnectionMode.Isolated requires a session that has isolated descriptors.
ServerSession ss = (ServerSession) broker.getSessionForClass(Address.class);
// make sure the id hasn't been already used - it will be assigned to a new object (in case sequencing is not used).
int id = (ss.getNextSequenceNumberValue(Address.class)).intValue();
// cache the original driver name and connection string.
String originalDriverName = ss.getLogin().getDriverClassName();
String originalConnectionString = ss.getLogin().getConnectionString();
// the new driver name and connection string to be used by the test
String newDriverName = DriverWrapper.class.getName();
String newConnectionString = DriverWrapper.codeUrl(originalConnectionString);
// setup the wrapper driver
DriverWrapper.initialize(originalDriverName);
// The test need to connect with the new driver and connection string.
// That could be done in JPA:
// // close the existing emf
// closeEntityManagerFactory();
// HashMap properties = new HashMap(JUnitTestCaseHelper.getDatabaseProperties());
// properties.put(PersistenceUnitProperties.JDBC_DRIVER, newDriverName);
// properties.put(PersistenceUnitProperties.JDBC_URL, newConnectionString);
// emf = getEntityManagerFactory(properties);
// However this only works in case closeEntityManagerFactory disconnects the original SessionBroker,
// which requires the factory to be the only one using the persistence unit.
// Alternative - and faster - approach is to disconnect the original session directly
// and then reconnected it with the new driver and connection string.
broker.logout();
ss.getLogin().setDriverClassName(newDriverName);
ss.getLogin().setConnectionString(newConnectionString);
AcquireReleaseListener listener = new AcquireReleaseListener();
ss.getEventManager().addListener(listener);
if (shouldForceFinest) {
if (broker.getLogLevel() != SessionLog.FINEST) {
originalLogLevel = broker.getLogLevel();
broker.setLogLevel(SessionLog.FINEST);
}
}
broker.login();
String errorMsg = "";
// test several configurations:
// all exclusive connection modes
String[] exclusiveConnectionModeArray = new String[] { ExclusiveConnectionMode.Transactional, ExclusiveConnectionMode.Isolated, ExclusiveConnectionMode.Always };
// Workaround for Bug 309881 - problems with CallQueryMechanism.prepareCall method
// Because of this bug em.find ignores QueryHints.JDBC_TIMEOUT,
// have to set it directly into the Descriptor's ReadObjectQuery.
// This should be removed from the test after the bug is fixed.
ReadObjectQuery addressFindQuery = broker.getDescriptor(Address.class).getQueryManager().getReadObjectQuery();
int originalQueryTimeout = addressFindQuery.getQueryTimeout();
if (originalQueryTimeout > 0) {
ss.setQueryTimeoutDefault(0);
addressFindQuery.setQueryTimeout(0);
// The same bug 309881 requires the query to be reprepaired for queryTimeOut to be set on its call
addressFindQuery.setIsPrepared(false);
addressFindQuery.checkPrepare(ss, null);
}
// currently reconnection is not attempted if query time out is not zero.
HashMap noTimeOutHint = new HashMap(1);
noTimeOutHint.put(QueryHints.JDBC_TIMEOUT, 0);
try {
for (int i = 0; i < 3; i++) {
String exclusiveConnectionMode = exclusiveConnectionModeArray[i];
for (int j = 0; j < 2; j++) {
// either using or not using sequencing
boolean useSequencing = (j == 0);
broker.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: " + (useSequencing ? "sequencing" : "no sequencing"), null, null, false);
HashMap emProperties = new HashMap(1);
HashMap mapOfProperties = new HashMap(1);
emProperties.put(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES, mapOfProperties);
HashMap memberProperties = new HashMap();
mapOfProperties.put(ss.getName(), memberProperties);
memberProperties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, exclusiveConnectionMode);
EntityManager em = createEntityManager(emProperties);
em.find(Address.class, 1, noTimeOutHint);
Address address = null;
boolean hasUnexpectedlyCommitted = false;
try {
em.getTransaction().begin();
// imitate disconnecting from network:
// driver's connect method and any method on any connection will throw SQLException
broker.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: DriverWrapper.breakDriver(); DriverWrapper.breakOldConnections();", null, null, false);
DriverWrapper.breakDriver();
DriverWrapper.breakOldConnections();
address = new Address();
if (!useSequencing) {
address.setID(id);
}
em.persist(address);
em.getTransaction().commit();
// should never get here - all connections should be broken.
hasUnexpectedlyCommitted = true;
errorMsg += "useSequencing = " + useSequencing + "; exclusiveConnectionMode = " + exclusiveConnectionMode + ": Commit has unexpectedly succeeded - should have failed because all connections broken. driver = " + ss.getLogin().getDriverClassName() + "; url = " + ss.getLogin().getConnectionString();
} catch (Exception e) {
// expected exception - connection is invalid and cannot be reconnected.
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
}
closeEntityManager(em);
// verify - all connections should be released
String localErrorMsg = "";
if (listener.nAcquredWriteConnections() > 0) {
localErrorMsg += "writeConnection not released; ";
}
if (listener.nAcquredReadConnections() > 0) {
localErrorMsg += "readConnection not released; ";
}
if (localErrorMsg.length() > 0) {
localErrorMsg = exclusiveConnectionMode + " useSequencing=" + useSequencing + ": " + localErrorMsg;
errorMsg += localErrorMsg;
listener.clear();
}
// imitate reconnecting to network:
// driver's connect method will now work, all newly acquired connections will work, too;
// however the old connections cached in the connection pools are still invalid.
DriverWrapper.repairDriver();
broker.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: DriverWrapper.repairDriver();", null, null, false);
boolean failed = true;
try {
em = createEntityManager();
em.find(Address.class, 1);
if (!hasUnexpectedlyCommitted) {
em.getTransaction().begin();
address = new Address();
if (!useSequencing) {
address.setID(id);
}
em.persist(address);
em.getTransaction().commit();
failed = false;
}
} finally {
if (failed) {
// This should not happen
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
closeEntityManager(em);
if (errorMsg.length() > 0) {
broker.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: errorMsg: " + "\n" + errorMsg, null, null, false);
}
}
}
// clean-up
// remove the inserted object
em.getTransaction().begin();
em.remove(address);
em.getTransaction().commit();
closeEntityManager(em);
}
}
} finally {
// This should be removed from the test after the bug is fixed.
if (originalQueryTimeout > 0) {
ss.setQueryTimeoutDefault(originalQueryTimeout);
addressFindQuery.setQueryTimeout(originalQueryTimeout);
// The same bug 309881 requires the query to be reprepaired for queryTimeOut to be set on its call
addressFindQuery.setIsPrepared(false);
addressFindQuery.checkPrepare(ss, null);
}
// clear the driver wrapper
DriverWrapper.clear();
// reconnect the session using the original driver and connection string
ss.getEventManager().removeListener(listener);
broker.logout();
if (originalLogLevel >= 0) {
broker.setLogLevel(originalLogLevel);
}
ss.getLogin().setDriverClassName(originalDriverName);
ss.getLogin().setConnectionString(originalConnectionString);
broker.login();
if (errorMsg.length() > 0) {
fail(errorMsg);
}
}
}
use of org.eclipse.persistence.jpa.JpaEntityManagerFactory in project eclipselink by eclipse-ee4j.
the class JPAPerformanceServerTestSuite method testPerformance.
public void testPerformance() throws Throwable {
TestExecutor executor = new TestExecutor();
EntityManagerFactory factory = Persistence.createEntityManagerFactory("performance");
executor.setSession(((JpaEntityManagerFactory) factory).getServerSession());
executor.setEntityManagerFactory(factory);
JPAPerformanceRegressionModel test = new JPAPerformanceRegressionModel();
executor.runTest(test);
executor.logResultForTestEntity(test);
factory.close();
}
use of org.eclipse.persistence.jpa.JpaEntityManagerFactory in project eclipselink by eclipse-ee4j.
the class EntityManagerJUnitTestSuite method testPESSIMISTIC_ExtendedScope.
public void testPESSIMISTIC_ExtendedScope() {
ServerSession session = JUnitTestCase.getServerSession();
// Cannot create parallel entity managers in the server. Uses FOR UPDATE clause which SQLServer doesn't support.
if (isOnServer() || !isSelectForUpateSupported() || !isPessimisticWriteLockSupported()) {
return;
}
if ((JUnitTestCase.getServerSession()).getPlatform().isHANA()) {
// feature is under development (see bug 384129), but test should be skipped for the time being
return;
}
ServerSession ss = ((JpaEntityManagerFactory) getEntityManagerFactory()).getServerSession();
// If FOR UPDATE NOWAIT is not supported then FOR UPDATE is used - and that could lock the test (em2) for a long time (depending on db setting).
boolean shouldSpawnThread = !isSelectForUpateNoWaitSupported();
// To avoid that a separate thread is spawned that - after waiting the specified time -
// completes the locking transaction (em1) and therefore clears the way to em2 go ahead.
long timeToWait = 1000;
String errorMsg = "";
LockModeType lockMode = LockModeType.PESSIMISTIC_WRITE;
// create Employee with Projects and Responsibilities
Employee emp = new Employee();
emp.setFirstName("PESSIMISTIC");
emp.setLastName("ExtendedScope");
emp.addResponsibility("0");
emp.addResponsibility("1");
SmallProject smallProject = new SmallProject();
smallProject.setName("SmallExtendedScope");
emp.addProject(smallProject);
LargeProject largeProject = new LargeProject();
largeProject.setName("LargeExtendedScope");
largeProject.setBudget(5000);
emp.addProject(largeProject);
// persist
EntityManager em = createEntityManager();
try {
beginTransaction(em);
em.persist(emp);
commitTransaction(em);
} finally {
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
closeEntityManager(em);
}
// cache ids
int id = emp.getId();
int smallProjId = smallProject.getId();
clearCache();
// properties to be passed to find, lock, refresh methods
Map<String, Object> properties = new HashMap();
properties.put(QueryHints.PESSIMISTIC_LOCK_SCOPE, PessimisticLockScope.EXTENDED);
String forUpdateClause = session.getPlatform().getSelectForUpdateString();
if (isSelectForUpateNoWaitSupported()) {
properties.put(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
forUpdateClause = session.getPlatform().getSelectForUpdateNoWaitString();
}
String lockingClauseAfterWhereClause = "";
String lockingClauseBeforeWhereClause = "";
if (session.getPlatform().shouldPrintLockingClauseAfterWhereClause()) {
lockingClauseAfterWhereClause = forUpdateClause;
} else {
lockingClauseBeforeWhereClause = forUpdateClause;
}
// indicates whether the object to be locked is already in cache.
boolean[] isObjectCached = { false, true };
// indicates which method on the first entity manager is used to lock the object.
String[] testModeArray1 = { "query", "find", "lock", "refresh" };
// indicates which method on the second entity manager is used to test the lock.
String[] testModeArray2 = { "query", "find", "update_name", "update_salary", "remove_project", "remove_respons", "update_project", "update_respons", "lock", "refresh" };
if (usesSOP()) {
// if SOP is used there is no expected exceptions for remove_respons and update_respons because responsibilities read from sopObject, not from db row directly.
// Therefore exclude remove_respons and update_respons.
testModeArray2 = new String[] { "query", "find", "update_name", "update_salary", "remove_project", "update_project", "lock", "refresh" };
}
// testMode1 loop
for (int i = 0; i < testModeArray1.length; i++) {
String testMode1 = testModeArray1[i];
// isObjectCached loop
for (int k = 0; k < isObjectCached.length; k++) {
boolean isObjCached = isObjectCached[k];
// testMode2 loop
for (int j = 0; j < testModeArray2.length; j++) {
String testMode2 = testModeArray2[j];
boolean isExceptionExpected = !testMode2.equals("update_project");
// lock emp using em1
EntityManager em1 = createEntityManager();
// bring object into cache if required
if (isObjCached) {
ss.log(SessionLog.FINEST, SessionLog.QUERY, "testPESSIMISTIC_ExtendedScope: bring object into cache", null, null, false);
em1.find(Employee.class, id);
}
Employee emp1;
try {
beginTransaction(em1);
ss.log(SessionLog.FINEST, SessionLog.QUERY, "testPESSIMISTIC_ExtendedScope: testMode1 = " + testMode1, null, null, false);
if (testMode1.equals("query")) {
Query query1 = em1.createQuery("SELECT emp FROM Employee emp WHERE emp.id = " + id).setLockMode(lockMode).setHint(QueryHints.PESSIMISTIC_LOCK_SCOPE, PessimisticLockScope.EXTENDED);
if (isSelectForUpateNoWaitSupported()) {
query1.setHint(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
}
emp1 = (Employee) query1.getSingleResult();
} else if (testMode1.equals("find")) {
emp1 = em1.find(Employee.class, id, lockMode, properties);
} else {
emp1 = em1.find(Employee.class, id);
if (testMode1.equals("lock")) {
em1.lock(emp1, lockMode, properties);
} else if (testMode1.equals("refresh")) {
em1.refresh(emp1, lockMode, properties);
} else {
fail("Unknown testMode1 = " + testMode1);
}
}
TransactionKiller transactionKiller = null;
// try to update emp using em2
EntityManager em2 = createEntityManager();
Employee emp2;
try {
beginTransaction(em2);
ss.log(SessionLog.FINEST, SessionLog.QUERY, "testPESSIMISTIC_ExtendedScope: testMode2 = " + testMode2, null, null, false);
if (shouldSpawnThread) {
// after waiting TransactionKiller rollback em1 transaction unlocking way for em2 to proceed.
// the test assumes that em2 waiting for timeToWait means em2 waiting on the lock acquired by em1.
transactionKiller = new TransactionKiller(em1, timeToWait);
transactionKiller.start();
}
if (testMode2.equals("query")) {
Query query2 = em2.createQuery("SELECT emp FROM Employee emp WHERE emp.id = " + id).setLockMode(lockMode).setHint(QueryHints.PESSIMISTIC_LOCK_SCOPE, PessimisticLockScope.EXTENDED);
if (isSelectForUpateNoWaitSupported()) {
query2.setHint(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
}
emp2 = (Employee) query2.getSingleResult();
} else if (testMode2.equals("find")) {
emp2 = em2.find(Employee.class, id, lockMode, properties);
} else if (testMode2.equals("update_name")) {
em2.createNativeQuery("SELECT L_NAME FROM CMP3_EMPLOYEE" + lockingClauseBeforeWhereClause + " WHERE EMP_ID = " + id + lockingClauseAfterWhereClause).getSingleResult();
// em2.createNativeQuery("UPDATE CMP3_EMPLOYEE SET L_NAME = 'NEW' WHERE EMP_ID = "+id).executeUpdate();
} else if (testMode2.equals("update_salary")) {
em2.createNativeQuery("SELECT SALARY FROM CMP3_SALARY" + lockingClauseBeforeWhereClause + " WHERE EMP_ID = " + id + lockingClauseAfterWhereClause).getSingleResult();
// em2.createNativeQuery("UPDATE CMP3_SALARY SET SALARY = 1000 WHERE EMP_ID = "+id).executeUpdate();
} else if (testMode2.equals("remove_project")) {
em2.createNativeQuery("SELECT PROJECTS_PROJ_ID FROM CMP3_EMP_PROJ" + lockingClauseBeforeWhereClause + " WHERE EMPLOYEES_EMP_ID = " + id + lockingClauseAfterWhereClause).getResultList();
// em2.createNativeQuery("DELETE FROM CMP3_EMP_PROJ WHERE EMPLOYEES_EMP_ID = "+id).executeUpdate();
} else if (testMode2.equals("remove_respons")) {
em2.createNativeQuery("SELECT EMP_ID FROM CMP3_RESPONS" + lockingClauseBeforeWhereClause + " WHERE EMP_ID = " + id + lockingClauseAfterWhereClause).getResultList();
// em2.createNativeQuery("DELETE FROM CMP3_RESPONS WHERE EMP_ID = "+id).executeUpdate();
} else if (testMode2.equals("update_project")) {
em2.createNativeQuery("SELECT PROJ_NAME FROM CMP3_PROJECT" + lockingClauseBeforeWhereClause + " WHERE PROJ_ID = " + smallProjId + lockingClauseAfterWhereClause).getSingleResult();
// em2.createNativeQuery("UPDATE CMP3_PROJECT SET PROJ_NAME = 'NEW' WHERE PROJ_ID = "+smallProjId).executeUpdate();
} else if (testMode2.equals("update_respons")) {
em2.createNativeQuery("SELECT DESCRIPTION FROM CMP3_RESPONS" + lockingClauseBeforeWhereClause + " WHERE EMP_ID = " + id + lockingClauseAfterWhereClause).getResultList();
// em2.createNativeQuery("UPDATE CMP3_RESPONS SET DESCRIPTION = 'NEW' WHERE EMP_ID = "+id).executeUpdate();
} else {
emp2 = em2.find(Employee.class, id);
if (testMode2.equals("lock")) {
em2.lock(emp2, lockMode, properties);
} else if (testMode2.equals("refresh")) {
em2.refresh(emp2, lockMode, properties);
} else {
fail("Unknown testMode2 = " + testMode2);
}
}
// commitTransaction(em2);
boolean hasKilledTransaction = false;
if (transactionKiller != null) {
transactionKiller.shouldKillTransaction = false;
try {
transactionKiller.join();
} catch (InterruptedException intEx) {
// Ignore
}
hasKilledTransaction = transactionKiller.hasKilledTransaction;
}
// transaction killed by TransactionKiller is treated as PessimisticLockException
if (isExceptionExpected && !hasKilledTransaction) {
String localErrorMsg = testMode1 + (isObjCached ? " cached " : " ") + testMode2 + ": Exception was expected.";
ss.log(SessionLog.FINEST, SessionLog.QUERY, localErrorMsg, null, null, false);
errorMsg += '\n' + localErrorMsg;
}
} catch (Exception ex) {
if (transactionKiller != null) {
transactionKiller.shouldKillTransaction = false;
try {
transactionKiller.join();
} catch (InterruptedException intEx) {
// Ignore
}
}
if (!isExceptionExpected) {
String localErrorMsg = testMode1 + (isObjCached ? " cached " : " ") + testMode2 + ": Unexpected exception: " + ex.getMessage();
ss.log(SessionLog.FINEST, SessionLog.QUERY, localErrorMsg, null, null, false);
errorMsg += '\n' + localErrorMsg;
}
} finally {
if (isTransactionActive(em2)) {
rollbackTransaction(em2);
}
closeEntityManager(em2);
}
// commitTransaction(em1);
} finally {
if (isTransactionActive(em1)) {
rollbackTransaction(em1);
}
closeEntityManager(em1);
}
clearCache();
}
// testModel2 loop
}
// isObjectCached loop
}
// testMode1 loop
// clean up
em = createEntityManager();
emp = em.find(Employee.class, id);
try {
beginTransaction(em);
Iterator<Project> it = emp.getProjects().iterator();
while (it.hasNext()) {
Project project = it.next();
it.remove();
em.remove(project);
}
em.remove(emp);
commitTransaction(em);
} finally {
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
closeEntityManager(em);
}
if (errorMsg.length() > 0) {
fail(errorMsg);
}
}
Aggregations