Search in sources :

Example 1 with JpaEntityManagerFactory

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();
        }
    }
}
Also used : Connector(org.eclipse.persistence.sessions.Connector) JNDIConnector(org.eclipse.persistence.sessions.JNDIConnector) ServerSession(org.eclipse.persistence.sessions.server.ServerSession) Address(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_1.Address) HashMap(java.util.HashMap) DataSourceImpl(org.eclipse.persistence.internal.jpa.jdbc.DataSourceImpl) SessionBroker(org.eclipse.persistence.sessions.broker.SessionBroker) UnitOfWorkImpl(org.eclipse.persistence.internal.sessions.UnitOfWorkImpl) EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) JpaEntityManagerFactory(org.eclipse.persistence.jpa.JpaEntityManagerFactory) JNDIConnector(org.eclipse.persistence.sessions.JNDIConnector) ConnectionPolicy(org.eclipse.persistence.sessions.server.ConnectionPolicy)

Example 2 with JpaEntityManagerFactory

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();
    }
}
Also used : DatabaseLogin(org.eclipse.persistence.sessions.DatabaseLogin) ServerSession(org.eclipse.persistence.sessions.server.ServerSession) EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) Address(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_1.Address) HashMap(java.util.HashMap) SessionBroker(org.eclipse.persistence.sessions.broker.SessionBroker) JpaEntityManagerFactory(org.eclipse.persistence.jpa.JpaEntityManagerFactory) ArrayList(java.util.ArrayList) TestProblemException(org.eclipse.persistence.testing.framework.TestProblemException) IntegrityException(org.eclipse.persistence.exceptions.IntegrityException) EntityNotFoundException(jakarta.persistence.EntityNotFoundException) ValidationException(org.eclipse.persistence.exceptions.ValidationException) EclipseLinkException(org.eclipse.persistence.exceptions.EclipseLinkException) EntityExistsException(jakarta.persistence.EntityExistsException) OptimisticLockException(jakarta.persistence.OptimisticLockException) RollbackException(jakarta.persistence.RollbackException) PersistenceException(jakarta.persistence.PersistenceException) QueryException(org.eclipse.persistence.exceptions.QueryException) TransactionRequiredException(jakarta.persistence.TransactionRequiredException)

Example 3 with JpaEntityManagerFactory

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);
        }
    }
}
Also used : ServerSession(org.eclipse.persistence.sessions.server.ServerSession) Address(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_1.Address) ReadObjectQuery(org.eclipse.persistence.queries.ReadObjectQuery) HashMap(java.util.HashMap) SessionBroker(org.eclipse.persistence.sessions.broker.SessionBroker) TestProblemException(org.eclipse.persistence.testing.framework.TestProblemException) IntegrityException(org.eclipse.persistence.exceptions.IntegrityException) EntityNotFoundException(jakarta.persistence.EntityNotFoundException) ValidationException(org.eclipse.persistence.exceptions.ValidationException) EclipseLinkException(org.eclipse.persistence.exceptions.EclipseLinkException) EntityExistsException(jakarta.persistence.EntityExistsException) OptimisticLockException(jakarta.persistence.OptimisticLockException) RollbackException(jakarta.persistence.RollbackException) PersistenceException(jakarta.persistence.PersistenceException) QueryException(org.eclipse.persistence.exceptions.QueryException) TransactionRequiredException(jakarta.persistence.TransactionRequiredException) EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) JpaEntityManagerFactory(org.eclipse.persistence.jpa.JpaEntityManagerFactory)

Example 4 with JpaEntityManagerFactory

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();
}
Also used : JpaEntityManagerFactory(org.eclipse.persistence.jpa.JpaEntityManagerFactory)

