use of org.eclipse.persistence.jpa.JpaEntityManagerFactory in project eclipselink by eclipse-ee4j.
the class EntityManagerJUnitTestSuite method testDeadConnectionFailover.
/**
* Tests that queries will be re-executed if a query fails from a dead connection.
*/
public void testDeadConnectionFailover() {
if (isOnServer()) {
// Uses DefaultConnector.
return;
}
if (JUnitTestCase.getServerSession().getPlatform().isSymfoware() || JUnitTestCase.getServerSession().getPlatform().isSybase()) {
warning("Test testDeadConnectionFailover skipped for this platform, Sybase, Symfoware platform doesn't support failover.");
return;
}
ServerSession server = ((JpaEntityManagerFactory) getEntityManagerFactory()).getServerSession();
// cache the original driver name and connection string.
String originalDriverName = server.getLogin().getDriverClassName();
String originalConnectionString = server.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);
server.logout();
server.getLogin().setDriverClassName(newDriverName);
server.getLogin().setConnectionHealthValidatedOnError(true);
server.getLogin().setConnectionString(newConnectionString);
server.login();
try {
EntityManager em = createEntityManager();
em.createQuery("Select e from Employee e").getResultList();
em.getTransaction().begin();
em.persist(new Employee());
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);
emProperties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, exclusiveConnectionMode);
em = createEntityManager(emProperties);
List<Employee> employees = em.createQuery("Select e from Employee e").getResultList();
DriverWrapper.breakOldConnections();
List<Employee> employees2 = em.createQuery("Select e from Employee e").getResultList();
if (employees.size() != employees2.size()) {
fail("Query results not the same after failure.");
}
DriverWrapper.breakOldConnections();
em.getTransaction().begin();
em.persist(new Employee());
DriverWrapper.breakOldConnections();
em.getTransaction().commit();
em.getTransaction().begin();
em.persist(new Employee());
em.flush();
DriverWrapper.breakOldConnections();
boolean failed = false;
try {
em.getTransaction().commit();
} catch (Exception shouldFail) {
failed = true;
}
if (!failed) {
fail("Retry should not work in a transaction.");
}
} 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
server.logout();
server.getLogin().setDriverClassName(originalDriverName);
server.getLogin().setConnectionString(originalConnectionString);
server.login();
}
}
use of org.eclipse.persistence.jpa.JpaEntityManagerFactory in project eclipselink by eclipse-ee4j.
the class EntityManagerJUnitTestSuite method testDeadConnectionFailover.
/**
* Tests that queries will be re-executed if a query fails from a dead connection.
*/
public void testDeadConnectionFailover() {
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.
String originalDriverName = server.getLogin().getDriverClassName();
String originalConnectionString = server.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);
broker.logout();
server.getLogin().setDriverClassName(newDriverName);
server.getLogin().setConnectionHealthValidatedOnError(true);
server.getLogin().setConnectionString(newConnectionString);
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.breakOldConnections();
List<Address> addresses2 = em.createQuery("Select a from Address a").getResultList();
if (addresses.size() != addresses2.size()) {
fail("Query results not the same after failure.");
}
DriverWrapper.breakOldConnections();
em.getTransaction().begin();
em.persist(new Address());
DriverWrapper.breakOldConnections();
em.getTransaction().commit();
em.getTransaction().begin();
em.persist(new Address());
em.flush();
DriverWrapper.breakOldConnections();
boolean failed = false;
try {
em.getTransaction().commit();
} catch (Exception shouldFail) {
failed = true;
}
if (!failed) {
fail("Retry should not work in a transaction.");
}
} 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.getLogin().setDriverClassName(originalDriverName);
server.getLogin().setConnectionString(originalConnectionString);
broker.login();
}
}
use of org.eclipse.persistence.jpa.JpaEntityManagerFactory in project eclipselink by eclipse-ee4j.
the class EntityManagerJUnitTestSuite method testEMFactoryCloseAndOpen.
// Bug 256284: Closing an EMF where the database is unavailable results in deployment exception on redeploy
public void testEMFactoryCloseAndOpen() {
if (isOnServer()) {
// Uses DefaultConnector.
return;
}
// Assert.assertFalse("Warning Sybase Driver does not work with DriverWrapper, testEMCloseAndOpen can't run on this platform.", getPlatform(Employee.class).isSybase());
SessionBroker broker = ((JpaEntityManagerFactory) getEntityManagerFactory()).getSessionBroker();
ServerSession ss = (ServerSession) broker.getSessionForClass(Employee.class);
// cache the driver name
String driverName = ss.getLogin().getDriverClassName();
String originalConnectionString = ss.getLogin().getConnectionString();
// disconnect the session
closeEntityManagerFactory();
// setup the wrapper driver
DriverWrapper.initialize(driverName);
// connect the session using the wrapper driver
HashMap properties = new HashMap(JUnitTestCaseHelper.getDatabaseProperties(getPersistenceUnitName()));
Map mapOfProperties = (Map) properties.get(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES);
if (mapOfProperties == null) {
mapOfProperties = new HashMap(1);
} else {
mapOfProperties = new HashMap(mapOfProperties);
}
properties.put(PersistenceUnitProperties.COMPOSITE_UNIT_PROPERTIES, mapOfProperties);
Map memberProperties = (Map) mapOfProperties.get(ss.getName());
if (memberProperties == null) {
memberProperties = new HashMap(2);
} else {
memberProperties = new HashMap(memberProperties);
}
mapOfProperties.put(ss.getName(), memberProperties);
memberProperties.put(PersistenceUnitProperties.JDBC_DRIVER, DriverWrapper.class.getName());
memberProperties.put(PersistenceUnitProperties.JDBC_URL, DriverWrapper.codeUrl(originalConnectionString));
getEntityManagerFactory(properties);
// this connects the session
EntityManager em = createEntityManager();
// imitate disconnecting from network:
// driver's connect method and any method on any connection will throw SQLException
DriverWrapper.breakDriver();
DriverWrapper.breakOldConnections();
// close factory
try {
closeEntityManagerFactory();
} finally {
// clear the driver wrapper
DriverWrapper.clear();
}
String errorMsg = "";
// reconnect the session
em = createEntityManager();
// verify connections
Iterator<ConnectionPool> itPools = ((ServerSession) ((EntityManagerImpl) em).getSessionBroker().getSessionForName(ss.getName())).getConnectionPools().values().iterator();
while (itPools.hasNext()) {
ConnectionPool pool = itPools.next();
int disconnected = 0;
for (int i = 0; i < pool.getConnectionsAvailable().size(); i++) {
if (!(pool.getConnectionsAvailable().get(i)).isConnected()) {
disconnected++;
}
}
if (disconnected > 0) {
errorMsg += pool.getName() + " has " + disconnected + " connections; ";
}
}
if (errorMsg.length() > 0) {
fail(errorMsg);
}
}
use of org.eclipse.persistence.jpa.JpaEntityManagerFactory in project eclipselink by eclipse-ee4j.
the class ProxyAuthenticationTestSuite method internalTest.
void internalTest(boolean shouldUseExternalConnectionPooling, Map serverSessionProxyProperties, boolean shoulUseExclusiveIsolatedSession, Map clientSessionProxyProperties) {
if (shouldUseExternalConnectionPooling) {
// create data source and add it to factoryProperties
createDataSource((String) factoryProperties.get(PersistenceUnitProperties.JDBC_URL));
factoryProperties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, dataSource);
}
if (shoulUseExclusiveIsolatedSession) {
factoryProperties.put(PersistenceUnitProperties.EXCLUSIVE_CONNECTION_MODE, ExclusiveConnectionMode.Isolated);
}
// EMFactory uses proxyProperties
if (serverSessionProxyProperties != null) {
factoryProperties.putAll(serverSessionProxyProperties);
}
EntityManagerFactory factory = getEntityManagerFactory(factoryProperties);
ServerSession ss = ((JpaEntityManagerFactory) factory).getServerSession();
if (shoulUseExclusiveIsolatedSession) {
ss.getDefaultConnectionPolicy().setExclusiveMode(ConnectionPolicy.ExclusiveMode.Always);
}
String expectedMainSessionUser = ProxyAuthenticationUsersAndProperties.connectionUser;
if (serverSessionProxyProperties != null) {
expectedMainSessionUser = getExpectedUserName(serverSessionProxyProperties);
}
// in case no proxy properties specified on the ClientSession it uses the same use as the ServerSession.
String expectedClientSessionUser = expectedMainSessionUser;
if (clientSessionProxyProperties != null) {
expectedClientSessionUser = getExpectedUserName(clientSessionProxyProperties);
}
// The second ClientSession created without proxy properties.
EntityManager em1 = factory.createEntityManager();
boolean isExclusiveIsolated = ((UnitOfWorkImpl) ((org.eclipse.persistence.internal.jpa.EntityManagerImpl) em1).getActiveSession()).getParent() instanceof ExclusiveIsolatedClientSession;
if (isExclusiveIsolated != shoulUseExclusiveIsolatedSession) {
if (isExclusiveIsolated) {
fail("EntityManager is using ExclusiveIsolatedClientSession, ClientSession was expected");
} else {
fail("EntityManager is using ClientSession, ExclusiveIsolatedClientSession was expected");
}
}
verifyUser("ClientSession1 before transaction read", getReadUser(em1), expectedMainSessionUser);
beginTransaction(em1);
verifyUser("ClientSession1 in transaction read", getReadUser(em1), expectedMainSessionUser);
verifyUser("ClientSession1 wrote", getWriteUser(em1), expectedMainSessionUser);
rollbackTransaction(em1);
verifyUser("ClientSession1 after transaction read", getReadUser(em1), expectedMainSessionUser);
em1.close();
// The second ClientSession created with proxy properties.
EntityManager em2 = factory.createEntityManager(clientSessionProxyProperties);
if (shoulUseExclusiveIsolatedSession) {
verifyUser("ExclusiveIsolatedClientSession2 before transaction read", getReadUser(em2), expectedClientSessionUser);
} else {
verifyUser("ClientSession2 before transaction read", getReadUser(em2), expectedMainSessionUser);
}
beginTransaction(em2);
verifyUser("ClientSession2 in transaction read", getReadUser(em2), expectedClientSessionUser);
verifyUser("ClientSession2 wrote", getWriteUser(em2), expectedClientSessionUser);
rollbackTransaction(em2);
if (shoulUseExclusiveIsolatedSession) {
verifyUser("ExclusiveIsolatedClientSession2 after transaction read", getReadUser(em2), expectedClientSessionUser);
} else {
verifyUser("ClientSession2 after transaction read", getReadUser(em2), expectedMainSessionUser);
}
em2.close();
// The third ClientSession created without proxy properties again - should always use the same user as ServerSession.
// Because there is one one connection in each connection pool (internal pool case) this would fail in case proxy customizer
// wasn't removed by cs2.
EntityManager em3 = factory.createEntityManager();
verifyUser("ClientSession3 before transaction read", getReadUser(em3), expectedMainSessionUser);
beginTransaction(em3);
verifyUser("ClientSession3 in transaction read", getReadUser(em3), expectedMainSessionUser);
verifyUser("ClientSession3 wrote", getWriteUser(em3), expectedMainSessionUser);
rollbackTransaction(em3);
verifyUser("ClientSession3 after transaction read", getReadUser(em3), expectedMainSessionUser);
em3.close();
if (errorMsg.length() > 0) {
fail(errorMsg);
}
}
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.", JUnitTestCase.getServerSession().getPlatform().isSybase());
if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
getServerSession().logMessage("Test testEMCloseAndOpen skipped for this platform, " + "Symfoware platform doesn't support failover.");
return;
} else if ((JUnitTestCase.getServerSession()).getPlatform().isPervasive()) {
getServerSession().logMessage("Test testEMCloseAndOpen skipped for this platform.");
return;
}
// normally false; set to true for debug output for just this single test
boolean shouldForceFinest = false;
int originalLogLevel = -1;
ServerSession ss = ((JpaEntityManagerFactory) getEntityManagerFactory()).getServerSession();
// 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(Employee.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 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.
ss.logout();
ss.getLogin().setDriverClassName(newDriverName);
ss.getLogin().setConnectionString(newConnectionString);
AcquireReleaseListener listener = new AcquireReleaseListener();
ss.getEventManager().addListener(listener);
if (shouldForceFinest) {
if (ss.getLogLevel() != SessionLog.FINEST) {
originalLogLevel = ss.getLogLevel();
ss.setLogLevel(SessionLog.FINEST);
}
}
ss.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 employeeFindQuery = ss.getDescriptor(Employee.class).getQueryManager().getReadObjectQuery();
int originalQueryTimeout = employeeFindQuery.getQueryTimeout();
if (originalQueryTimeout > 0) {
ss.setQueryTimeoutDefault(0);
employeeFindQuery.setQueryTimeout(0);
// The same bug 309881 requires the query to be reprepaired for queryTimeOut to be set on its call
employeeFindQuery.setIsPrepared(false);
employeeFindQuery.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);
ss.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: " + (useSequencing ? "sequencing" : "no sequencing"), null, null, false);
HashMap emProperties = new HashMap(1);
emProperties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, exclusiveConnectionMode);
EntityManager em = createEntityManager(emProperties);
em.find(Employee.class, 1, noTimeOutHint);
Employee emp = 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
ss.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: DriverWrapper.breakDriver(); DriverWrapper.breakOldConnections();", null, null, false);
DriverWrapper.breakDriver();
DriverWrapper.breakOldConnections();
emp = new Employee();
if (!useSequencing) {
emp.setId(id);
}
em.persist(emp);
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();
ss.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: DriverWrapper.repairDriver();", null, null, false);
boolean failed = true;
try {
em = createEntityManager();
em.find(Employee.class, 1);
if (!hasUnexpectedlyCommitted) {
em.getTransaction().begin();
emp = new Employee();
if (!useSequencing) {
emp.setId(id);
}
em.persist(emp);
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) {
ss.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: errorMsg: " + "\n" + errorMsg, null, null, false);
}
}
}
// clean-up
// remove the inserted object
em.getTransaction().begin();
em.remove(emp);
em.getTransaction().commit();
closeEntityManager(em);
}
}
} finally {
// This should be removed from the test after the bug is fixed.
if (originalQueryTimeout > 0) {
ss.setQueryTimeoutDefault(originalQueryTimeout);
employeeFindQuery.setQueryTimeout(originalQueryTimeout);
// The same bug 309881 requires the query to be reprepaired for queryTimeOut to be set on its call
employeeFindQuery.setIsPrepared(false);
employeeFindQuery.checkPrepare(ss, null);
}
// clear the driver wrapper
DriverWrapper.clear();
// reconnect the session using the original driver and connection string
ss.getEventManager().removeListener(listener);
ss.logout();
if (originalLogLevel >= 0) {
ss.setLogLevel(originalLogLevel);
}
ss.getLogin().setDriverClassName(originalDriverName);
ss.getLogin().setConnectionString(originalConnectionString);
ss.login();
if (errorMsg.length() > 0) {
fail(errorMsg);
}
}
}
Aggregations