@Override public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException { Connection con = entityManager.unwrap(Connection.class); return (con != null ? new SimpleConnectionHandle(con) : null); }
/** * This implementation always returns {@code null}, * indicating that no JDBC Connection can be provided. */ @Override public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException { return null; }
@Override public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException { Session session = getSession(entityManager); return new HibernateConnectionHandle(session); }
@Override public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException { // As of Spring 4.1.2, we're using a custom ConnectionHandle for lazy retrieval // of the underlying Connection (allowing for deferred internal transaction begin // within the EclipseLink EntityManager) return new EclipseLinkConnectionHandle(entityManager); }
@Override public ConnectionHandle getJdbcConnection(EntityManager em, boolean readOnly) throws PersistenceException, SQLException { AbstractSession session = (AbstractSession) getSession(em); // The connection was already acquired eagerly in beginTransaction, // unless lazyDatabaseTransaction was set to true. Connection con = session.getAccessor().getConnection(); return (con != null ? new SimpleConnectionHandle(con) : null); }
@Override public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException { return new OpenJpaConnectionHandle(getOpenJPAEntityManager(entityManager)); }
@Test public void testTransactionCommitWithDataSource() throws SQLException { final DataSource ds = mock(DataSource.class); JdoDialect dialect = mock(JdoDialect.class); final Connection con = mock(Connection.class); ConnectionHandle conHandle = new SimpleConnectionHandle(con); given(pmf.getPersistenceManager()).willReturn(pm); given(pm.currentTransaction()).willReturn(tx); TransactionTemplate tt = new TransactionTemplate(); given(dialect.getJdbcConnection(pm, false)).willReturn(conHandle); JdoTransactionManager tm = new JdoTransactionManager(); tm.setPersistenceManagerFactory(pmf); tm.setDataSource(ds); tm.setJdoDialect(dialect); tt.setTransactionManager(tm); final List l = new ArrayList(); l.add("test"); assertTrue("Hasn't thread pm", !TransactionSynchronizationManager.hasResource(pmf)); Object result = tt.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { assertTrue("Has thread pm", TransactionSynchronizationManager.hasResource(pmf)); assertTrue("Has thread con", TransactionSynchronizationManager.hasResource(ds)); PersistenceManagerFactoryUtils.getPersistenceManager(pmf, true); return l; } }); assertTrue("Correct result list", result == l); assertTrue("Hasn't thread pm", !TransactionSynchronizationManager.hasResource(pmf)); assertTrue("Hasn't thread con", !TransactionSynchronizationManager.hasResource(ds)); verify(pm).close(); verify(dialect).beginTransaction(tx, tt); verify(dialect).releaseJdbcConnection(conHandle, pm); verify(dialect).cleanupTransaction(null); verify(tx).commit(); }
@Test public void testTransactionCommitWithAutoDetectedDataSource() throws SQLException { final DataSource ds = mock(DataSource.class); JdoDialect dialect = mock(JdoDialect.class); final Connection con = mock(Connection.class); ConnectionHandle conHandle = new SimpleConnectionHandle(con); given(pmf.getConnectionFactory()).willReturn(ds); given(pmf.getPersistenceManager()).willReturn(pm); given(pm.currentTransaction()).willReturn(tx); TransactionTemplate tt = new TransactionTemplate(); given(dialect.getJdbcConnection(pm, false)).willReturn(conHandle); JdoTransactionManager tm = new JdoTransactionManager(); tm.setPersistenceManagerFactory(pmf); tm.setJdoDialect(dialect); tm.afterPropertiesSet(); tt.setTransactionManager(tm); final List l = new ArrayList(); l.add("test"); assertTrue("Hasn't thread pm", !TransactionSynchronizationManager.hasResource(pmf)); Object result = tt.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { assertTrue("Has thread pm", TransactionSynchronizationManager.hasResource(pmf)); assertTrue("Has thread con", TransactionSynchronizationManager.hasResource(ds)); PersistenceManagerFactoryUtils.getPersistenceManager(pmf, true); return l; } }); assertTrue("Correct result list", result == l); assertTrue("Hasn't thread pm", !TransactionSynchronizationManager.hasResource(pmf)); assertTrue("Hasn't thread con", !TransactionSynchronizationManager.hasResource(ds)); verify(pm).close(); verify(dialect).beginTransaction(tx, tt); verify(dialect).releaseJdbcConnection(conHandle, pm); verify(dialect).cleanupTransaction(null); verify(tx).commit(); }
/** * This implementation always returns {@code null}, * indicating that no JDBC Connection can be provided. */ public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException { return null; }
@Override public ConnectionHandle getJdbcConnection(final EntityManager entityManager, final boolean readOnly) throws PersistenceException, SQLException { return new OpenJpaConnectionHandle(getOpenJPAEntityManager(entityManager)); }
/** * This implementation returns a DataStoreConnectionHandle for JDO. * <p><b>NOTE:</b> A JDO DataStoreConnection is always a wrapper, * never the native JDBC Connection. If you need access to the native JDBC * Connection (or the connection pool handle, to be unwrapped via a Spring * NativeJdbcExtractor), override this method to return the native * Connection through the corresponding vendor-specific mechanism. * <p>A JDO DataStoreConnection is only "borrowed" from the PersistenceManager: * it needs to be returned as early as possible. Effectively, JDO requires the * fetched Connection to be closed before continuing PersistenceManager work. * For this reason, the exposed ConnectionHandle eagerly releases its JDBC * Connection at the end of each JDBC data access operation (that is, on * {@code DataSourceUtils.releaseConnection}). * @see javax.jdo.PersistenceManager#getDataStoreConnection() * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor * @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection */ @Override public ConnectionHandle getJdbcConnection(PersistenceManager pm, boolean readOnly) throws JDOException, SQLException { return new DataStoreConnectionHandle(pm); }
/** * This implementation does nothing, assuming that the Connection * will implicitly be closed with the EntityManager. * <p>If the JPA implementation returns a Connection handle that it expects * the application to close after use, the dialect implementation needs to invoke * {@code Connection.close()} (or some other method with similar effect) here. * @see java.sql.Connection#close() */ @Override public void releaseJdbcConnection(ConnectionHandle conHandle, EntityManager em) throws PersistenceException, SQLException { }
/** * Retrieve the JDBC Connection that the given JPA EntityManager uses underneath, * if accessing a relational database. This method will just get invoked if actually * needing access to the underlying JDBC Connection, usually within an active JPA * transaction (for example, by JpaTransactionManager). The returned handle will * be passed into the {@code releaseJdbcConnection} method when not needed anymore. * <p>This strategy is necessary as JPA does not provide a standard way to retrieve * the underlying JDBC Connection (due to the fact that a JPA implementation might not * work with a relational database at all). * <p>Implementations are encouraged to return an unwrapped Connection object, i.e. * the Connection as they got it from the connection pool. This makes it easier for * application code to get at the underlying native JDBC Connection, like an * OracleConnection, which is sometimes necessary for LOB handling etc. We assume * that calling code knows how to properly handle the returned Connection object. * <p>In a simple case where the returned Connection will be auto-closed with the * EntityManager or can be released via the Connection object itself, an * implementation can return a SimpleConnectionHandle that just contains the * Connection. If some other object is needed in {@code releaseJdbcConnection}, * an implementation should use a special handle that references that other object. * @param entityManager the current JPA EntityManager * @param readOnly whether the Connection is only needed for read-only purposes * @return a handle for the JDBC Connection, to be passed into * {@code releaseJdbcConnection}, or {@code null} * if no JDBC Connection can be retrieved * @throws javax.persistence.PersistenceException if thrown by JPA methods * @throws java.sql.SQLException if thrown by JDBC methods * @see #releaseJdbcConnection * @see org.springframework.jdbc.datasource.ConnectionHandle#getConnection * @see org.springframework.jdbc.datasource.SimpleConnectionHandle * @see JpaTransactionManager#setDataSource * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor */ ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException;
/** * Release the given JDBC Connection, which has originally been retrieved * via {@code getJdbcConnection}. This should be invoked in any case, * to allow for proper release of the retrieved Connection handle. * <p>An implementation might simply do nothing, if the Connection returned * by {@code getJdbcConnection} will be implicitly closed when the JPA * transaction completes or when the EntityManager is closed. * @param conHandle the JDBC Connection handle to release * @param entityManager the current JPA EntityManager * @throws javax.persistence.PersistenceException if thrown by JPA methods * @throws java.sql.SQLException if thrown by JDBC methods * @see #getJdbcConnection */ void releaseJdbcConnection(ConnectionHandle conHandle, EntityManager entityManager) throws PersistenceException, SQLException;
/** * This implementation does nothing, assuming that the Connection * will implicitly be closed with the PersistenceManager. * <p>If the JDO provider returns a Connection handle that it * expects the application to close, the dialect needs to invoke * {@code Connection.close} here. * @see java.sql.Connection#close() */ @Override public void releaseJdbcConnection(ConnectionHandle conHandle, PersistenceManager pm) throws JDOException, SQLException { }
/** * Retrieve the JDBC Connection that the given JDO PersistenceManager uses underneath, * if accessing a relational database. This method will just get invoked if actually * needing access to the underlying JDBC Connection, usually within an active JDO * transaction (for example, by JdoTransactionManager). The returned handle will * be passed into the {@code releaseJdbcConnection} method when not needed anymore. * <p>Implementations are encouraged to return an unwrapped Connection object, i.e. * the Connection as they got it from the connection pool. This makes it easier for * application code to get at the underlying native JDBC Connection, like an * OracleConnection, which is sometimes necessary for LOB handling etc. We assume * that calling code knows how to properly handle the returned Connection object. * <p>In a simple case where the returned Connection will be auto-closed with the * PersistenceManager or can be released via the Connection object itself, an * implementation can return a SimpleConnectionHandle that just contains the * Connection. If some other object is needed in {@code releaseJdbcConnection}, * an implementation should use a special handle that references that other object. * @param pm the current JDO PersistenceManager * @param readOnly whether the Connection is only needed for read-only purposes * @return a handle for the JDBC Connection, to be passed into * {@code releaseJdbcConnection}, or {@code null} * if no JDBC Connection can be retrieved * @throws JDOException if thrown by JDO methods * @throws SQLException if thrown by JDBC methods * @see #releaseJdbcConnection * @see org.springframework.jdbc.datasource.ConnectionHandle#getConnection * @see org.springframework.jdbc.datasource.SimpleConnectionHandle * @see JdoTransactionManager#setDataSource * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor */ ConnectionHandle getJdbcConnection(PersistenceManager pm, boolean readOnly) throws JDOException, SQLException;
/** * Release the given JDBC Connection, which has originally been retrieved * via {@code getJdbcConnection}. This should be invoked in any case, * to allow for proper release of the retrieved Connection handle. * <p>An implementation might simply do nothing, if the Connection returned * by {@code getJdbcConnection} will be implicitly closed when the JDO * transaction completes or when the PersistenceManager is closed. * @param conHandle the JDBC Connection handle to release * @param pm the current JDO PersistenceManager * @throws JDOException if thrown by JDO methods * @throws SQLException if thrown by JDBC methods * @see #getJdbcConnection */ void releaseJdbcConnection(ConnectionHandle conHandle, PersistenceManager pm) throws JDOException, SQLException;
/** * Retrieve the JDBC Connection that the given JPA EntityManager uses underneath, * if accessing a relational database. This method will just get invoked if actually * needing access to the underlying JDBC Connection, usually within an active JPA * transaction (for example, by JpaTransactionManager). The returned handle will * be passed into the {@code releaseJdbcConnection} method when not needed anymore. * <p>This strategy is necessary as JPA does not provide a standard way to retrieve * the underlying JDBC Connection (due to the fact that a JPA implementation might not * work with a relational database at all). * <p>Implementations are encouraged to return an unwrapped Connection object, i.e. * the Connection as they got it from the connection pool. This makes it easier for * application code to get at the underlying native JDBC Connection, like an * OracleConnection, which is sometimes necessary for LOB handling etc. We assume * that calling code knows how to properly handle the returned Connection object. * <p>In a simple case where the returned Connection will be auto-closed with the * EntityManager or can be released via the Connection object itself, an * implementation can return a SimpleConnectionHandle that just contains the * Connection. If some other object is needed in {@code releaseJdbcConnection}, * an implementation should use a special handle that references that other object. * @param entityManager the current JPA EntityManager * @param readOnly whether the Connection is only needed for read-only purposes * @return a handle for the Connection, to be passed into {@code releaseJdbcConnection}, * or {@code null} if no JDBC Connection can be retrieved * @throws javax.persistence.PersistenceException if thrown by JPA methods * @throws java.sql.SQLException if thrown by JDBC methods * @see #releaseJdbcConnection * @see org.springframework.jdbc.datasource.ConnectionHandle#getConnection * @see org.springframework.jdbc.datasource.SimpleConnectionHandle * @see JpaTransactionManager#setDataSource * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor */ ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException;
/** * This implementation does nothing, assuming that the Connection * will implicitly be closed with the EntityManager. * <p>If the JPA implementation returns a Connection handle that it expects * the application to close after use, the dialect implementation needs to invoke * {@code Connection.close()} (or some other method with similar effect) here. * @see java.sql.Connection#close() */ public void releaseJdbcConnection(ConnectionHandle conHandle, EntityManager em) throws PersistenceException, SQLException { }
/** * Retrieve the JDBC Connection that the given JPA EntityManager uses underneath, * if accessing a relational database. This method will just get invoked if actually * needing access to the underlying JDBC Connection, usually within an active JPA * transaction (for example, by JpaTransactionManager). The returned handle will * be passed into the {@code releaseJdbcConnection} method when not needed anymore. * <p>This strategy is necessary as JPA 1.0 does not provide a standard way to retrieve * the underlying JDBC Connection (due to the fact that a JPA implementation might not * work with a relational database at all). * <p>Implementations are encouraged to return an unwrapped Connection object, i.e. * the Connection as they got it from the connection pool. This makes it easier for * application code to get at the underlying native JDBC Connection, like an * OracleConnection, which is sometimes necessary for LOB handling etc. We assume * that calling code knows how to properly handle the returned Connection object. * <p>In a simple case where the returned Connection will be auto-closed with the * EntityManager or can be released via the Connection object itself, an * implementation can return a SimpleConnectionHandle that just contains the * Connection. If some other object is needed in {@code releaseJdbcConnection}, * an implementation should use a special handle that references that other object. * @param entityManager the current JPA EntityManager * @param readOnly whether the Connection is only needed for read-only purposes * @return a handle for the JDBC Connection, to be passed into * {@code releaseJdbcConnection}, or {@code null} * if no JDBC Connection can be retrieved * @throws javax.persistence.PersistenceException if thrown by JPA methods * @throws java.sql.SQLException if thrown by JDBC methods * @see #releaseJdbcConnection * @see org.springframework.jdbc.datasource.ConnectionHandle#getConnection * @see org.springframework.jdbc.datasource.SimpleConnectionHandle * @see JpaTransactionManager#setDataSource * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor */ ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException;
/** * This implementation returns a DataStoreConnectionHandle for JDO2, * which will also work on JDO1 until actually accessing the JDBC Connection. * <p>For pre-JDO2 implementations, override this method to return the * Connection through the corresponding vendor-specific mechanism, or {@code null} * if the Connection is not retrievable. * <p><b>NOTE:</b> A JDO2 DataStoreConnection is always a wrapper, * never the native JDBC Connection. If you need access to the native JDBC * Connection (or the connection pool handle, to be unwrapped via a Spring * NativeJdbcExtractor), override this method to return the native * Connection through the corresponding vendor-specific mechanism. * <p>A JDO2 DataStoreConnection is only "borrowed" from the PersistenceManager: * it needs to be returned as early as possible. Effectively, JDO2 requires the * fetched Connection to be closed before continuing PersistenceManager work. * For this reason, the exposed ConnectionHandle eagerly releases its JDBC * Connection at the end of each JDBC data access operation (that is, on * {@code DataSourceUtils.releaseConnection}). * @see javax.jdo.PersistenceManager#getDataStoreConnection() * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor * @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection */ public ConnectionHandle getJdbcConnection(PersistenceManager pm, boolean readOnly) throws JDOException, SQLException { return new DataStoreConnectionHandle(pm); }
/** * This implementation does nothing, assuming that the Connection * will implicitly be closed with the PersistenceManager. * <p>If the JDO provider returns a Connection handle that it * expects the application to close, the dialect needs to invoke * {@code Connection.close} here. * @see java.sql.Connection#close() */ public void releaseJdbcConnection(ConnectionHandle conHandle, PersistenceManager pm) throws JDOException, SQLException { }