Example 5 with JpaEntityManagerFactory

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);
    }
}
Also used : SmallProject(org.eclipse.persistence.testing.models.jpa.advanced.SmallProject) ServerSession(org.eclipse.persistence.sessions.server.ServerSession) ReportQuery(org.eclipse.persistence.queries.ReportQuery) JpaQuery(org.eclipse.persistence.jpa.JpaQuery) ObjectLevelReadQuery(org.eclipse.persistence.queries.ObjectLevelReadQuery) DatabaseQuery(org.eclipse.persistence.queries.DatabaseQuery) Query(jakarta.persistence.Query) ReadObjectQuery(org.eclipse.persistence.queries.ReadObjectQuery) ReadAllQuery(org.eclipse.persistence.queries.ReadAllQuery) ValueReadQuery(org.eclipse.persistence.queries.ValueReadQuery) DataModifyQuery(org.eclipse.persistence.queries.DataModifyQuery) TypedQuery(jakarta.persistence.TypedQuery) HashMap(java.util.HashMap) TestProblemException(org.eclipse.persistence.testing.framework.TestProblemException) ValidationException(org.eclipse.persistence.exceptions.ValidationException) EclipseLinkException(org.eclipse.persistence.exceptions.EclipseLinkException) EntityExistsException(jakarta.persistence.EntityExistsException) OptimisticLockException(jakarta.persistence.OptimisticLockException) QueryException(org.eclipse.persistence.exceptions.QueryException) TransactionRequiredException(jakarta.persistence.TransactionRequiredException) IntegrityException(org.eclipse.persistence.exceptions.IntegrityException) EntityNotFoundException(jakarta.persistence.EntityNotFoundException) SQLException(java.sql.SQLException) RollbackException(jakarta.persistence.RollbackException) NoResultException(jakarta.persistence.NoResultException) PersistenceException(jakarta.persistence.PersistenceException) PersistenceUnitLoadingException(org.eclipse.persistence.exceptions.PersistenceUnitLoadingException) Project(org.eclipse.persistence.testing.models.jpa.advanced.Project) HugeProject(org.eclipse.persistence.testing.models.jpa.advanced.HugeProject) SmallProject(org.eclipse.persistence.testing.models.jpa.advanced.SmallProject) SuperLargeProject(org.eclipse.persistence.testing.models.jpa.advanced.SuperLargeProject) SpecialHugeProject(org.eclipse.persistence.testing.models.jpa.advanced.SpecialHugeProject) LargeProject(org.eclipse.persistence.testing.models.jpa.advanced.LargeProject) EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) Employee(org.eclipse.persistence.testing.models.jpa.advanced.Employee) JpaEntityManagerFactory(org.eclipse.persistence.jpa.JpaEntityManagerFactory) LockModeType(jakarta.persistence.LockModeType) SuperLargeProject(org.eclipse.persistence.testing.models.jpa.advanced.SuperLargeProject) LargeProject(org.eclipse.persistence.testing.models.jpa.advanced.LargeProject)

Aggregations

JpaEntityManagerFactory (org.eclipse.persistence.jpa.JpaEntityManagerFactory)20 EntityManager (jakarta.persistence.EntityManager)14 HashMap (java.util.HashMap)13 JpaEntityManager (org.eclipse.persistence.jpa.JpaEntityManager)13 ServerSession (org.eclipse.persistence.sessions.server.ServerSession)13 PersistenceException (jakarta.persistence.PersistenceException)9 EntityExistsException (jakarta.persistence.EntityExistsException)7 EntityNotFoundException (jakarta.persistence.EntityNotFoundException)7 OptimisticLockException (jakarta.persistence.OptimisticLockException)7 RollbackException (jakarta.persistence.RollbackException)7 TransactionRequiredException (jakarta.persistence.TransactionRequiredException)7 EclipseLinkException (org.eclipse.persistence.exceptions.EclipseLinkException)7 IntegrityException (org.eclipse.persistence.exceptions.IntegrityException)7 QueryException (org.eclipse.persistence.exceptions.QueryException)7 ValidationException (org.eclipse.persistence.exceptions.ValidationException)7 TestProblemException (org.eclipse.persistence.testing.framework.TestProblemException)7 EntityManagerFactory (jakarta.persistence.EntityManagerFactory)5 SessionBroker (org.eclipse.persistence.sessions.broker.SessionBroker)5 Employee (org.eclipse.persistence.testing.models.jpa.advanced.Employee)5 NoResultException (jakarta.persistence.NoResultException)4