HHH-5765 : Refactor JDBCContext/ConnectionManager spi/impl and to use new proxies
This commit is contained in:
parent
cc4055d50c
commit
b006a6c3c5
hibernate-core/src
main/java/org/hibernate
cfg
context
dialect/lock
PessimisticReadSelectLockingStrategy.javaPessimisticReadUpdateLockingStrategy.javaPessimisticWriteSelectLockingStrategy.javaPessimisticWriteUpdateLockingStrategy.javaSelectLockingStrategy.javaUpdateLockingStrategy.java
engine
ActionQueue.javaSessionImplementor.java
jdbc
internal
ConnectionManagerImpl.javaJDBCContextImpl.javaJdbcResourceRegistryImpl.javaLogicalConnectionImpl.java
proxy
spi
query
hql/ast/exec
AbstractStatementExecutor.javaBasicExecutor.javaMultiTableDeleteExecutor.javaMultiTableUpdateExecutor.java
id
GUIDGenerator.javaIdentityGenerator.javaIncrementGenerator.javaSequenceGenerator.javaSequenceIdentityGenerator.java
enhanced
insert
impl
jdbc
AbstractBatcher.javaBatcher.javaBatcherFactory.javaBatchingBatcher.javaBatchingBatcherFactory.javaNonBatchingBatcher.javaNonBatchingBatcherFactory.java
loader
persister
collection
entity
transaction
CMTTransaction.javaCMTTransactionFactory.javaCacheSynchronization.javaJDBCTransaction.javaJDBCTransactionFactory.javaJTATransaction.javaJTATransactionFactory.javaTransactionFactory.java
synchronization
type
test
java/org/hibernate/test
insertordering
jdbc/proxies
manytomany/batchload
resources
hibernate-entitymanager/src/main/java/org/hibernate/ejb/transaction
hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy
|
@ -30,6 +30,7 @@ import org.hibernate.EntityMode;
|
|||
import org.hibernate.cache.QueryCacheFactory;
|
||||
import org.hibernate.cache.RegionFactory;
|
||||
import org.hibernate.engine.jdbc.JdbcSupport;
|
||||
import org.hibernate.engine.jdbc.batch.internal.BatchBuilder;
|
||||
import org.hibernate.hql.QueryTranslatorFactory;
|
||||
import org.hibernate.jdbc.BatcherFactory;
|
||||
import org.hibernate.jdbc.util.SQLStatementLogger;
|
||||
|
@ -78,6 +79,7 @@ public final class Settings {
|
|||
private TransactionFactory transactionFactory;
|
||||
private TransactionManagerLookup transactionManagerLookup;
|
||||
private BatcherFactory batcherFactory;
|
||||
private BatchBuilder batchBuilder;
|
||||
private QueryTranslatorFactory queryTranslatorFactory;
|
||||
private boolean wrapResultSetsEnabled;
|
||||
private boolean orderUpdatesEnabled;
|
||||
|
@ -230,6 +232,10 @@ public final class Settings {
|
|||
return batcherFactory;
|
||||
}
|
||||
|
||||
public BatchBuilder getBatchBuilder() {
|
||||
return batchBuilder;
|
||||
}
|
||||
|
||||
public boolean isAutoCloseSessionEnabled() {
|
||||
return autoCloseSessionEnabled;
|
||||
}
|
||||
|
@ -417,6 +423,10 @@ public final class Settings {
|
|||
this.batcherFactory = batcher;
|
||||
}
|
||||
|
||||
void setBatcherBuilder(BatchBuilder batchBuilder) {
|
||||
this.batchBuilder = batchBuilder;
|
||||
}
|
||||
|
||||
void setAutoCloseSessionEnabled(boolean autoCloseSessionEnabled) {
|
||||
this.autoCloseSessionEnabled = autoCloseSessionEnabled;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.hibernate.cache.QueryCacheFactory;
|
|||
import org.hibernate.cache.RegionFactory;
|
||||
import org.hibernate.cache.impl.NoCachingRegionFactory;
|
||||
import org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge;
|
||||
import org.hibernate.engine.jdbc.batch.internal.BatchBuilder;
|
||||
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.hql.QueryTranslatorFactory;
|
||||
|
@ -115,6 +116,7 @@ public class SettingsFactory implements Serializable {
|
|||
if (batchSize>0) log.info("JDBC batch updates for versioned data: " + enabledDisabled(jdbcBatchVersionedData) );
|
||||
settings.setJdbcBatchVersionedData(jdbcBatchVersionedData);
|
||||
settings.setBatcherFactory( createBatcherFactory(properties, batchSize) );
|
||||
settings.setBatcherBuilder( createBatchBuilder(properties, batchSize) );
|
||||
|
||||
boolean useScrollableResultSets = ConfigurationHelper.getBoolean(Environment.USE_SCROLLABLE_RESULTSET, properties, meta.supportsScrollableResults());
|
||||
log.info("Scrollable result sets: " + enabledDisabled(useScrollableResultSets) );
|
||||
|
@ -350,20 +352,45 @@ public class SettingsFactory implements Serializable {
|
|||
|
||||
protected BatcherFactory createBatcherFactory(Properties properties, int batchSize) {
|
||||
String batcherClass = properties.getProperty(Environment.BATCH_STRATEGY);
|
||||
BatcherFactory batcherFactory = null;
|
||||
if (batcherClass==null) {
|
||||
return batchSize == 0
|
||||
batcherFactory = batchSize == 0
|
||||
? new NonBatchingBatcherFactory()
|
||||
: new BatchingBatcherFactory();
|
||||
: new BatchingBatcherFactory( );
|
||||
}
|
||||
else {
|
||||
log.info("Batcher factory: " + batcherClass);
|
||||
try {
|
||||
return (BatcherFactory) ReflectHelper.classForName(batcherClass).newInstance();
|
||||
batcherFactory = (BatcherFactory) ReflectHelper.classForName(batcherClass).newInstance();
|
||||
}
|
||||
catch (Exception cnfe) {
|
||||
throw new HibernateException("could not instantiate BatcherFactory: " + batcherClass, cnfe);
|
||||
}
|
||||
}
|
||||
batcherFactory.setJdbcBatchSize( batchSize );
|
||||
return batcherFactory;
|
||||
}
|
||||
|
||||
protected BatchBuilder createBatchBuilder(Properties properties, int batchSize) {
|
||||
//FIXME: uncomment to use BatchBuilder
|
||||
/*
|
||||
String batchBuilderClass = properties.getProperty(Environment.BATCH_STRATEGY);
|
||||
if (batchBuilderClass==null) {
|
||||
return batchSize > 0
|
||||
? new BatchBuilder( batchSize )
|
||||
: new BatchBuilder();
|
||||
}
|
||||
else {
|
||||
log.info("Batcher factory: " + batchBuilderClass);
|
||||
try {
|
||||
return (BatchBuilder) ReflectHelper.classForName(batchBuilderClass).newInstance();
|
||||
}
|
||||
catch (Exception cnfe) {
|
||||
throw new HibernateException("could not instantiate BatchBuilder: " + batchBuilderClass, cnfe);
|
||||
}
|
||||
}
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
protected TransactionFactory createTransactionFactory(Properties properties) {
|
||||
|
|
|
@ -76,7 +76,7 @@ public class ThreadLocalSessionContext implements CurrentSessionContext {
|
|||
private static final Class[] SESS_PROXY_INTERFACES = new Class[] {
|
||||
org.hibernate.classic.Session.class,
|
||||
org.hibernate.engine.SessionImplementor.class,
|
||||
org.hibernate.jdbc.JDBCContext.Context.class,
|
||||
org.hibernate.engine.jdbc.spi.JDBCContext.Context.class,
|
||||
org.hibernate.event.EventSource.class
|
||||
};
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.hibernate.engine.SessionImplementor;
|
|||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.sql.SimpleSelect;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.JDBCException;
|
||||
|
@ -79,7 +78,7 @@ public class PessimisticReadSelectLockingStrategy extends AbstractSelectLockingS
|
|||
final String sql = determineSql( timeout );
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
|
@ -106,7 +105,7 @@ public class PessimisticReadSelectLockingStrategy extends AbstractSelectLockingS
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import java.sql.SQLException;
|
|||
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.persister.entity.Lockable;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.sql.Update;
|
||||
|
@ -95,7 +94,7 @@ public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
|
|||
}
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
|
@ -115,7 +114,7 @@ public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
|
|||
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.hibernate.LockMode;
|
|||
import org.hibernate.PessimisticLockException;
|
||||
import org.hibernate.sql.SimpleSelect;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
|
@ -79,7 +78,7 @@ public class PessimisticWriteSelectLockingStrategy extends AbstractSelectLocking
|
|||
final String sql = determineSql( timeout );
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
|
@ -106,7 +105,7 @@ public class PessimisticWriteSelectLockingStrategy extends AbstractSelectLocking
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import java.sql.SQLException;
|
|||
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.persister.entity.Lockable;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.sql.Update;
|
||||
|
@ -95,7 +94,7 @@ public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
|
|||
}
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
|
@ -115,7 +114,7 @@ public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
|
|||
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.hibernate.JDBCException;
|
|||
import org.hibernate.LockMode;
|
||||
import org.hibernate.sql.SimpleSelect;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
|
@ -74,7 +73,7 @@ public class SelectLockingStrategy extends AbstractSelectLockingStrategy {
|
|||
final String sql = determineSql( timeout );
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
|
@ -101,7 +100,7 @@ public class SelectLockingStrategy extends AbstractSelectLockingStrategy {
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.hibernate.LockMode;
|
|||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.persister.entity.Lockable;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.sql.Update;
|
||||
|
@ -93,7 +92,7 @@ public class UpdateLockingStrategy implements LockingStrategy {
|
|||
// todo : should we additionally check the current isolation mode explicitly?
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
|
@ -113,7 +112,7 @@ public class UpdateLockingStrategy implements LockingStrategy {
|
|||
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -265,7 +265,7 @@ public class ActionQueue {
|
|||
execute( ( Executable ) list.get( i ) );
|
||||
}
|
||||
list.clear();
|
||||
session.getBatcher().executeBatch();
|
||||
session.getJDBCContext().getConnectionManager().executeBatch();
|
||||
}
|
||||
|
||||
public void execute(Executable executable) {
|
||||
|
|
|
@ -29,7 +29,6 @@ import java.sql.Connection;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.EntityMode;
|
||||
|
@ -40,13 +39,11 @@ import org.hibernate.Query;
|
|||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
|
||||
import org.hibernate.collection.PersistentCollection;
|
||||
import org.hibernate.event.EventListeners;
|
||||
import org.hibernate.impl.CriteriaImpl;
|
||||
import org.hibernate.jdbc.Batcher;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.loader.custom.CustomQuery;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.Type;
|
||||
|
@ -116,11 +113,7 @@ public interface SessionImplementor extends Serializable {
|
|||
* Get the creating <tt>SessionFactoryImplementor</tt>
|
||||
*/
|
||||
public SessionFactoryImplementor getFactory();
|
||||
/**
|
||||
* Get the prepared statement <tt>Batcher</tt> for this session
|
||||
*/
|
||||
public Batcher getBatcher();
|
||||
|
||||
|
||||
/**
|
||||
* Execute a <tt>find()</tt> query
|
||||
*/
|
||||
|
|
|
@ -22,23 +22,32 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.jdbc;
|
||||
package org.hibernate.engine.jdbc.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
|
||||
import org.hibernate.engine.jdbc.internal.proxy.ProxyBuilder;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionManager;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionObserver;
|
||||
import org.hibernate.engine.jdbc.spi.LogicalConnection;
|
||||
import org.hibernate.jdbc.Batcher;
|
||||
import org.hibernate.jdbc.Expectation;
|
||||
|
||||
/**
|
||||
* Encapsulates JDBC Connection management logic needed by Hibernate.
|
||||
|
@ -48,92 +57,71 @@ import org.hibernate.engine.jdbc.spi.ConnectionObserver;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ConnectionManager implements Serializable {
|
||||
public class ConnectionManagerImpl implements ConnectionManager {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger( ConnectionManager.class );
|
||||
private static final Logger log = LoggerFactory.getLogger( ConnectionManagerImpl.class );
|
||||
|
||||
// TODO: check if it's ok to change the method names in Callback
|
||||
public static interface Callback extends ConnectionObserver {
|
||||
public boolean isTransactionInProgress();
|
||||
}
|
||||
|
||||
// TODO: check if it's ok to change the method names in Callback
|
||||
|
||||
private transient SessionFactoryImplementor factory;
|
||||
private transient Connection proxiedConnection;
|
||||
private transient Interceptor interceptor;
|
||||
|
||||
private final Callback callback;
|
||||
|
||||
private transient LogicalConnectionImpl connection;
|
||||
|
||||
private transient Batcher batcher;
|
||||
private transient Interceptor interceptor;
|
||||
private transient LogicalConnectionImpl logicalConnection;
|
||||
|
||||
/**
|
||||
* Constructs a ConnectionManager.
|
||||
* <p/>
|
||||
* This is the form used internally.
|
||||
*
|
||||
* @param factory The SessionFactory.
|
||||
* @param callback An observer for internal state change.
|
||||
* @param releaseMode The mode by which to release JDBC connections.
|
||||
* @param connection An externally supplied connection.
|
||||
* @param suppliedConnection An externally supplied connection.
|
||||
*/
|
||||
public ConnectionManager(
|
||||
public ConnectionManagerImpl(
|
||||
SessionFactoryImplementor factory,
|
||||
Callback callback,
|
||||
ConnectionReleaseMode releaseMode,
|
||||
Connection connection,
|
||||
Connection suppliedConnection,
|
||||
Interceptor interceptor) {
|
||||
this.factory = factory;
|
||||
this.callback = callback;
|
||||
|
||||
this.interceptor = interceptor;
|
||||
this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );
|
||||
|
||||
setupConnection( connection, releaseMode );
|
||||
this( factory,
|
||||
callback,
|
||||
interceptor,
|
||||
new LogicalConnectionImpl(
|
||||
suppliedConnection,
|
||||
releaseMode,
|
||||
factory.getJdbcServices(),
|
||||
factory.getStatistics() != null ? factory.getStatisticsImplementor() : null,
|
||||
factory.getSettings().getBatcherFactory()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor used exclusively from custom serialization
|
||||
*/
|
||||
private ConnectionManager(
|
||||
private ConnectionManagerImpl(
|
||||
SessionFactoryImplementor factory,
|
||||
Callback callback,
|
||||
ConnectionReleaseMode releaseMode,
|
||||
Interceptor interceptor
|
||||
Interceptor interceptor,
|
||||
LogicalConnectionImpl logicalConnection
|
||||
) {
|
||||
this.factory = factory;
|
||||
this.callback = callback;
|
||||
|
||||
this.interceptor = interceptor;
|
||||
this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );
|
||||
setupConnection( logicalConnection );
|
||||
}
|
||||
|
||||
private void setupConnection(Connection suppliedConnection,
|
||||
ConnectionReleaseMode releaseMode
|
||||
) {
|
||||
connection =
|
||||
new LogicalConnectionImpl(
|
||||
suppliedConnection,
|
||||
releaseMode,
|
||||
factory.getJdbcServices()
|
||||
);
|
||||
connection.addObserver( callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* The session factory.
|
||||
*
|
||||
* @return the session factory.
|
||||
*/
|
||||
public SessionFactoryImplementor getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* The batcher managed by this ConnectionManager.
|
||||
*
|
||||
* @return The batcher.
|
||||
*/
|
||||
public Batcher getBatcher() {
|
||||
return batcher;
|
||||
private void setupConnection(LogicalConnectionImpl logicalConnection) {
|
||||
this.logicalConnection = logicalConnection;
|
||||
this.logicalConnection.addObserver( callback );
|
||||
proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,21 +136,24 @@ public class ConnectionManager implements Serializable {
|
|||
* @throws HibernateException Indicates a connection is currently not
|
||||
* available (we are currently manually disconnected).
|
||||
*/
|
||||
@Override
|
||||
public Connection getConnection() throws HibernateException {
|
||||
return connection.getConnection();
|
||||
return logicalConnection.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBorrowedConnection() {
|
||||
// used from testsuite
|
||||
return connection.hasBorrowedConnection();
|
||||
return logicalConnection.hasBorrowedConnection();
|
||||
}
|
||||
|
||||
public Connection borrowConnection() {
|
||||
return connection.borrowConnection();
|
||||
return logicalConnection.borrowConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseBorrowedConnection() {
|
||||
connection.releaseBorrowedConnection();
|
||||
logicalConnection.releaseBorrowedConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -174,10 +165,10 @@ public class ConnectionManager implements Serializable {
|
|||
* @throws SQLException Can be thrown by the Connection.isAutoCommit() check.
|
||||
*/
|
||||
public boolean isAutoCommit() throws SQLException {
|
||||
return connection == null ||
|
||||
! connection.isOpen() ||
|
||||
! connection.isPhysicallyConnected() ||
|
||||
connection.getConnection().getAutoCommit();
|
||||
return logicalConnection == null ||
|
||||
! logicalConnection.isOpen() ||
|
||||
! logicalConnection.isPhysicallyConnected() ||
|
||||
logicalConnection.getConnection().getAutoCommit();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -194,10 +185,10 @@ public class ConnectionManager implements Serializable {
|
|||
* @return True if the connections will be released after each statement; false otherwise.
|
||||
*/
|
||||
public boolean isAggressiveRelease() {
|
||||
if ( connection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
|
||||
if ( logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
|
||||
return true;
|
||||
}
|
||||
else if ( connection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION ) {
|
||||
else if ( logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION ) {
|
||||
boolean inAutoCommitState;
|
||||
try {
|
||||
inAutoCommitState = isAutoCommit() && ! callback.isTransactionInProgress();
|
||||
|
@ -223,7 +214,7 @@ public class ConnectionManager implements Serializable {
|
|||
* @return True if the connections will be released after each statement; false otherwise.
|
||||
*/
|
||||
private boolean isAggressiveReleaseNoTransactionCheck() {
|
||||
if ( connection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
|
||||
if ( logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
@ -235,7 +226,7 @@ public class ConnectionManager implements Serializable {
|
|||
// assume we are in an auto-commit state
|
||||
inAutoCommitState = true;
|
||||
}
|
||||
return connection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION && inAutoCommitState;
|
||||
return logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION && inAutoCommitState;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,18 +237,9 @@ public class ConnectionManager implements Serializable {
|
|||
*
|
||||
* @return True if logically connected; false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isCurrentlyConnected() {
|
||||
if ( connection != null ) {
|
||||
if ( connection.isUserSuppliedConnection() ) {
|
||||
return connection.isPhysicallyConnected();
|
||||
}
|
||||
else {
|
||||
return connection.isOpen();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return logicalConnection != null && logicalConnection.isLogicallyConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -265,14 +247,10 @@ public class ConnectionManager implements Serializable {
|
|||
* conditionally release the JDBC connection aggressively if
|
||||
* the configured release mode indicates.
|
||||
*/
|
||||
@Override
|
||||
public void afterStatement() {
|
||||
if ( isAggressiveRelease() ) {
|
||||
if ( batcher.hasOpenResources() ) {
|
||||
log.debug( "skipping aggresive-release due to open resources on batcher" );
|
||||
}
|
||||
else {
|
||||
connection.afterStatementExecution();
|
||||
}
|
||||
logicalConnection.afterStatementExecution();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,33 +260,32 @@ public class ConnectionManager implements Serializable {
|
|||
* indicates.
|
||||
*/
|
||||
public void afterTransaction() {
|
||||
if ( connection != null ) {
|
||||
if ( isAfterTransactionRelease() ) {
|
||||
connection.afterTransaction();
|
||||
}
|
||||
else if ( isAggressiveReleaseNoTransactionCheck() && batcher.hasOpenResources() ) {
|
||||
log.info( "forcing batcher resource cleanup on transaction completion; forgot to close ScrollableResults/Iterator?" );
|
||||
batcher.closeStatements();
|
||||
connection.afterTransaction();
|
||||
if ( logicalConnection != null ) {
|
||||
if ( isAfterTransactionRelease() || isAggressiveReleaseNoTransactionCheck() ) {
|
||||
logicalConnection.afterTransaction();
|
||||
}
|
||||
else if ( isOnCloseRelease() ) {
|
||||
// log a message about potential connection leaks
|
||||
log.debug( "transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!" );
|
||||
}
|
||||
}
|
||||
batcher.unsetTransactionTimeout();
|
||||
}
|
||||
|
||||
private boolean isAfterTransactionRelease() {
|
||||
return connection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
|
||||
return logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
|
||||
}
|
||||
|
||||
private boolean isOnCloseRelease() {
|
||||
return connection.getConnectionReleaseMode() == ConnectionReleaseMode.ON_CLOSE;
|
||||
return logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.ON_CLOSE;
|
||||
}
|
||||
|
||||
public boolean isLogicallyConnected() {
|
||||
return connection != null && connection.isOpen();
|
||||
return logicalConnection != null && logicalConnection.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransactionTimeout(int seconds) {
|
||||
logicalConnection.setTransactionTimeout( seconds );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -318,6 +295,7 @@ public class ConnectionManager implements Serializable {
|
|||
* @return The connection mantained here at time of close. Null if
|
||||
* there was no connection cached internally.
|
||||
*/
|
||||
@Override
|
||||
public Connection close() {
|
||||
return cleanup();
|
||||
}
|
||||
|
@ -329,12 +307,12 @@ public class ConnectionManager implements Serializable {
|
|||
* @return The connection mantained here at time of disconnect. Null if
|
||||
* there was no connection cached internally.
|
||||
*/
|
||||
@Override
|
||||
public Connection manualDisconnect() {
|
||||
if ( ! isLogicallyConnected() ) {
|
||||
throw new IllegalStateException( "cannot manually disconnect because not logically connected." );
|
||||
}
|
||||
batcher.closeStatements();
|
||||
return connection.manualDisconnect();
|
||||
return logicalConnection.manualDisconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -343,6 +321,7 @@ public class ConnectionManager implements Serializable {
|
|||
* <p/>
|
||||
* This form is used for ConnectionProvider-supplied connections.
|
||||
*/
|
||||
@Override
|
||||
public void manualReconnect() {
|
||||
manualReconnect( null );
|
||||
}
|
||||
|
@ -353,11 +332,12 @@ public class ConnectionManager implements Serializable {
|
|||
* <p/>
|
||||
* This form is used for user-supplied connections.
|
||||
*/
|
||||
@Override
|
||||
public void manualReconnect(Connection suppliedConnection) {
|
||||
if ( ! isLogicallyConnected() ) {
|
||||
throw new IllegalStateException( "cannot manually disconnect because not logically connected." );
|
||||
}
|
||||
connection.reconnect( suppliedConnection );
|
||||
logicalConnection.reconnect( suppliedConnection );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -371,21 +351,17 @@ public class ConnectionManager implements Serializable {
|
|||
* @throws HibernateException
|
||||
*/
|
||||
private Connection cleanup() throws HibernateException {
|
||||
if ( connection == null ) {
|
||||
if ( logicalConnection == null ) {
|
||||
log.trace( "connection already null in cleanup : no action");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
log.trace( "performing cleanup" );
|
||||
|
||||
if ( isLogicallyConnected() ) {
|
||||
batcher.closeStatements();
|
||||
}
|
||||
Connection c = connection.close();
|
||||
Connection c = logicalConnection.close();
|
||||
return c;
|
||||
}
|
||||
finally {
|
||||
connection = null;
|
||||
logicalConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,23 +370,192 @@ public class ConnectionManager implements Serializable {
|
|||
* to temporarily circumvent aggressive connection releasing until after
|
||||
* the flush cycle is complete {@link #flushEnding()}
|
||||
*/
|
||||
@Override
|
||||
public void flushBeginning() {
|
||||
log.trace( "registering flush begin" );
|
||||
connection.disableReleases();
|
||||
logicalConnection.disableReleases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to let us know that a flush is ending. We use this fact to
|
||||
* stop circumventing aggressive releasing connections.
|
||||
*/
|
||||
@Override
|
||||
public void flushEnding() {
|
||||
log.trace( "registering flush end" );
|
||||
connection.enableReleases();
|
||||
logicalConnection.enableReleases();
|
||||
afterStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for inserting / deleting / updating,
|
||||
* using JDBC3 getGeneratedKeys ({@link java.sql.Connection#prepareStatement(String, int)}).
|
||||
*/
|
||||
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
|
||||
throws SQLException, HibernateException {
|
||||
if ( autoGeneratedKeys == PreparedStatement.RETURN_GENERATED_KEYS ) {
|
||||
checkAutoGeneratedKeysSupportEnabled();
|
||||
}
|
||||
executeBatch();
|
||||
return proxiedConnection.prepareStatement(
|
||||
getSQL( sql ),
|
||||
autoGeneratedKeys
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for inserting / deleting / updating.
|
||||
* using JDBC3 getGeneratedKeys ({@link java.sql.Connection#prepareStatement(String, String[])}).
|
||||
*/
|
||||
public PreparedStatement prepareStatement(String sql, String[] columnNames)
|
||||
throws SQLException, HibernateException {
|
||||
checkAutoGeneratedKeysSupportEnabled();
|
||||
executeBatch();
|
||||
return proxiedConnection.prepareStatement( getSQL( sql ), columnNames );
|
||||
}
|
||||
|
||||
private void checkAutoGeneratedKeysSupportEnabled() {
|
||||
if ( ! factory.getSettings().isGetGeneratedKeysEnabled() ) {
|
||||
throw new AssertionFailure("getGeneratedKeys() support is not enabled");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for selecting. Does not
|
||||
* result in execution of the current batch.
|
||||
*/
|
||||
public PreparedStatement prepareSelectStatement(String sql)
|
||||
throws SQLException, HibernateException {
|
||||
return proxiedConnection.prepareStatement( getSQL( sql ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for inserting / deleting / updating.
|
||||
*/
|
||||
public PreparedStatement prepareStatement(String sql, boolean isCallable)
|
||||
throws SQLException, HibernateException {
|
||||
return isCallable ? prepareCallableStatement( sql ) : prepareStatement( sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a non-batchable callable statement to use for inserting / deleting / updating.
|
||||
*/
|
||||
public CallableStatement prepareCallableStatement(String sql) throws SQLException, HibernateException {
|
||||
executeBatch();
|
||||
log.trace("preparing callable statement");
|
||||
return CallableStatement.class.cast(
|
||||
proxiedConnection.prepareStatement( getSQL( sql ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a batchable prepared statement to use for inserting / deleting / updating
|
||||
* (might be called many times before a single call to <tt>executeBatch()</tt>).
|
||||
* After setting parameters, call <tt>addToBatch</tt> - do not execute the
|
||||
* statement explicitly.
|
||||
* @see org.hibernate.jdbc.Batcher#addToBatch
|
||||
*/
|
||||
public PreparedStatement prepareBatchStatement(String sql, boolean isCallable)
|
||||
throws SQLException, HibernateException {
|
||||
String batchUpdateSQL = getSQL( sql );
|
||||
PreparedStatement batchUpdate = getBatcher().getStatement( batchUpdateSQL );
|
||||
if ( batchUpdate == null ) {
|
||||
batchUpdate = prepareStatement( batchUpdateSQL, isCallable ); // calls executeBatch()
|
||||
getBatcher().setStatement( batchUpdateSQL, batchUpdate );
|
||||
}
|
||||
else {
|
||||
log.debug( "reusing prepared statement" );
|
||||
factory.getJdbcServices().getSqlStatementLogger().logStatement( batchUpdateSQL );
|
||||
}
|
||||
return batchUpdate;
|
||||
}
|
||||
|
||||
private Batcher getBatcher() {
|
||||
return logicalConnection.getBatcher();
|
||||
}
|
||||
|
||||
private PreparedStatement prepareStatement(String sql)
|
||||
throws SQLException, HibernateException {
|
||||
executeBatch();
|
||||
return proxiedConnection.prepareStatement( getSQL( sql ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a prepared statement for use in loading / querying. If not explicitly
|
||||
* released by <tt>closeQueryStatement()</tt>, it will be released when the
|
||||
* session is closed or disconnected.
|
||||
*/
|
||||
public PreparedStatement prepareQueryStatement(
|
||||
String sql,
|
||||
boolean isCallable) throws SQLException, HibernateException {
|
||||
sql = getSQL( sql );
|
||||
PreparedStatement result = (
|
||||
isCallable ?
|
||||
proxiedConnection.prepareCall(sql ) :
|
||||
proxiedConnection.prepareStatement( sql )
|
||||
);
|
||||
setStatementFetchSize( result );
|
||||
logicalConnection.getResourceRegistry().registerLastQuery( result );
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the current query statement
|
||||
*/
|
||||
public void cancelLastQuery() throws HibernateException {
|
||||
logicalConnection.getResourceRegistry().cancelLastQuery();
|
||||
}
|
||||
|
||||
public PreparedStatement prepareScrollableQueryStatement(
|
||||
String sql,
|
||||
ScrollMode scrollMode,
|
||||
boolean isCallable) throws SQLException, HibernateException {
|
||||
if ( ! factory.getSettings().isScrollableResultSetsEnabled() ) {
|
||||
throw new AssertionFailure("scrollable result sets are not enabled");
|
||||
}
|
||||
sql = getSQL( sql );
|
||||
PreparedStatement result = (
|
||||
isCallable ?
|
||||
proxiedConnection.prepareCall(
|
||||
sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY
|
||||
) :
|
||||
proxiedConnection.prepareStatement(
|
||||
sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY
|
||||
)
|
||||
);
|
||||
setStatementFetchSize( result );
|
||||
logicalConnection.getResourceRegistry().registerLastQuery( result );
|
||||
return result;
|
||||
}
|
||||
|
||||
public void abortBatch(SQLException sqle) {
|
||||
getBatcher().abortBatch( sqle );
|
||||
}
|
||||
|
||||
public void addToBatch(Expectation expectation ) throws SQLException, HibernateException {
|
||||
getBatcher().addToBatch( expectation );
|
||||
}
|
||||
|
||||
public void executeBatch() throws HibernateException {
|
||||
getBatcher().executeBatch();
|
||||
}
|
||||
|
||||
private String getSQL(String sql) {
|
||||
sql = interceptor.onPrepareStatement( sql );
|
||||
if ( sql==null || sql.length() == 0 ) {
|
||||
throw new AssertionFailure( "Interceptor.onPrepareStatement() returned null or empty string." );
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
private void setStatementFetchSize(PreparedStatement statement) throws SQLException {
|
||||
if ( factory.getSettings().getJdbcFetchSize() !=null ) {
|
||||
statement.setFetchSize( factory.getSettings().getJdbcFetchSize().intValue() );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReadyForSerialization() {
|
||||
return connection == null ? true : ! batcher.hasOpenResources() && connection.isReadyForSerialization();
|
||||
return logicalConnection == null ? true : logicalConnection.isReadyForSerialization();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,9 +568,6 @@ public class ConnectionManager implements Serializable {
|
|||
if ( !isReadyForSerialization() ) {
|
||||
throw new IllegalStateException( "Cannot serialize a ConnectionManager while connected" );
|
||||
}
|
||||
|
||||
oos.writeObject( factory );
|
||||
oos.writeObject( interceptor );
|
||||
oos.defaultWriteObject();
|
||||
}
|
||||
|
||||
|
@ -437,34 +579,30 @@ public class ConnectionManager implements Serializable {
|
|||
* @throws ClassNotFoundException Indicates resource class resolution.
|
||||
*/
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
factory = (SessionFactoryImplementor) ois.readObject();
|
||||
interceptor = (Interceptor) ois.readObject();
|
||||
ois.defaultReadObject();
|
||||
}
|
||||
|
||||
public void serialize(ObjectOutputStream oos) throws IOException {
|
||||
connection.serialize( oos );
|
||||
logicalConnection.serialize( oos );
|
||||
}
|
||||
|
||||
public static ConnectionManager deserialize(
|
||||
public static ConnectionManagerImpl deserialize(
|
||||
ObjectInputStream ois,
|
||||
SessionFactoryImplementor factory,
|
||||
Interceptor interceptor,
|
||||
ConnectionReleaseMode connectionReleaseMode,
|
||||
Callback callback) throws IOException {
|
||||
ConnectionManager connectionManager = new ConnectionManager(
|
||||
return new ConnectionManagerImpl(
|
||||
factory,
|
||||
callback,
|
||||
connectionReleaseMode,
|
||||
interceptor
|
||||
);
|
||||
connectionManager.connection =
|
||||
interceptor,
|
||||
LogicalConnectionImpl.deserialize(
|
||||
ois,
|
||||
factory.getJdbcServices( ),
|
||||
connectionReleaseMode
|
||||
);
|
||||
connectionManager.connection.addObserver( callback );
|
||||
return connectionManager;
|
||||
factory.getJdbcServices(),
|
||||
factory.getStatistics() != null ? factory.getStatisticsImplementor() : null,
|
||||
connectionReleaseMode,
|
||||
factory.getSettings().getBatcherFactory()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -22,9 +22,8 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.jdbc;
|
||||
package org.hibernate.engine.jdbc.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
@ -41,12 +40,12 @@ import org.hibernate.Interceptor;
|
|||
import org.hibernate.SessionException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionObserver;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionManager;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.transaction.synchronization.CallbackCoordinator;
|
||||
import org.hibernate.transaction.synchronization.HibernateSynchronizationImpl;
|
||||
import org.hibernate.util.JTAHelper;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.transaction.TransactionFactory;
|
||||
|
||||
/**
|
||||
* Acts as the mediary between "entity-mode related" sessions in terms of
|
||||
|
@ -54,7 +53,7 @@ import org.hibernate.transaction.TransactionFactory;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
||||
public class JDBCContextImpl implements ConnectionManagerImpl.Callback, JDBCContext {
|
||||
|
||||
// TODO : make this the factory for "entity mode related" sessions;
|
||||
// also means making this the target of transaction-synch and the
|
||||
|
@ -64,36 +63,24 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
// ConnectionManager is a "JDBCContext"? A "SessionContext" should
|
||||
// live in the impl package...
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger( JDBCContext.class );
|
||||
|
||||
public static interface Context extends TransactionFactory.Context {
|
||||
/**
|
||||
* We cannot rely upon this method being called! It is only
|
||||
* called if we are using Hibernate Transaction API.
|
||||
*/
|
||||
public void afterTransactionBegin(Transaction tx);
|
||||
public void beforeTransactionCompletion(Transaction tx);
|
||||
public void afterTransactionCompletion(boolean success, Transaction tx);
|
||||
public ConnectionReleaseMode getConnectionReleaseMode();
|
||||
public boolean isAutoCloseSessionEnabled();
|
||||
}
|
||||
private static final Logger log = LoggerFactory.getLogger( JDBCContextImpl.class );
|
||||
|
||||
private Context owner;
|
||||
private ConnectionManager connectionManager;
|
||||
private ConnectionManagerImpl connectionManager;
|
||||
private transient boolean isTransactionCallbackRegistered;
|
||||
private transient Transaction hibernateTransaction;
|
||||
|
||||
private CallbackCoordinator jtaSynchronizationCallbackCoordinator;
|
||||
|
||||
public JDBCContext(Context owner, Connection connection, Interceptor interceptor) {
|
||||
public JDBCContextImpl(Context owner, Connection connection, Interceptor interceptor) {
|
||||
this.owner = owner;
|
||||
this.connectionManager = new ConnectionManager(
|
||||
this.connectionManager = new ConnectionManagerImpl(
|
||||
owner.getFactory(),
|
||||
this,
|
||||
this,
|
||||
owner.getConnectionReleaseMode(),
|
||||
connection,
|
||||
interceptor
|
||||
);
|
||||
);
|
||||
|
||||
final boolean registerSynchronization = owner.isAutoCloseSessionEnabled()
|
||||
|| owner.isFlushBeforeCompletionEnabled()
|
||||
|
@ -107,31 +94,34 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
* Private constructor used exclusively for custom serialization...
|
||||
*
|
||||
*/
|
||||
private JDBCContext() {
|
||||
private JDBCContextImpl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallbackCoordinator getJtaSynchronizationCallbackCoordinator() {
|
||||
return jtaSynchronizationCallbackCoordinator;
|
||||
}
|
||||
|
||||
public CallbackCoordinator getJtaSynchronizationCallbackCoordinator(javax.transaction.Transaction jtaTransaction) {
|
||||
private CallbackCoordinator getJtaSynchronizationCallbackCoordinator(javax.transaction.Transaction jtaTransaction) {
|
||||
jtaSynchronizationCallbackCoordinator = new CallbackCoordinator( owner, this, jtaTransaction, hibernateTransaction );
|
||||
return jtaSynchronizationCallbackCoordinator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUpJtaSynchronizationCallbackCoordinator() {
|
||||
jtaSynchronizationCallbackCoordinator = null;
|
||||
}
|
||||
|
||||
|
||||
// ConnectionManager.Callback implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public void physicalConnectionObtained(Connection connection) {
|
||||
if ( owner.getFactory().getStatistics().isStatisticsEnabled() ) {
|
||||
owner.getFactory().getStatisticsImplementor().connect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void physicalConnectionReleased() {
|
||||
if ( !isTransactionCallbackRegistered ) {
|
||||
afterTransactionCompletion( false, null );
|
||||
|
@ -139,14 +129,17 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logicalConnectionClosed() {
|
||||
// TODO: anything need to be done?
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryImplementor getFactory() {
|
||||
return owner.getFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionManager getConnectionManager() {
|
||||
return connectionManager;
|
||||
}
|
||||
|
@ -155,6 +148,7 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
return connectionManager.borrowConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection connection() throws HibernateException {
|
||||
if ( owner.isClosed() ) {
|
||||
throw new SessionException( "Session is closed" );
|
||||
|
@ -163,6 +157,7 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
return connectionManager.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerCallbackIfNecessary() {
|
||||
if ( isTransactionCallbackRegistered ) {
|
||||
return false;
|
||||
|
@ -174,6 +169,7 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerSynchronizationIfPossible() {
|
||||
if ( isTransactionCallbackRegistered ) {
|
||||
// we already have a callback registered; either a local
|
||||
|
@ -234,11 +230,13 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTransactionInProgress() {
|
||||
return owner.getFactory().getSettings().getTransactionFactory()
|
||||
.isTransactionInProgress( this, owner, hibernateTransaction );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction getTransaction() throws HibernateException {
|
||||
if (hibernateTransaction==null) {
|
||||
hibernateTransaction = owner.getFactory().getSettings()
|
||||
|
@ -248,6 +246,7 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
return hibernateTransaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTransactionCompletion(Transaction tx) {
|
||||
log.trace( "before transaction completion" );
|
||||
owner.beforeTransactionCompletion(tx);
|
||||
|
@ -257,11 +256,13 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
* We cannot rely upon this method being called! It is only
|
||||
* called if we are using Hibernate Transaction API.
|
||||
*/
|
||||
@Override
|
||||
public void afterTransactionBegin(Transaction tx) {
|
||||
log.trace( "after transaction begin" );
|
||||
owner.afterTransactionBegin(tx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(boolean success, Transaction tx) {
|
||||
log.trace( "after transaction completion" );
|
||||
|
||||
|
@ -280,6 +281,7 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
* Called after executing a query outside the scope of
|
||||
* a Hibernate or JTA transaction
|
||||
*/
|
||||
@Override
|
||||
public void afterNontransactionalQuery(boolean success) {
|
||||
log.trace( "after autocommit" );
|
||||
try {
|
||||
|
@ -306,6 +308,10 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
|
||||
// serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
public boolean isReadyForSerialization() {
|
||||
return connectionManager.isReadyForSerialization();
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
// isTransactionCallbackRegistered denotes whether any Hibernate
|
||||
// Transaction has registered as a callback against this
|
||||
|
@ -345,16 +351,16 @@ public class JDBCContext implements Serializable, ConnectionManager.Callback {
|
|||
* @param ois The stream from which to read the entry.
|
||||
* @throws IOException
|
||||
*/
|
||||
public static JDBCContext deserialize(
|
||||
public static JDBCContextImpl deserialize(
|
||||
ObjectInputStream ois,
|
||||
Context context,
|
||||
Interceptor interceptor) throws IOException {
|
||||
JDBCContext jdbcContext = new JDBCContext();
|
||||
Interceptor interceptor) throws IOException, ClassNotFoundException {
|
||||
JDBCContextImpl jdbcContext = new JDBCContextImpl();
|
||||
jdbcContext.owner = context;
|
||||
jdbcContext.connectionManager = ConnectionManager.deserialize(
|
||||
jdbcContext.connectionManager = ConnectionManagerImpl.deserialize(
|
||||
ois,
|
||||
context.getFactory(),
|
||||
interceptor,
|
||||
interceptor,
|
||||
context.getConnectionReleaseMode(),
|
||||
jdbcContext
|
||||
);
|
|
@ -23,11 +23,14 @@
|
|||
*/
|
||||
package org.hibernate.engine.jdbc.internal;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -35,9 +38,12 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcWrapper;
|
||||
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcResourceRegistry;
|
||||
import org.hibernate.engine.jdbc.spi.InvalidatableWrapper;
|
||||
import org.hibernate.jdbc.Batcher;
|
||||
import org.hibernate.jdbc.BatcherFactory;
|
||||
|
||||
/**
|
||||
* Standard implementation of the {@link org.hibernate.engine.jdbc.spi.JdbcResourceRegistry} contract
|
||||
|
@ -50,9 +56,13 @@ public class JdbcResourceRegistryImpl implements JdbcResourceRegistry {
|
|||
private final HashMap<Statement,Set<ResultSet>> xref = new HashMap<Statement,Set<ResultSet>>();
|
||||
private final Set<ResultSet> unassociatedResultSets = new HashSet<ResultSet>();
|
||||
private final SQLExceptionHelper exceptionHelper;
|
||||
private final Batcher batcher;
|
||||
|
||||
public JdbcResourceRegistryImpl(SQLExceptionHelper exceptionHelper) {
|
||||
private Statement lastQuery;
|
||||
|
||||
public JdbcResourceRegistryImpl(SQLExceptionHelper exceptionHelper, BatcherFactory batcherFactory) {
|
||||
this.exceptionHelper = exceptionHelper;
|
||||
this.batcher = batcherFactory.createBatcher( exceptionHelper );
|
||||
}
|
||||
|
||||
public void register(Statement statement) {
|
||||
|
@ -63,6 +73,38 @@ public class JdbcResourceRegistryImpl implements JdbcResourceRegistry {
|
|||
xref.put( statement, null );
|
||||
}
|
||||
|
||||
public Batcher getBatcher() {
|
||||
return batcher;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public void registerLastQuery(Statement statement) {
|
||||
log.trace( "registering last query statement [{}]", statement );
|
||||
if ( statement instanceof JdbcWrapper ) {
|
||||
JdbcWrapper<Statement> wrapper = ( JdbcWrapper<Statement> ) statement;
|
||||
registerLastQuery( wrapper.getWrappedObject() );
|
||||
return;
|
||||
}
|
||||
lastQuery = statement;
|
||||
}
|
||||
|
||||
public void cancelLastQuery() {
|
||||
try {
|
||||
if (lastQuery != null) {
|
||||
lastQuery.cancel();
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
throw exceptionHelper.convert(
|
||||
sqle,
|
||||
"Cannot cancel query"
|
||||
);
|
||||
}
|
||||
finally {
|
||||
lastQuery = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void release(Statement statement) {
|
||||
log.trace( "releasing statement [" + statement + "]" );
|
||||
Set<ResultSet> resultSets = xref.get( statement );
|
||||
|
@ -132,7 +174,7 @@ public class JdbcResourceRegistryImpl implements JdbcResourceRegistry {
|
|||
}
|
||||
|
||||
public boolean hasRegisteredResources() {
|
||||
return ! ( xref.isEmpty() && unassociatedResultSets.isEmpty() );
|
||||
return ! xref.isEmpty() || ! unassociatedResultSets.isEmpty();
|
||||
}
|
||||
|
||||
public void releaseResources() {
|
||||
|
@ -141,6 +183,7 @@ public class JdbcResourceRegistryImpl implements JdbcResourceRegistry {
|
|||
}
|
||||
|
||||
private void cleanup() {
|
||||
batcher.closeStatements();
|
||||
for ( Map.Entry<Statement,Set<ResultSet>> entry : xref.entrySet() ) {
|
||||
if ( entry.getValue() != null ) {
|
||||
for ( ResultSet resultSet : entry.getValue() ) {
|
||||
|
@ -156,6 +199,59 @@ public class JdbcResourceRegistryImpl implements JdbcResourceRegistry {
|
|||
close( resultSet );
|
||||
}
|
||||
unassociatedResultSets.clear();
|
||||
|
||||
// TODO: can ConcurrentModificationException still happen???
|
||||
// Following is from old AbstractBatcher...
|
||||
/*
|
||||
Iterator iter = resultSetsToClose.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
try {
|
||||
logCloseResults();
|
||||
( ( ResultSet ) iter.next() ).close();
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
// no big deal
|
||||
log.warn( "Could not close a JDBC result set", e );
|
||||
}
|
||||
catch ( ConcurrentModificationException e ) {
|
||||
// this has been shown to happen occasionally in rare cases
|
||||
// when using a transaction manager + transaction-timeout
|
||||
// where the timeout calls back through Hibernate's
|
||||
// registered transaction synchronization on a separate
|
||||
// "reaping" thread. In cases where that reaping thread
|
||||
// executes through this block at the same time the main
|
||||
// application thread does we can get into situations where
|
||||
// these CMEs occur. And though it is not "allowed" per-se,
|
||||
// the end result without handling it specifically is infinite
|
||||
// looping. So here, we simply break the loop
|
||||
log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
|
||||
break;
|
||||
}
|
||||
catch ( Throwable e ) {
|
||||
// sybase driver (jConnect) throwing NPE here in certain
|
||||
// cases, but we'll just handle the general "unexpected" case
|
||||
log.warn( "Could not close a JDBC result set", e );
|
||||
}
|
||||
}
|
||||
resultSetsToClose.clear();
|
||||
|
||||
iter = statementsToClose.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
try {
|
||||
closeQueryStatement( ( PreparedStatement ) iter.next() );
|
||||
}
|
||||
catch ( ConcurrentModificationException e ) {
|
||||
// see explanation above...
|
||||
log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
|
||||
break;
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
// no big deal
|
||||
log.warn( "Could not close a JDBC statement", e );
|
||||
}
|
||||
}
|
||||
statementsToClose.clear();
|
||||
*/
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
@ -191,6 +287,9 @@ public class JdbcResourceRegistryImpl implements JdbcResourceRegistry {
|
|||
return; // EARLY EXIT!!!
|
||||
}
|
||||
statement.close();
|
||||
if ( lastQuery == statement ) {
|
||||
lastQuery = null;
|
||||
}
|
||||
}
|
||||
catch( SQLException sqle ) {
|
||||
log.debug( "Unable to release statement [{}]", sqle.getMessage() );
|
||||
|
|
|
@ -41,7 +41,10 @@ import org.hibernate.engine.jdbc.spi.JdbcResourceRegistry;
|
|||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionObserver;
|
||||
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
|
||||
import org.hibernate.jdbc.Batcher;
|
||||
import org.hibernate.jdbc.BatcherFactory;
|
||||
import org.hibernate.jdbc.BorrowedConnectionProxy;
|
||||
import org.hibernate.stat.StatisticsImplementor;
|
||||
|
||||
/**
|
||||
* LogicalConnectionImpl implementation
|
||||
|
@ -51,50 +54,71 @@ import org.hibernate.jdbc.BorrowedConnectionProxy;
|
|||
public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
||||
private static final Logger log = LoggerFactory.getLogger( LogicalConnectionImpl.class );
|
||||
|
||||
private transient Connection physicalConnection;
|
||||
private transient Connection borrowedConnection;
|
||||
private Connection physicalConnection;
|
||||
private Connection borrowedConnection;
|
||||
|
||||
private final ConnectionReleaseMode connectionReleaseMode;
|
||||
private final JdbcServices jdbcServices;
|
||||
private final JdbcResourceRegistry jdbcResourceRegistry;
|
||||
private final StatisticsImplementor statisticsImplementor;
|
||||
private final JdbcResourceRegistryImpl jdbcResourceRegistry;
|
||||
private final List<ConnectionObserver> observers = new ArrayList<ConnectionObserver>();
|
||||
|
||||
private boolean releasesEnabled = true;
|
||||
private long transactionTimeout = -1;
|
||||
boolean isTransactionTimeoutSet;
|
||||
|
||||
private final boolean isUserSuppliedConnection;
|
||||
|
||||
private boolean isClosed;
|
||||
|
||||
public LogicalConnectionImpl(
|
||||
Connection userSuppliedConnection,
|
||||
ConnectionReleaseMode connectionReleaseMode,
|
||||
JdbcServices jdbcServices) {
|
||||
public LogicalConnectionImpl(Connection userSuppliedConnection,
|
||||
ConnectionReleaseMode connectionReleaseMode,
|
||||
JdbcServices jdbcServices,
|
||||
StatisticsImplementor statisticsImplementor,
|
||||
BatcherFactory batcherFactory
|
||||
) {
|
||||
this.jdbcServices = jdbcServices;
|
||||
this.statisticsImplementor = statisticsImplementor;
|
||||
this.physicalConnection = userSuppliedConnection;
|
||||
this.connectionReleaseMode =
|
||||
determineConnectionReleaseMode(
|
||||
userSuppliedConnection != null, connectionReleaseMode, jdbcServices
|
||||
jdbcServices, userSuppliedConnection != null, connectionReleaseMode
|
||||
);
|
||||
this.jdbcResourceRegistry =
|
||||
new JdbcResourceRegistryImpl(
|
||||
getJdbcServices().getSqlExceptionHelper(),
|
||||
batcherFactory
|
||||
);
|
||||
this.jdbcServices = jdbcServices;
|
||||
this.jdbcResourceRegistry = new JdbcResourceRegistryImpl( jdbcServices.getSqlExceptionHelper() );
|
||||
|
||||
this.isUserSuppliedConnection = ( userSuppliedConnection != null );
|
||||
this.isClosed = false;
|
||||
}
|
||||
|
||||
public LogicalConnectionImpl(
|
||||
ConnectionReleaseMode connectionReleaseMode,
|
||||
JdbcServices jdbcServices,
|
||||
boolean isUserSuppliedConnection,
|
||||
boolean isClosed) {
|
||||
// used for deserialization
|
||||
private LogicalConnectionImpl(ConnectionReleaseMode connectionReleaseMode,
|
||||
JdbcServices jdbcServices,
|
||||
StatisticsImplementor statisticsImplementor,
|
||||
BatcherFactory batcherFactory,
|
||||
boolean isUserSuppliedConnection,
|
||||
boolean isClosed) {
|
||||
this.connectionReleaseMode = determineConnectionReleaseMode(
|
||||
isUserSuppliedConnection, connectionReleaseMode, jdbcServices
|
||||
jdbcServices, isUserSuppliedConnection, connectionReleaseMode
|
||||
);
|
||||
this.jdbcServices = jdbcServices;
|
||||
this.jdbcResourceRegistry = new JdbcResourceRegistryImpl( jdbcServices.getSqlExceptionHelper() );
|
||||
this.statisticsImplementor = statisticsImplementor;
|
||||
this.jdbcResourceRegistry =
|
||||
new JdbcResourceRegistryImpl(
|
||||
getJdbcServices().getSqlExceptionHelper(),
|
||||
batcherFactory
|
||||
);
|
||||
|
||||
this.isUserSuppliedConnection = isUserSuppliedConnection;
|
||||
this.isClosed = isClosed;
|
||||
}
|
||||
|
||||
private static ConnectionReleaseMode determineConnectionReleaseMode(boolean isUserSuppliedConnection,
|
||||
ConnectionReleaseMode connectionReleaseMode,
|
||||
JdbcServices jdbcServices) {
|
||||
private static ConnectionReleaseMode determineConnectionReleaseMode(JdbcServices jdbcServices,
|
||||
boolean isUserSuppliedConnection,
|
||||
ConnectionReleaseMode connectionReleaseMode) {
|
||||
if ( isUserSuppliedConnection ) {
|
||||
return ConnectionReleaseMode.ON_CLOSE;
|
||||
}
|
||||
|
@ -108,6 +132,40 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transaction timeout to <tt>seconds</tt> later
|
||||
* than the current system time.
|
||||
*/
|
||||
public void setTransactionTimeout(int seconds) {
|
||||
isTransactionTimeoutSet = true;
|
||||
transactionTimeout = System.currentTimeMillis() / 1000 + seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the transaction timeout, called after the end of a
|
||||
* transaction.
|
||||
*/
|
||||
private void unsetTransactionTimeout() {
|
||||
isTransactionTimeoutSet = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean isTransactionTimeoutSet() {
|
||||
return isTransactionTimeoutSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public long getTransactionTimeout() throws HibernateException {
|
||||
if ( isTransactionTimeoutSet ) {
|
||||
throw new HibernateException( "transaction timeout has not been set." );
|
||||
}
|
||||
return transactionTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -115,6 +173,13 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
|||
return jdbcServices;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public StatisticsImplementor getStatisticsImplementor() {
|
||||
return statisticsImplementor;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -136,6 +201,15 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
|||
return !isClosed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean isLogicallyConnected() {
|
||||
return isUserSuppliedConnection ?
|
||||
isPhysicallyConnected() :
|
||||
isOpen();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -192,8 +266,8 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
|||
return connectionReleaseMode;
|
||||
}
|
||||
|
||||
public boolean isUserSuppliedConnection() {
|
||||
return isUserSuppliedConnection;
|
||||
public Batcher getBatcher() {
|
||||
return jdbcResourceRegistry.getBatcher();
|
||||
}
|
||||
|
||||
public boolean hasBorrowedConnection() {
|
||||
|
@ -204,7 +278,7 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
|||
if ( isClosed ) {
|
||||
throw new HibernateException( "connection has been closed" );
|
||||
}
|
||||
if ( isUserSuppliedConnection() ) {
|
||||
if ( isUserSuppliedConnection ) {
|
||||
return physicalConnection;
|
||||
}
|
||||
else {
|
||||
|
@ -237,6 +311,9 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
|||
log.debug( "skipping aggressive release due to registered resources" );
|
||||
return;
|
||||
}
|
||||
else if ( borrowedConnection != null ) {
|
||||
log.debug( "skipping aggresive-release due to borrowed connection" );
|
||||
}
|
||||
releaseConnection();
|
||||
}
|
||||
}
|
||||
|
@ -250,6 +327,7 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
|||
}
|
||||
aggressiveRelease();
|
||||
}
|
||||
unsetTransactionTimeout();
|
||||
}
|
||||
|
||||
public void disableReleases() {
|
||||
|
@ -342,6 +420,7 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
|||
throw new IllegalStateException( "cannot manually disconnect because logical connection is already closed" );
|
||||
}
|
||||
Connection c = physicalConnection;
|
||||
jdbcResourceRegistry.releaseResources();
|
||||
releaseConnection();
|
||||
return c;
|
||||
}
|
||||
|
@ -380,7 +459,7 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
|||
}
|
||||
|
||||
public boolean isReadyForSerialization() {
|
||||
return isUserSuppliedConnection() ?
|
||||
return isUserSuppliedConnection ?
|
||||
! isPhysicallyConnected() :
|
||||
! getResourceRegistry().hasRegisteredResources()
|
||||
;
|
||||
|
@ -391,13 +470,17 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
|
|||
oos.writeBoolean( isClosed );
|
||||
}
|
||||
|
||||
public static LogicalConnectionImpl deserialize(
|
||||
ObjectInputStream ois,
|
||||
JdbcServices jdbcServices,
|
||||
ConnectionReleaseMode connectionReleaseMode ) throws IOException {
|
||||
public static LogicalConnectionImpl deserialize(ObjectInputStream ois,
|
||||
JdbcServices jdbcServices,
|
||||
StatisticsImplementor statisticsImplementor,
|
||||
ConnectionReleaseMode connectionReleaseMode,
|
||||
BatcherFactory batcherFactory
|
||||
) throws IOException {
|
||||
return new LogicalConnectionImpl(
|
||||
connectionReleaseMode,
|
||||
jdbcServices,
|
||||
statisticsImplementor,
|
||||
batcherFactory,
|
||||
ois.readBoolean(),
|
||||
ois.readBoolean()
|
||||
);
|
||||
|
|
|
@ -140,7 +140,7 @@ public abstract class AbstractStatementProxyHandler extends AbstractProxyHandler
|
|||
|
||||
final ResultSet wrapper;
|
||||
if ( "getGeneratedKeys".equals( method.getName() ) ) {
|
||||
wrapper = ProxyBuilder.buildImplicitResultSet( ( ResultSet ) result, connectionProxyHandler, connectionProxy );
|
||||
wrapper = ProxyBuilder.buildImplicitResultSet( ( ResultSet ) result, connectionProxyHandler, connectionProxy, ( Statement ) proxy );
|
||||
}
|
||||
else {
|
||||
wrapper = ProxyBuilder.buildResultSet( ( ResultSet ) result, this, ( Statement ) proxy );
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.internal.proxy;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Invocation handler for {@link java.sql.CallableStatement} proxies
|
||||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class CallableStatementProxyHandler extends PreparedStatementProxyHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger( CallableStatementProxyHandler.class );
|
||||
|
||||
protected CallableStatementProxyHandler(
|
||||
String sql,
|
||||
Statement statement,
|
||||
ConnectionProxyHandler connectionProxyHandler,
|
||||
Connection connectionProxy) {
|
||||
super( sql, statement, connectionProxyHandler, connectionProxy );
|
||||
}
|
||||
|
||||
protected Object continueInvocation(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if ( ! "executeQuery".equals( method.getName() ) ) {
|
||||
return super.continueInvocation( proxy, method, args ); // EARLY RETURN!
|
||||
}
|
||||
errorIfInvalid();
|
||||
return executeQuery();
|
||||
}
|
||||
|
||||
private Object executeQuery() throws SQLException {
|
||||
return getConnectionProxy().getJdbcServices().getDialect().getResultSet( ( CallableStatement ) this );
|
||||
}
|
||||
}
|
|
@ -36,10 +36,12 @@ import java.sql.Statement;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcResourceRegistry;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionObserver;
|
||||
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
|
||||
import org.hibernate.stat.StatisticsImplementor;
|
||||
|
||||
/**
|
||||
* The {@link InvocationHandler} for intercepting messages to {@link java.sql.Connection} proxies.
|
||||
|
@ -127,7 +129,7 @@ public class ConnectionProxyHandler extends AbstractProxyHandler implements Invo
|
|||
|
||||
try {
|
||||
Object result = method.invoke( extractPhysicalConnection(), args );
|
||||
result = wrapIfNecessary( result, proxy, method, args );
|
||||
result = postProcess( result, proxy, method, args );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -143,7 +145,7 @@ public class ConnectionProxyHandler extends AbstractProxyHandler implements Invo
|
|||
}
|
||||
}
|
||||
|
||||
private Object wrapIfNecessary(Object result, Object proxy, Method method, Object[] args) {
|
||||
private Object postProcess(Object result, Object proxy, Method method, Object[] args) throws SQLException {
|
||||
String methodName = method.getName();
|
||||
Object wrapped = result;
|
||||
if ( "createStatement".equals( methodName ) ) {
|
||||
|
@ -152,7 +154,7 @@ public class ConnectionProxyHandler extends AbstractProxyHandler implements Invo
|
|||
this,
|
||||
( Connection ) proxy
|
||||
);
|
||||
getResourceRegistry().register( ( Statement ) wrapped );
|
||||
postProcessStatement( ( Statement ) wrapped );
|
||||
}
|
||||
else if ( "prepareStatement".equals( methodName ) ) {
|
||||
wrapped = ProxyBuilder.buildPreparedStatement(
|
||||
|
@ -161,7 +163,7 @@ public class ConnectionProxyHandler extends AbstractProxyHandler implements Invo
|
|||
this,
|
||||
( Connection ) proxy
|
||||
);
|
||||
getResourceRegistry().register( ( Statement ) wrapped );
|
||||
postProcessPreparedStatement( ( Statement ) wrapped );
|
||||
}
|
||||
else if ( "prepareCall".equals( methodName ) ) {
|
||||
wrapped = ProxyBuilder.buildCallableStatement(
|
||||
|
@ -170,7 +172,7 @@ public class ConnectionProxyHandler extends AbstractProxyHandler implements Invo
|
|||
this,
|
||||
( Connection ) proxy
|
||||
);
|
||||
getResourceRegistry().register( ( Statement ) wrapped );
|
||||
postProcessPreparedStatement( ( Statement ) wrapped );
|
||||
}
|
||||
else if ( "getMetaData".equals( methodName ) ) {
|
||||
wrapped = ProxyBuilder.buildDatabaseMetaData( (DatabaseMetaData) result, this, ( Connection ) proxy );
|
||||
|
@ -178,6 +180,18 @@ public class ConnectionProxyHandler extends AbstractProxyHandler implements Invo
|
|||
return wrapped;
|
||||
}
|
||||
|
||||
private void postProcessStatement(Statement statement) throws SQLException {
|
||||
setTimeout( statement );
|
||||
getResourceRegistry().register( statement );
|
||||
}
|
||||
|
||||
private void postProcessPreparedStatement(Statement statement) throws SQLException {
|
||||
if ( getStatisticsImplementorOrNull() != null ) {
|
||||
getStatisticsImplementorOrNull().prepareStatement();
|
||||
}
|
||||
postProcessStatement( statement );
|
||||
}
|
||||
|
||||
private void explicitClose() {
|
||||
if ( isValid() ) {
|
||||
invalidateHandle();
|
||||
|
@ -210,4 +224,23 @@ public class ConnectionProxyHandler extends AbstractProxyHandler implements Invo
|
|||
log.info( "*** logical connection closed ***" );
|
||||
invalidateHandle();
|
||||
}
|
||||
|
||||
/* package-protected */
|
||||
StatisticsImplementor getStatisticsImplementorOrNull() {
|
||||
return getLogicalConnection().getStatisticsImplementor();
|
||||
}
|
||||
|
||||
private void setTimeout(Statement result) throws SQLException {
|
||||
if ( logicalConnection.isTransactionTimeoutSet() ) {
|
||||
int timeout = (int) ( logicalConnection.getTransactionTimeout() - ( System.currentTimeMillis() / 1000 ) );
|
||||
if (timeout<=0) {
|
||||
throw new TransactionException("transaction timeout expired");
|
||||
}
|
||||
else {
|
||||
result.setQueryTimeout(timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -47,6 +47,13 @@ public class ImplicitResultSetProxyHandler extends AbstractResultSetProxyHandler
|
|||
this.connectionProxy = connectionProxy;
|
||||
}
|
||||
|
||||
public ImplicitResultSetProxyHandler(ResultSet resultSet, ConnectionProxyHandler connectionProxyHandler, Connection connectionProxy, Statement sourceStatement) {
|
||||
super( resultSet );
|
||||
this.connectionProxyHandler = connectionProxyHandler;
|
||||
this.connectionProxy = connectionProxy;
|
||||
this.sourceStatement = sourceStatement;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JdbcServices getJdbcServices() {
|
||||
return connectionProxyHandler.getJdbcServices();
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcWrapper;
|
||||
import org.hibernate.engine.jdbc.spi.InvalidatableWrapper;
|
||||
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
|
||||
|
@ -139,7 +140,7 @@ public class ProxyBuilder {
|
|||
CallableStatement statement,
|
||||
ConnectionProxyHandler connectionProxyHandler,
|
||||
Connection connectionProxy) {
|
||||
PreparedStatementProxyHandler proxyHandler = new PreparedStatementProxyHandler(
|
||||
CallableStatementProxyHandler proxyHandler = new CallableStatementProxyHandler(
|
||||
sql,
|
||||
statement,
|
||||
connectionProxyHandler,
|
||||
|
@ -186,6 +187,19 @@ public class ProxyBuilder {
|
|||
);
|
||||
}
|
||||
|
||||
public static ResultSet buildImplicitResultSet(
|
||||
ResultSet resultSet,
|
||||
ConnectionProxyHandler connectionProxyHandler,
|
||||
Connection connectionProxy,
|
||||
Statement sourceStatement) {
|
||||
ImplicitResultSetProxyHandler proxyHandler = new ImplicitResultSetProxyHandler( resultSet, connectionProxyHandler, connectionProxy, sourceStatement );
|
||||
return ( ResultSet ) Proxy.newProxyInstance(
|
||||
JdbcWrapper.class.getClassLoader(),
|
||||
RESULTSET_PROXY_INTERFACES,
|
||||
proxyHandler
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// DatabaseMetaData ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.jdbc.Expectation;
|
||||
|
||||
/**
|
||||
* Encapsulates JDBC Connection management SPI.
|
||||
* <p/>
|
||||
* The lifecycle is intended to span a logical series of interactions with the
|
||||
* database. Internally, this means the the lifecycle of the Session.
|
||||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public interface ConnectionManager extends Serializable {
|
||||
|
||||
/**
|
||||
* Retrieves the connection currently managed by this ConnectionManager.
|
||||
* <p/>
|
||||
* Note, that we may need to obtain a connection to return here if a
|
||||
* connection has either not yet been obtained (non-UserSuppliedConnectionProvider)
|
||||
* or has previously been aggressively released (if supported in this environment).
|
||||
*
|
||||
* @return The current Connection.
|
||||
*
|
||||
* @throws HibernateException Indicates a connection is currently not
|
||||
* available (we are currently manually disconnected).
|
||||
*/
|
||||
Connection getConnection() throws HibernateException;
|
||||
|
||||
// TODO: should this be removd from the SPI?
|
||||
boolean hasBorrowedConnection();
|
||||
|
||||
// TODO: should this be removd from the SPI?
|
||||
void releaseBorrowedConnection();
|
||||
|
||||
/**
|
||||
* Is this ConnectionManager instance "logically" connected. Meaning
|
||||
* do we either have a cached connection available or do we have the
|
||||
* ability to obtain a connection on demand.
|
||||
*
|
||||
* @return True if logically connected; false otherwise.
|
||||
*/
|
||||
boolean isCurrentlyConnected();
|
||||
|
||||
/**
|
||||
* To be called after execution of each JDBC statement. Used to
|
||||
* conditionally release the JDBC connection aggressively if
|
||||
* the configured release mode indicates.
|
||||
*/
|
||||
void afterStatement();
|
||||
|
||||
void setTransactionTimeout(int seconds);
|
||||
|
||||
/**
|
||||
* To be called after Session completion. Used to release the JDBC
|
||||
* connection.
|
||||
*
|
||||
* @return The connection mantained here at time of close. Null if
|
||||
* there was no connection cached internally.
|
||||
*/
|
||||
Connection close();
|
||||
|
||||
/**
|
||||
* Manually disconnect the underlying JDBC Connection. The assumption here
|
||||
* is that the manager will be reconnected at a later point in time.
|
||||
*
|
||||
* @return The connection mantained here at time of disconnect. Null if
|
||||
* there was no connection cached internally.
|
||||
*/
|
||||
Connection manualDisconnect();
|
||||
|
||||
/**
|
||||
* Manually reconnect the underlying JDBC Connection. Should be called at
|
||||
* some point after manualDisconnect().
|
||||
* <p/>
|
||||
* This form is used for ConnectionProvider-supplied connections.
|
||||
*/
|
||||
void manualReconnect();
|
||||
|
||||
/**
|
||||
* Manually reconnect the underlying JDBC Connection. Should be called at
|
||||
* some point after manualDisconnect().
|
||||
* <p/>
|
||||
* This form is used for user-supplied connections.
|
||||
*/
|
||||
void manualReconnect(Connection suppliedConnection);
|
||||
|
||||
/**
|
||||
* Callback to let us know that a flush is beginning. We use this fact
|
||||
* to temporarily circumvent aggressive connection releasing until after
|
||||
* the flush cycle is complete {@link #flushEnding()}
|
||||
*/
|
||||
void flushBeginning();
|
||||
|
||||
/**
|
||||
* Callback to let us know that a flush is ending. We use this fact to
|
||||
* stop circumventing aggressive releasing connections.
|
||||
*/
|
||||
void flushEnding();
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for inserting / deleting / updating,
|
||||
* using JDBC3 getGeneratedKeys ({@link java.sql.Connection#prepareStatement(String, int)}).
|
||||
*/
|
||||
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
|
||||
throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for inserting / deleting / updating.
|
||||
* using JDBC3 getGeneratedKeys ({@link java.sql.Connection#prepareStatement(String, String[])}).
|
||||
*/
|
||||
public PreparedStatement prepareStatement(String sql, String[] columnNames)
|
||||
throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for selecting. Does not
|
||||
* result in execution of the current batch.
|
||||
*/
|
||||
public PreparedStatement prepareSelectStatement(String sql)
|
||||
throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for inserting / deleting / updating.
|
||||
*/
|
||||
public PreparedStatement prepareStatement(String sql, boolean isCallable)
|
||||
throws SQLException, HibernateException ;
|
||||
|
||||
/**
|
||||
* Get a non-batchable callable statement to use for inserting / deleting / updating.
|
||||
*/
|
||||
public CallableStatement prepareCallableStatement(String sql) throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Get a batchable prepared statement to use for inserting / deleting / updating
|
||||
* (might be called many times before a single call to <tt>executeBatch()</tt>).
|
||||
* After setting parameters, call <tt>addToBatch</tt> - do not execute the
|
||||
* statement explicitly.
|
||||
* @see org.hibernate.jdbc.Batcher#addToBatch
|
||||
*/
|
||||
public PreparedStatement prepareBatchStatement(String sql, boolean isCallable) throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Get a prepared statement for use in loading / querying. If not explicitly
|
||||
* released by <tt>closeQueryStatement()</tt>, it will be released when the
|
||||
* session is closed or disconnected.
|
||||
*/
|
||||
public PreparedStatement prepareQueryStatement(
|
||||
String sql,
|
||||
boolean isCallable) throws SQLException, HibernateException;
|
||||
/**
|
||||
* Cancel the current query statement
|
||||
*/
|
||||
public void cancelLastQuery() throws HibernateException;
|
||||
|
||||
public PreparedStatement prepareScrollableQueryStatement(
|
||||
String sql,
|
||||
ScrollMode scrollMode,
|
||||
boolean isCallable) throws SQLException, HibernateException;
|
||||
|
||||
public void abortBatch(SQLException sqle);
|
||||
|
||||
public void addToBatch(Expectation expectation ) throws SQLException, HibernateException;
|
||||
|
||||
public void executeBatch() throws HibernateException;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Connection;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.transaction.TransactionFactory;
|
||||
import org.hibernate.transaction.synchronization.CallbackCoordinator;
|
||||
|
||||
/**
|
||||
* Acts as the SPI for the mediary between "entity-mode related" sessions in terms of
|
||||
* their interaction with the JDBC data store.
|
||||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public interface JDBCContext extends Serializable {
|
||||
|
||||
// TODO: Document these methods...
|
||||
|
||||
CallbackCoordinator getJtaSynchronizationCallbackCoordinator();
|
||||
|
||||
void cleanUpJtaSynchronizationCallbackCoordinator();
|
||||
|
||||
SessionFactoryImplementor getFactory();
|
||||
|
||||
ConnectionManager getConnectionManager();
|
||||
|
||||
Connection connection() throws HibernateException;
|
||||
|
||||
boolean registerCallbackIfNecessary();
|
||||
|
||||
boolean registerSynchronizationIfPossible();
|
||||
|
||||
boolean isTransactionInProgress();
|
||||
|
||||
Transaction getTransaction() throws HibernateException;
|
||||
|
||||
void beforeTransactionCompletion(Transaction tx);
|
||||
|
||||
void afterTransactionBegin(Transaction tx);
|
||||
|
||||
void afterTransactionCompletion(boolean success, Transaction tx);
|
||||
|
||||
void afterNontransactionalQuery(boolean success);
|
||||
|
||||
public static interface Context extends TransactionFactory.Context {
|
||||
/**
|
||||
* We cannot rely upon this method being called! It is only
|
||||
* called if we are using Hibernate Transaction API.
|
||||
*/
|
||||
public void afterTransactionBegin(Transaction tx);
|
||||
public void beforeTransactionCompletion(Transaction tx);
|
||||
public void afterTransactionCompletion(boolean success, Transaction tx);
|
||||
public ConnectionReleaseMode getConnectionReleaseMode();
|
||||
public boolean isAutoCloseSessionEnabled();
|
||||
}
|
||||
}
|
|
@ -39,6 +39,10 @@ public interface JdbcResourceRegistry {
|
|||
*/
|
||||
public void register(Statement statement);
|
||||
|
||||
public void registerLastQuery(Statement statement);
|
||||
|
||||
public void cancelLastQuery();
|
||||
|
||||
/**
|
||||
* Release a previously registered statement.
|
||||
*
|
||||
|
|
|
@ -31,7 +31,7 @@ import java.sql.Connection;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface LogicalConnection extends Serializable {
|
||||
public interface LogicalConnection {
|
||||
/**
|
||||
* Is this logical connection open? Another phraseology sometimes used is: "are we
|
||||
* logically connected"?
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
package org.hibernate.engine.jdbc.spi;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.stat.StatisticsImplementor;
|
||||
|
||||
/**
|
||||
* The "internal" contract for LogicalConnection
|
||||
|
@ -38,6 +39,27 @@ public interface LogicalConnectionImplementor extends LogicalConnection {
|
|||
*/
|
||||
public JdbcServices getJdbcServices();
|
||||
|
||||
/**
|
||||
* Obtains the statistics implementor.
|
||||
*
|
||||
* @return the statistics implementor
|
||||
*/
|
||||
public StatisticsImplementor getStatisticsImplementor();
|
||||
|
||||
/**
|
||||
* Is the transaction timeout set?
|
||||
*
|
||||
* @return true, if the transaction timeout is set; false otherwise
|
||||
*/
|
||||
public boolean isTransactionTimeoutSet();
|
||||
|
||||
/**
|
||||
* Gets the transaction timeout.
|
||||
*
|
||||
* @return the transaction time out
|
||||
*/
|
||||
public long getTransactionTimeout();
|
||||
|
||||
/**
|
||||
* Obtains the JDBC resource registry associated with this logical connection.
|
||||
*
|
||||
|
@ -82,4 +104,6 @@ public interface LogicalConnectionImplementor extends LogicalConnection {
|
|||
* Re-enable aggressive release processing (after a prior {@link #disableReleases()} call.
|
||||
*/
|
||||
public void enableReleases();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ import org.hibernate.engine.SessionFactoryImplementor;
|
|||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.engine.TypedValue;
|
||||
import org.hibernate.event.EventSource;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.loader.custom.sql.SQLCustomQuery;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.util.ArrayHelper;
|
||||
|
@ -199,7 +198,7 @@ public class NativeSQLQueryPlan implements Serializable {
|
|||
session );
|
||||
String sql = queryParameters.getFilteredSQL();
|
||||
|
||||
ps = session.getBatcher().prepareStatement( sql );
|
||||
ps = session.getJDBCContext().getConnectionManager().prepareStatement( sql, false );
|
||||
|
||||
try {
|
||||
int col = 1;
|
||||
|
@ -211,7 +210,7 @@ public class NativeSQLQueryPlan implements Serializable {
|
|||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -238,7 +238,9 @@ public abstract class AbstractStatementExecutor implements StatementExecutor {
|
|||
// at the very least cleanup the data :)
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = session.getBatcher().prepareStatement( "delete from " + persister.getTemporaryIdTableName() );
|
||||
ps = session.getJDBCContext().getConnectionManager().prepareStatement( "delete from " + persister.getTemporaryIdTableName(),
|
||||
false
|
||||
);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
catch( Throwable t ) {
|
||||
|
@ -247,7 +249,7 @@ public abstract class AbstractStatementExecutor implements StatementExecutor {
|
|||
finally {
|
||||
if ( ps != null ) {
|
||||
try {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
// ignore
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.engine.QueryParameters;
|
||||
import org.hibernate.engine.RowSelection;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.hql.ast.HqlSqlWalker;
|
||||
import org.hibernate.hql.ast.QuerySyntaxException;
|
||||
import org.hibernate.hql.ast.SqlGenerator;
|
||||
|
@ -85,7 +84,7 @@ public class BasicExecutor extends AbstractStatementExecutor {
|
|||
|
||||
try {
|
||||
try {
|
||||
st = session.getBatcher().prepareStatement( sql );
|
||||
st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, false );
|
||||
Iterator parameterSpecifications = this.parameterSpecifications.iterator();
|
||||
int pos = 1;
|
||||
while ( parameterSpecifications.hasNext() ) {
|
||||
|
@ -102,7 +101,7 @@ public class BasicExecutor extends AbstractStatementExecutor {
|
|||
}
|
||||
finally {
|
||||
if ( st != null ) {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ import java.util.Iterator;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.QueryParameters;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.hql.ast.HqlSqlWalker;
|
||||
import org.hibernate.hql.ast.tree.DeleteStatement;
|
||||
import org.hibernate.hql.ast.tree.FromElement;
|
||||
|
@ -106,7 +105,7 @@ public class MultiTableDeleteExecutor extends AbstractStatementExecutor {
|
|||
int resultCount = 0;
|
||||
try {
|
||||
try {
|
||||
ps = session.getBatcher().prepareStatement( idInsertSelect );
|
||||
ps = session.getJDBCContext().getConnectionManager().prepareStatement( idInsertSelect, false );
|
||||
Iterator paramSpecifications = getIdSelectParameterSpecifications().iterator();
|
||||
int pos = 1;
|
||||
while ( paramSpecifications.hasNext() ) {
|
||||
|
@ -117,7 +116,7 @@ public class MultiTableDeleteExecutor extends AbstractStatementExecutor {
|
|||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,12 +132,12 @@ public class MultiTableDeleteExecutor extends AbstractStatementExecutor {
|
|||
for ( int i = 0; i < deletes.length; i++ ) {
|
||||
try {
|
||||
try {
|
||||
ps = session.getBatcher().prepareStatement( deletes[i] );
|
||||
ps = session.getJDBCContext().getConnectionManager().prepareStatement( deletes[i], false );
|
||||
ps.executeUpdate();
|
||||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import java.util.List;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.QueryParameters;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.hql.ast.HqlSqlWalker;
|
||||
import org.hibernate.hql.ast.tree.AssignmentSpecification;
|
||||
import org.hibernate.hql.ast.tree.FromElement;
|
||||
|
@ -130,7 +129,7 @@ public class MultiTableUpdateExecutor extends AbstractStatementExecutor {
|
|||
int resultCount = 0;
|
||||
try {
|
||||
try {
|
||||
ps = session.getBatcher().prepareStatement( idInsertSelect );
|
||||
ps = session.getJDBCContext().getConnectionManager().prepareStatement( idInsertSelect, false );
|
||||
// int parameterStart = getWalker().getNumberOfParametersInSetClause();
|
||||
// List allParams = getIdSelectParameterSpecifications();
|
||||
// Iterator whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
|
||||
|
@ -143,7 +142,7 @@ public class MultiTableUpdateExecutor extends AbstractStatementExecutor {
|
|||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +161,7 @@ public class MultiTableUpdateExecutor extends AbstractStatementExecutor {
|
|||
}
|
||||
try {
|
||||
try {
|
||||
ps = session.getBatcher().prepareStatement( updates[i] );
|
||||
ps = session.getJDBCContext().getConnectionManager().prepareStatement( updates[i], false );
|
||||
if ( hqlParameters[i] != null ) {
|
||||
int position = 1; // jdbc params are 1-based
|
||||
for ( int x = 0; x < hqlParameters[i].length; x++ ) {
|
||||
|
@ -173,7 +172,7 @@ public class MultiTableUpdateExecutor extends AbstractStatementExecutor {
|
|||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
|
||||
/**
|
||||
* Generates <tt>string</tt> values using the SQL Server NEWID() function.
|
||||
|
@ -59,7 +58,7 @@ public class GUIDGenerator implements IdentifierGenerator {
|
|||
|
||||
final String sql = session.getFactory().getDialect().getSelectGUIDString();
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement(sql);
|
||||
try {
|
||||
ResultSet rs = st.executeQuery();
|
||||
final String result;
|
||||
|
@ -74,7 +73,7 @@ public class GUIDGenerator implements IdentifierGenerator {
|
|||
return result;
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement(st);
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
|
|
|
@ -87,7 +87,7 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
|
|||
}
|
||||
|
||||
protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
|
||||
return session.getBatcher().prepareStatement( insertSQL, true );
|
||||
return session.getJDBCContext().getConnectionManager().prepareStatement( insertSQL, PreparedStatement.RETURN_GENERATED_KEYS );
|
||||
}
|
||||
|
||||
public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
|
||||
|
@ -131,7 +131,7 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
|
|||
}
|
||||
|
||||
protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
|
||||
return session.getBatcher().prepareStatement( insertSQL, false );
|
||||
return session.getJDBCContext().getConnectionManager().prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS );
|
||||
}
|
||||
|
||||
public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.hibernate.MappingException;
|
|||
import org.hibernate.cfg.ObjectNameNormalizer;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.util.StringHelper;
|
||||
|
@ -122,7 +121,7 @@ public class IncrementGenerator implements IdentifierGenerator, Configurable {
|
|||
|
||||
log.debug( "fetching initial value: " + sql );
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
try {
|
||||
ResultSet rs = st.executeQuery();
|
||||
try {
|
||||
|
@ -140,7 +139,7 @@ public class IncrementGenerator implements IdentifierGenerator, Configurable {
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement(st);
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
|
|
|
@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.cfg.ObjectNameNormalizer;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.mapping.Table;
|
||||
|
@ -107,7 +106,7 @@ public class SequenceGenerator implements PersistentIdentifierGenerator, Configu
|
|||
|
||||
protected IntegralDataTypeHolder generateHolder(SessionImplementor session) {
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
try {
|
||||
ResultSet rs = st.executeQuery();
|
||||
try {
|
||||
|
@ -124,7 +123,7 @@ public class SequenceGenerator implements PersistentIdentifierGenerator, Configu
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement(st);
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ public class SequenceIdentityGenerator extends SequenceGenerator
|
|||
}
|
||||
|
||||
protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
|
||||
return session.getBatcher().prepareStatement( insertSQL, keyColumns );
|
||||
return session.getJDBCContext().getConnectionManager().prepareStatement( insertSQL, keyColumns );
|
||||
}
|
||||
|
||||
protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.id.IdentifierGeneratorHelper;
|
||||
import org.hibernate.id.IntegralDataTypeHolder;
|
||||
|
@ -103,7 +102,7 @@ public class SequenceStructure implements DatabaseStructure {
|
|||
public IntegralDataTypeHolder getNextValue() {
|
||||
accessCounter++;
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
try {
|
||||
ResultSet rs = st.executeQuery();
|
||||
try {
|
||||
|
@ -125,7 +124,7 @@ public class SequenceStructure implements DatabaseStructure {
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ package org.hibernate.id.insert;
|
|||
|
||||
import org.hibernate.id.PostInsertIdentityPersister;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
@ -78,6 +77,6 @@ public abstract class AbstractReturningDelegate implements InsertGeneratedIdenti
|
|||
protected abstract Serializable executeAndExtract(PreparedStatement insert) throws SQLException;
|
||||
|
||||
protected void releaseStatement(PreparedStatement insert, SessionImplementor session) throws SQLException {
|
||||
session.getBatcher().closeStatement( insert );
|
||||
insert.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
*/
|
||||
package org.hibernate.id.insert;
|
||||
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.id.PostInsertIdentityPersister;
|
||||
|
@ -51,13 +50,13 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti
|
|||
public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) {
|
||||
try {
|
||||
// prepare and execute the insert
|
||||
PreparedStatement insert = session.getBatcher().prepareStatement( insertSQL, false );
|
||||
PreparedStatement insert = session.getJDBCContext().getConnectionManager().prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS );
|
||||
try {
|
||||
binder.bindValues( insert );
|
||||
insert.executeUpdate();
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( insert );
|
||||
insert.close();
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
|
@ -72,7 +71,7 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti
|
|||
|
||||
try {
|
||||
//fetch the generated id in a separate query
|
||||
PreparedStatement idSelect = session.getBatcher().prepareStatement( selectSQL );
|
||||
PreparedStatement idSelect = session.getJDBCContext().getConnectionManager().prepareStatement( selectSQL, false );
|
||||
try {
|
||||
bindParameters( session, idSelect, binder.getEntity() );
|
||||
ResultSet rs = idSelect.executeQuery();
|
||||
|
@ -84,7 +83,7 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( idSelect );
|
||||
idSelect.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ import org.hibernate.MappingException;
|
|||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.engine.QueryParameters;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.hql.HolderInstantiator;
|
||||
import org.hibernate.loader.Loader;
|
||||
import org.hibernate.type.Type;
|
||||
|
@ -119,7 +118,8 @@ public abstract class AbstractScrollableResults implements ScrollableResults {
|
|||
public final void close() throws HibernateException {
|
||||
try {
|
||||
// not absolutely necessary, but does help with aggressive release
|
||||
session.getBatcher().closeQueryStatement( ps, resultSet );
|
||||
//session.getJDBCContext().getConnectionManager().closeQueryStatement( ps, resultSet );
|
||||
ps.close();
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
throw session.getFactory().getSQLExceptionHelper().convert(
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.engine.HibernateIterator;
|
||||
import org.hibernate.event.EventSource;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.hql.HolderInstantiator;
|
||||
import org.hibernate.type.EntityType;
|
||||
import org.hibernate.type.Type;
|
||||
|
@ -87,7 +86,7 @@ public final class IteratorImpl implements HibernateIterator {
|
|||
if (ps!=null) {
|
||||
try {
|
||||
log.debug("closing iterator");
|
||||
session.getBatcher().closeQueryStatement(ps, rs);
|
||||
ps.close();
|
||||
ps = null;
|
||||
rs = null;
|
||||
hasNext = false;
|
||||
|
|
|
@ -89,6 +89,8 @@ import org.hibernate.engine.Status;
|
|||
import org.hibernate.engine.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.internal.JDBCContextImpl;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.engine.query.FilterQueryPlan;
|
||||
import org.hibernate.engine.query.HQLQueryPlan;
|
||||
import org.hibernate.engine.query.NativeSQLQueryPlan;
|
||||
|
@ -122,9 +124,6 @@ import org.hibernate.event.ReplicateEvent;
|
|||
import org.hibernate.event.ReplicateEventListener;
|
||||
import org.hibernate.event.SaveOrUpdateEvent;
|
||||
import org.hibernate.event.SaveOrUpdateEventListener;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.jdbc.Batcher;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.jdbc.Work;
|
||||
import org.hibernate.loader.criteria.CriteriaLoader;
|
||||
import org.hibernate.loader.custom.CustomLoader;
|
||||
|
@ -174,7 +173,7 @@ public final class SessionImpl extends AbstractSessionImpl
|
|||
|
||||
private transient ActionQueue actionQueue;
|
||||
private transient StatefulPersistenceContext persistenceContext;
|
||||
private transient JDBCContext jdbcContext;
|
||||
private transient JDBCContextImpl jdbcContext;
|
||||
private transient EventListeners listeners;
|
||||
|
||||
private transient boolean flushBeforeCompletionEnabled;
|
||||
|
@ -252,7 +251,7 @@ public final class SessionImpl extends AbstractSessionImpl
|
|||
this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
|
||||
this.autoCloseSessionEnabled = autoCloseSessionEnabled;
|
||||
this.connectionReleaseMode = connectionReleaseMode;
|
||||
this.jdbcContext = new JDBCContext( this, connection, interceptor );
|
||||
this.jdbcContext = new JDBCContextImpl( this, connection, interceptor );
|
||||
|
||||
loadQueryInfluencers = new LoadQueryInfluencers( factory );
|
||||
|
||||
|
@ -300,14 +299,6 @@ public final class SessionImpl extends AbstractSessionImpl
|
|||
actionQueue.clear();
|
||||
}
|
||||
|
||||
public Batcher getBatcher() {
|
||||
errorIfClosed();
|
||||
checkTransactionSynchStatus();
|
||||
// TODO : should remove this exposure
|
||||
// and have all references to the session's batcher use the ConnectionManager.
|
||||
return jdbcContext.getConnectionManager().getBatcher();
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
checkTransactionSynchStatus();
|
||||
return timestamp;
|
||||
|
@ -1913,7 +1904,7 @@ public final class SessionImpl extends AbstractSessionImpl
|
|||
|
||||
public void cancelQuery() throws HibernateException {
|
||||
errorIfClosed();
|
||||
getBatcher().cancelLastQuery();
|
||||
getJDBCContext().getConnectionManager().cancelLastQuery();
|
||||
}
|
||||
|
||||
public Interceptor getInterceptor() {
|
||||
|
@ -2140,7 +2131,7 @@ public final class SessionImpl extends AbstractSessionImpl
|
|||
listeners = factory.getEventListeners();
|
||||
|
||||
if ( isRootSession ) {
|
||||
jdbcContext = JDBCContext.deserialize( ois, this, interceptor );
|
||||
jdbcContext = JDBCContextImpl.deserialize( ois, this, interceptor );
|
||||
}
|
||||
|
||||
persistenceContext = StatefulPersistenceContext.deserialize( ois, this );
|
||||
|
@ -2177,7 +2168,7 @@ public final class SessionImpl extends AbstractSessionImpl
|
|||
* @throws IOException Indicates a general IO stream exception
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
if ( !jdbcContext.getConnectionManager().isReadyForSerialization() ) {
|
||||
if ( !jdbcContext.isReadyForSerialization() ) {
|
||||
throw new IllegalStateException( "Cannot serialize a session while connected" );
|
||||
}
|
||||
|
||||
|
|
|
@ -56,13 +56,13 @@ import org.hibernate.engine.StatefulPersistenceContext;
|
|||
import org.hibernate.engine.Versioning;
|
||||
import org.hibernate.engine.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.NonFlushedChanges;
|
||||
import org.hibernate.engine.jdbc.internal.JDBCContextImpl;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.engine.query.HQLQueryPlan;
|
||||
import org.hibernate.engine.query.NativeSQLQueryPlan;
|
||||
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
|
||||
import org.hibernate.event.EventListeners;
|
||||
import org.hibernate.id.IdentifierGeneratorHelper;
|
||||
import org.hibernate.jdbc.Batcher;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.loader.criteria.CriteriaLoader;
|
||||
import org.hibernate.loader.custom.CustomLoader;
|
||||
import org.hibernate.loader.custom.CustomQuery;
|
||||
|
@ -81,12 +81,12 @@ public class StatelessSessionImpl extends AbstractSessionImpl
|
|||
|
||||
private static final Logger log = LoggerFactory.getLogger( StatelessSessionImpl.class );
|
||||
|
||||
private JDBCContext jdbcContext;
|
||||
private JDBCContextImpl jdbcContext;
|
||||
private PersistenceContext temporaryPersistenceContext = new StatefulPersistenceContext( this );
|
||||
|
||||
StatelessSessionImpl(Connection connection, SessionFactoryImpl factory) {
|
||||
super( factory );
|
||||
this.jdbcContext = new JDBCContext( this, connection, EmptyInterceptor.INSTANCE );
|
||||
this.jdbcContext = new JDBCContextImpl( this, connection, EmptyInterceptor.INSTANCE );
|
||||
}
|
||||
|
||||
|
||||
|
@ -330,7 +330,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl
|
|||
|
||||
public void managedFlush() {
|
||||
errorIfClosed();
|
||||
getBatcher().executeBatch();
|
||||
getJDBCContext().getConnectionManager().executeBatch();
|
||||
}
|
||||
|
||||
public boolean shouldAutoClose() {
|
||||
|
@ -371,12 +371,6 @@ public class StatelessSessionImpl extends AbstractSessionImpl
|
|||
return result;
|
||||
}
|
||||
|
||||
public Batcher getBatcher() {
|
||||
errorIfClosed();
|
||||
return jdbcContext.getConnectionManager()
|
||||
.getBatcher();
|
||||
}
|
||||
|
||||
public CacheMode getCacheMode() {
|
||||
return CacheMode.IGNORE;
|
||||
}
|
||||
|
|
|
@ -24,29 +24,14 @@
|
|||
*/
|
||||
package org.hibernate.jdbc;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.ConcurrentModificationException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.jdbc.util.FormatStyle;
|
||||
import org.hibernate.util.JDBCExceptionReporter;
|
||||
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
|
||||
|
||||
/**
|
||||
* Manages prepared statements and batching.
|
||||
|
@ -55,225 +40,84 @@ import org.hibernate.util.JDBCExceptionReporter;
|
|||
*/
|
||||
public abstract class AbstractBatcher implements Batcher {
|
||||
|
||||
private static int globalOpenPreparedStatementCount;
|
||||
private static int globalOpenResultSetCount;
|
||||
|
||||
private int openPreparedStatementCount;
|
||||
private int openResultSetCount;
|
||||
|
||||
protected static final Logger log = LoggerFactory.getLogger( AbstractBatcher.class );
|
||||
|
||||
private final ConnectionManager connectionManager;
|
||||
private final SessionFactoryImplementor factory;
|
||||
private final SQLExceptionHelper exceptionHelper;
|
||||
private final int jdbcBatchSize;
|
||||
|
||||
private PreparedStatement batchUpdate;
|
||||
private String batchUpdateSQL;
|
||||
private boolean isClosingBatchUpdate = false;
|
||||
|
||||
private HashSet statementsToClose = new HashSet();
|
||||
private HashSet resultSetsToClose = new HashSet();
|
||||
private PreparedStatement lastQuery;
|
||||
|
||||
private boolean releasing = false;
|
||||
private final Interceptor interceptor;
|
||||
|
||||
private long transactionTimeout = -1;
|
||||
boolean isTransactionTimeoutSet;
|
||||
|
||||
public AbstractBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
|
||||
this.connectionManager = connectionManager;
|
||||
this.interceptor = interceptor;
|
||||
this.factory = connectionManager.getFactory();
|
||||
public AbstractBatcher(SQLExceptionHelper exceptionHelper, int jdbcBatchSize) {
|
||||
this.exceptionHelper = exceptionHelper;
|
||||
this.jdbcBatchSize = jdbcBatchSize;
|
||||
}
|
||||
|
||||
public void setTransactionTimeout(int seconds) {
|
||||
isTransactionTimeoutSet = true;
|
||||
transactionTimeout = System.currentTimeMillis() / 1000 + seconds;
|
||||
public final int getJdbcBatchSize() {
|
||||
return jdbcBatchSize;
|
||||
}
|
||||
|
||||
public void unsetTransactionTimeout() {
|
||||
isTransactionTimeoutSet = false;
|
||||
public boolean hasOpenResources() {
|
||||
try {
|
||||
return !isClosingBatchUpdate && batchUpdate != null && ! batchUpdate.isClosed();
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
throw exceptionHelper.convert(
|
||||
sqle,
|
||||
"Could check to see if batch statement was closed",
|
||||
batchUpdateSQL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public PreparedStatement getStatement(String sql) {
|
||||
return batchUpdate != null && batchUpdateSQL.equals( sql ) ? batchUpdate : null;
|
||||
}
|
||||
|
||||
public void setStatement(String sql, PreparedStatement ps) {
|
||||
checkNotClosingBatchUpdate();
|
||||
batchUpdateSQL = sql;
|
||||
batchUpdate = ps;
|
||||
}
|
||||
|
||||
protected PreparedStatement getStatement() {
|
||||
return batchUpdate;
|
||||
}
|
||||
|
||||
public CallableStatement prepareCallableStatement(String sql)
|
||||
throws SQLException, HibernateException {
|
||||
executeBatch();
|
||||
logOpenPreparedStatement();
|
||||
return getCallableStatement( connectionManager.getConnection(), sql, false);
|
||||
}
|
||||
|
||||
public PreparedStatement prepareStatement(String sql)
|
||||
throws SQLException, HibernateException {
|
||||
return prepareStatement( sql, false );
|
||||
}
|
||||
|
||||
public PreparedStatement prepareStatement(String sql, boolean getGeneratedKeys)
|
||||
throws SQLException, HibernateException {
|
||||
executeBatch();
|
||||
logOpenPreparedStatement();
|
||||
return getPreparedStatement(
|
||||
connectionManager.getConnection(),
|
||||
sql,
|
||||
false,
|
||||
getGeneratedKeys,
|
||||
null,
|
||||
null,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
public PreparedStatement prepareStatement(String sql, String[] columnNames)
|
||||
throws SQLException, HibernateException {
|
||||
executeBatch();
|
||||
logOpenPreparedStatement();
|
||||
return getPreparedStatement(
|
||||
connectionManager.getConnection(),
|
||||
sql,
|
||||
false,
|
||||
false,
|
||||
columnNames,
|
||||
null,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
public PreparedStatement prepareSelectStatement(String sql)
|
||||
throws SQLException, HibernateException {
|
||||
logOpenPreparedStatement();
|
||||
return getPreparedStatement(
|
||||
connectionManager.getConnection(),
|
||||
sql,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
public PreparedStatement prepareQueryStatement(
|
||||
String sql,
|
||||
boolean scrollable,
|
||||
ScrollMode scrollMode) throws SQLException, HibernateException {
|
||||
logOpenPreparedStatement();
|
||||
PreparedStatement ps = getPreparedStatement(
|
||||
connectionManager.getConnection(),
|
||||
sql,
|
||||
scrollable,
|
||||
scrollMode
|
||||
);
|
||||
setStatementFetchSize( ps );
|
||||
statementsToClose.add( ps );
|
||||
lastQuery = ps;
|
||||
return ps;
|
||||
}
|
||||
|
||||
public CallableStatement prepareCallableQueryStatement(
|
||||
String sql,
|
||||
boolean scrollable,
|
||||
ScrollMode scrollMode) throws SQLException, HibernateException {
|
||||
logOpenPreparedStatement();
|
||||
CallableStatement ps = ( CallableStatement ) getPreparedStatement(
|
||||
connectionManager.getConnection(),
|
||||
sql,
|
||||
scrollable,
|
||||
false,
|
||||
null,
|
||||
scrollMode,
|
||||
true
|
||||
);
|
||||
setStatementFetchSize( ps );
|
||||
statementsToClose.add( ps );
|
||||
lastQuery = ps;
|
||||
return ps;
|
||||
}
|
||||
|
||||
public void abortBatch(SQLException sqle) {
|
||||
closeStatements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually releases the batcher, allowing it to cleanup internally held
|
||||
* resources.
|
||||
*/
|
||||
public void closeStatements() {
|
||||
try {
|
||||
if (batchUpdate!=null) closeStatement(batchUpdate);
|
||||
closeBatchUpdate();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
//noncritical, swallow and let the other propagate!
|
||||
JDBCExceptionReporter.logExceptions(e);
|
||||
}
|
||||
finally {
|
||||
batchUpdate=null;
|
||||
batchUpdateSQL=null;
|
||||
catch ( SQLException sqle ) {
|
||||
//no big deal
|
||||
log.warn( "Could not close a JDBC prepared statement", sqle );
|
||||
}
|
||||
batchUpdate = null;
|
||||
batchUpdateSQL = null;
|
||||
}
|
||||
|
||||
public ResultSet getResultSet(PreparedStatement ps) throws SQLException {
|
||||
ResultSet rs = ps.executeQuery();
|
||||
resultSetsToClose.add(rs);
|
||||
logOpenResults();
|
||||
return rs;
|
||||
}
|
||||
|
||||
public ResultSet getResultSet(CallableStatement ps, Dialect dialect) throws SQLException {
|
||||
ResultSet rs = dialect.getResultSet(ps);
|
||||
resultSetsToClose.add(rs);
|
||||
logOpenResults();
|
||||
return rs;
|
||||
|
||||
}
|
||||
|
||||
public void closeQueryStatement(PreparedStatement ps, ResultSet rs) throws SQLException {
|
||||
boolean psStillThere = statementsToClose.remove( ps );
|
||||
try {
|
||||
if ( rs != null ) {
|
||||
if ( resultSetsToClose.remove( rs ) ) {
|
||||
logCloseResults();
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ( psStillThere ) {
|
||||
closeQueryStatement( ps );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PreparedStatement prepareBatchStatement(String sql)
|
||||
throws SQLException, HibernateException {
|
||||
sql = getSQL( sql );
|
||||
|
||||
if ( !sql.equals(batchUpdateSQL) ) {
|
||||
batchUpdate=prepareStatement(sql); // calls executeBatch()
|
||||
batchUpdateSQL=sql;
|
||||
}
|
||||
else {
|
||||
log.debug("reusing prepared statement");
|
||||
log(sql);
|
||||
}
|
||||
return batchUpdate;
|
||||
}
|
||||
|
||||
public CallableStatement prepareBatchCallableStatement(String sql)
|
||||
throws SQLException, HibernateException {
|
||||
if ( !sql.equals(batchUpdateSQL) ) { // TODO: what if batchUpdate is a callablestatement ?
|
||||
batchUpdate=prepareCallableStatement(sql); // calls executeBatch()
|
||||
batchUpdateSQL=sql;
|
||||
}
|
||||
return (CallableStatement)batchUpdate;
|
||||
}
|
||||
|
||||
|
||||
public void executeBatch() throws HibernateException {
|
||||
checkNotClosingBatchUpdate();
|
||||
if (batchUpdate!=null) {
|
||||
try {
|
||||
try {
|
||||
doExecuteBatch(batchUpdate);
|
||||
}
|
||||
finally {
|
||||
closeStatement(batchUpdate);
|
||||
closeBatchUpdate();
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
throw factory.getSQLExceptionHelper().convert(
|
||||
throw exceptionHelper.convert(
|
||||
sqle,
|
||||
"Could not execute JDBC batch update",
|
||||
batchUpdateSQL
|
||||
|
@ -286,321 +130,28 @@ public abstract class AbstractBatcher implements Batcher {
|
|||
}
|
||||
}
|
||||
|
||||
public void closeStatement(PreparedStatement ps) throws SQLException {
|
||||
logClosePreparedStatement();
|
||||
closePreparedStatement(ps);
|
||||
}
|
||||
|
||||
private void closeQueryStatement(PreparedStatement ps) throws SQLException {
|
||||
|
||||
try {
|
||||
//work around a bug in all known connection pools....
|
||||
if ( ps.getMaxRows()!=0 ) ps.setMaxRows(0);
|
||||
if ( ps.getQueryTimeout()!=0 ) ps.setQueryTimeout(0);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("exception clearing maxRows/queryTimeout", e);
|
||||
// ps.close(); //just close it; do NOT try to return it to the pool!
|
||||
return; //NOTE: early exit!
|
||||
}
|
||||
finally {
|
||||
closeStatement(ps);
|
||||
}
|
||||
|
||||
if ( lastQuery==ps ) lastQuery = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually releases the batcher, allowing it to cleanup internally held
|
||||
* resources.
|
||||
*/
|
||||
public void closeStatements() {
|
||||
try {
|
||||
releasing = true;
|
||||
|
||||
try {
|
||||
if ( batchUpdate != null ) {
|
||||
batchUpdate.close();
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
//no big deal
|
||||
log.warn( "Could not close a JDBC prepared statement", sqle );
|
||||
}
|
||||
batchUpdate = null;
|
||||
batchUpdateSQL = null;
|
||||
|
||||
Iterator iter = resultSetsToClose.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
try {
|
||||
logCloseResults();
|
||||
( ( ResultSet ) iter.next() ).close();
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
// no big deal
|
||||
log.warn( "Could not close a JDBC result set", e );
|
||||
}
|
||||
catch ( ConcurrentModificationException e ) {
|
||||
// this has been shown to happen occasionally in rare cases
|
||||
// when using a transaction manager + transaction-timeout
|
||||
// where the timeout calls back through Hibernate's
|
||||
// registered transaction synchronization on a separate
|
||||
// "reaping" thread. In cases where that reaping thread
|
||||
// executes through this block at the same time the main
|
||||
// application thread does we can get into situations where
|
||||
// these CMEs occur. And though it is not "allowed" per-se,
|
||||
// the end result without handling it specifically is infinite
|
||||
// looping. So here, we simply break the loop
|
||||
log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
|
||||
break;
|
||||
}
|
||||
catch ( Throwable e ) {
|
||||
// sybase driver (jConnect) throwing NPE here in certain
|
||||
// cases, but we'll just handle the general "unexpected" case
|
||||
log.warn( "Could not close a JDBC result set", e );
|
||||
}
|
||||
}
|
||||
resultSetsToClose.clear();
|
||||
|
||||
iter = statementsToClose.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
try {
|
||||
closeQueryStatement( ( PreparedStatement ) iter.next() );
|
||||
}
|
||||
catch ( ConcurrentModificationException e ) {
|
||||
// see explanation above...
|
||||
log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
|
||||
break;
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
// no big deal
|
||||
log.warn( "Could not close a JDBC statement", e );
|
||||
}
|
||||
}
|
||||
statementsToClose.clear();
|
||||
}
|
||||
finally {
|
||||
releasing = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException;
|
||||
|
||||
private String preparedStatementCountsToString() {
|
||||
return
|
||||
" (open PreparedStatements: " +
|
||||
openPreparedStatementCount +
|
||||
", globally: " +
|
||||
globalOpenPreparedStatementCount +
|
||||
")";
|
||||
}
|
||||
|
||||
private String resultSetCountsToString() {
|
||||
return
|
||||
" (open ResultSets: " +
|
||||
openResultSetCount +
|
||||
", globally: " +
|
||||
globalOpenResultSetCount +
|
||||
")";
|
||||
}
|
||||
|
||||
private void logOpenPreparedStatement() {
|
||||
if ( log.isDebugEnabled() ) {
|
||||
log.debug( "about to open PreparedStatement" + preparedStatementCountsToString() );
|
||||
openPreparedStatementCount++;
|
||||
globalOpenPreparedStatementCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private void logClosePreparedStatement() {
|
||||
if ( log.isDebugEnabled() ) {
|
||||
log.debug( "about to close PreparedStatement" + preparedStatementCountsToString() );
|
||||
openPreparedStatementCount--;
|
||||
globalOpenPreparedStatementCount--;
|
||||
}
|
||||
}
|
||||
|
||||
private void logOpenResults() {
|
||||
if ( log.isDebugEnabled() ) {
|
||||
log.debug( "about to open ResultSet" + resultSetCountsToString() );
|
||||
openResultSetCount++;
|
||||
globalOpenResultSetCount++;
|
||||
}
|
||||
}
|
||||
private void logCloseResults() {
|
||||
if ( log.isDebugEnabled() ) {
|
||||
log.debug( "about to close ResultSet" + resultSetCountsToString() );
|
||||
openResultSetCount--;
|
||||
globalOpenResultSetCount--;
|
||||
}
|
||||
}
|
||||
|
||||
protected SessionFactoryImplementor getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
private void log(String sql) {
|
||||
factory.getSettings().getSqlStatementLogger().logStatement( sql, FormatStyle.BASIC );
|
||||
}
|
||||
|
||||
private PreparedStatement getPreparedStatement(
|
||||
final Connection conn,
|
||||
final String sql,
|
||||
final boolean scrollable,
|
||||
final ScrollMode scrollMode) throws SQLException {
|
||||
return getPreparedStatement(
|
||||
conn,
|
||||
sql,
|
||||
scrollable,
|
||||
false,
|
||||
null,
|
||||
scrollMode,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
private CallableStatement getCallableStatement(
|
||||
final Connection conn,
|
||||
String sql,
|
||||
boolean scrollable) throws SQLException {
|
||||
if ( scrollable && !factory.getSettings().isScrollableResultSetsEnabled() ) {
|
||||
throw new AssertionFailure("scrollable result sets are not enabled");
|
||||
}
|
||||
|
||||
sql = getSQL( sql );
|
||||
log( sql );
|
||||
|
||||
log.trace("preparing callable statement");
|
||||
if ( scrollable ) {
|
||||
return conn.prepareCall(
|
||||
sql,
|
||||
ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY
|
||||
);
|
||||
}
|
||||
else {
|
||||
return conn.prepareCall( sql );
|
||||
}
|
||||
}
|
||||
|
||||
private String getSQL(String sql) {
|
||||
sql = interceptor.onPrepareStatement( sql );
|
||||
if ( sql==null || sql.length() == 0 ) {
|
||||
throw new AssertionFailure( "Interceptor.onPrepareStatement() returned null or empty string." );
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
private PreparedStatement getPreparedStatement(
|
||||
final Connection conn,
|
||||
String sql,
|
||||
boolean scrollable,
|
||||
final boolean useGetGeneratedKeys,
|
||||
final String[] namedGeneratedKeys,
|
||||
final ScrollMode scrollMode,
|
||||
final boolean callable) throws SQLException {
|
||||
if ( scrollable && !factory.getSettings().isScrollableResultSetsEnabled() ) {
|
||||
throw new AssertionFailure("scrollable result sets are not enabled");
|
||||
}
|
||||
if ( useGetGeneratedKeys && !factory.getSettings().isGetGeneratedKeysEnabled() ) {
|
||||
throw new AssertionFailure("getGeneratedKeys() support is not enabled");
|
||||
}
|
||||
|
||||
sql = getSQL( sql );
|
||||
log( sql );
|
||||
|
||||
log.trace( "preparing statement" );
|
||||
PreparedStatement result;
|
||||
if ( scrollable ) {
|
||||
if ( callable ) {
|
||||
result = conn.prepareCall( sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY );
|
||||
}
|
||||
else {
|
||||
result = conn.prepareStatement( sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY );
|
||||
}
|
||||
}
|
||||
else if ( useGetGeneratedKeys ) {
|
||||
result = conn.prepareStatement( sql, PreparedStatement.RETURN_GENERATED_KEYS );
|
||||
}
|
||||
else if ( namedGeneratedKeys != null ) {
|
||||
result = conn.prepareStatement( sql, namedGeneratedKeys );
|
||||
}
|
||||
else {
|
||||
if ( callable ) {
|
||||
result = conn.prepareCall( sql );
|
||||
}
|
||||
else {
|
||||
result = conn.prepareStatement( sql );
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout( result );
|
||||
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
factory.getStatisticsImplementor().prepareStatement();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private void setTimeout(PreparedStatement result) throws SQLException {
|
||||
if ( isTransactionTimeoutSet ) {
|
||||
int timeout = (int) ( transactionTimeout - ( System.currentTimeMillis() / 1000 ) );
|
||||
if (timeout<=0) {
|
||||
throw new TransactionException("transaction timeout expired");
|
||||
}
|
||||
else {
|
||||
result.setQueryTimeout(timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void closePreparedStatement(PreparedStatement ps) throws SQLException {
|
||||
private void closeBatchUpdate() throws SQLException{
|
||||
checkNotClosingBatchUpdate();
|
||||
try {
|
||||
log.trace("closing statement");
|
||||
ps.close();
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
factory.getStatisticsImplementor().closeStatement();
|
||||
if ( batchUpdate != null ) {
|
||||
isClosingBatchUpdate = true;
|
||||
batchUpdate.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ( !releasing ) {
|
||||
// If we are in the process of releasing, no sense
|
||||
// checking for aggressive-release possibility.
|
||||
connectionManager.afterStatement();
|
||||
}
|
||||
isClosingBatchUpdate = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void checkNotClosingBatchUpdate() {
|
||||
if ( isClosingBatchUpdate ) {
|
||||
throw new IllegalStateException( "Cannot perform operation while closing batch update." );
|
||||
}
|
||||
}
|
||||
|
||||
private void setStatementFetchSize(PreparedStatement statement) throws SQLException {
|
||||
Integer statementFetchSize = factory.getSettings().getJdbcFetchSize();
|
||||
if ( statementFetchSize!=null ) {
|
||||
statement.setFetchSize( statementFetchSize.intValue() );
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelLastQuery() throws HibernateException {
|
||||
try {
|
||||
if (lastQuery!=null) lastQuery.cancel();
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
throw factory.getSQLExceptionHelper().convert(
|
||||
sqle,
|
||||
"Cannot cancel query"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasOpenResources() {
|
||||
return resultSetsToClose.size() > 0 || statementsToClose.size() > 0;
|
||||
}
|
||||
|
||||
public String openResourceStatsAsString() {
|
||||
return preparedStatementCountsToString() + resultSetCountsToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,82 +45,10 @@ import org.hibernate.dialect.Dialect;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public interface Batcher {
|
||||
/**
|
||||
* Get a prepared statement for use in loading / querying. If not explicitly
|
||||
* released by <tt>closeQueryStatement()</tt>, it will be released when the
|
||||
* session is closed or disconnected.
|
||||
*/
|
||||
public PreparedStatement prepareQueryStatement(String sql, boolean scrollable, ScrollMode scrollMode) throws SQLException, HibernateException;
|
||||
/**
|
||||
* Close a prepared statement opened with <tt>prepareQueryStatement()</tt>
|
||||
*/
|
||||
public void closeQueryStatement(PreparedStatement ps, ResultSet rs) throws SQLException;
|
||||
/**
|
||||
* Get a prepared statement for use in loading / querying. If not explicitly
|
||||
* released by <tt>closeQueryStatement()</tt>, it will be released when the
|
||||
* session is closed or disconnected.
|
||||
*/
|
||||
public CallableStatement prepareCallableQueryStatement(String sql, boolean scrollable, ScrollMode scrollMode) throws SQLException, HibernateException;
|
||||
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for selecting. Does not
|
||||
* result in execution of the current batch.
|
||||
*/
|
||||
public PreparedStatement prepareSelectStatement(String sql) throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for inserting / deleting / updating,
|
||||
* using JDBC3 getGeneratedKeys ({@link Connection#prepareStatement(String, int)}).
|
||||
* <p/>
|
||||
* Must be explicitly released by {@link #closeStatement} after use.
|
||||
*/
|
||||
public PreparedStatement prepareStatement(String sql, boolean useGetGeneratedKeys) throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for inserting / deleting / updating.
|
||||
* using JDBC3 getGeneratedKeys ({@link Connection#prepareStatement(String, String[])}).
|
||||
* <p/>
|
||||
* Must be explicitly released by {@link #closeStatement} after use.
|
||||
*/
|
||||
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Get a non-batchable prepared statement to use for inserting / deleting / updating.
|
||||
* <p/>
|
||||
* Must be explicitly released by {@link #closeStatement} after use.
|
||||
*/
|
||||
public PreparedStatement prepareStatement(String sql) throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Get a non-batchable callable statement to use for inserting / deleting / updating.
|
||||
* <p/>
|
||||
* Must be explicitly released by {@link #closeStatement} after use.
|
||||
*/
|
||||
public CallableStatement prepareCallableStatement(String sql) throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Close a prepared or callable statement opened using <tt>prepareStatement()</tt> or <tt>prepareCallableStatement()</tt>
|
||||
*/
|
||||
public void closeStatement(PreparedStatement ps) throws SQLException;
|
||||
|
||||
/**
|
||||
* Get a batchable prepared statement to use for inserting / deleting / updating
|
||||
* (might be called many times before a single call to <tt>executeBatch()</tt>).
|
||||
* After setting parameters, call <tt>addToBatch</tt> - do not execute the
|
||||
* statement explicitly.
|
||||
* @see Batcher#addToBatch
|
||||
*/
|
||||
public PreparedStatement prepareBatchStatement(String sql) throws SQLException, HibernateException;
|
||||
|
||||
/**
|
||||
* Get a batchable callable statement to use for inserting / deleting / updating
|
||||
* (might be called many times before a single call to <tt>executeBatch()</tt>).
|
||||
* After setting parameters, call <tt>addToBatch</tt> - do not execute the
|
||||
* statement explicitly.
|
||||
* @see Batcher#addToBatch
|
||||
*/
|
||||
public CallableStatement prepareBatchCallableStatement(String sql) throws SQLException, HibernateException;
|
||||
public PreparedStatement getStatement(String sql);
|
||||
public void setStatement(String sql, PreparedStatement ps);
|
||||
public boolean hasOpenResources();
|
||||
|
||||
/**
|
||||
* Add an insert / delete / update to the current batch (might be called multiple times
|
||||
|
@ -133,19 +61,6 @@ public interface Batcher {
|
|||
*/
|
||||
public void executeBatch() throws HibernateException;
|
||||
|
||||
/**
|
||||
* Close any query statements that were left lying around
|
||||
*/
|
||||
public void closeStatements();
|
||||
/**
|
||||
* Execute the statement and return the result set
|
||||
*/
|
||||
public ResultSet getResultSet(PreparedStatement ps) throws SQLException;
|
||||
/**
|
||||
* Execute the statement and return the result set from a callable statement
|
||||
*/
|
||||
public ResultSet getResultSet(CallableStatement ps, Dialect dialect) throws SQLException;
|
||||
|
||||
/**
|
||||
* Must be called when an exception occurs
|
||||
* @param sqle the (not null) exception that is the reason for aborting
|
||||
|
@ -153,23 +68,9 @@ public interface Batcher {
|
|||
public void abortBatch(SQLException sqle);
|
||||
|
||||
/**
|
||||
* Cancel the current query statement
|
||||
* Actually releases the batcher, allowing it to cleanup internally held
|
||||
* resources.
|
||||
*/
|
||||
public void cancelLastQuery() throws HibernateException;
|
||||
|
||||
public boolean hasOpenResources();
|
||||
|
||||
public String openResourceStatsAsString();
|
||||
|
||||
/**
|
||||
* Set the transaction timeout to <tt>seconds</tt> later
|
||||
* than the current system time.
|
||||
*/
|
||||
public void setTransactionTimeout(int seconds);
|
||||
/**
|
||||
* Unset the transaction timeout, called after the end of a
|
||||
* transaction.
|
||||
*/
|
||||
public void unsetTransactionTimeout();
|
||||
public void closeStatements();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
package org.hibernate.jdbc;
|
||||
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -32,5 +33,6 @@ import org.hibernate.Interceptor;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public interface BatcherFactory {
|
||||
public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor);
|
||||
public void setJdbcBatchSize(int jdbcBatchSize);
|
||||
public Batcher createBatcher(SQLExceptionHelper exceptionHelper);
|
||||
}
|
||||
|
|
|
@ -28,9 +28,7 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
|
||||
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
|
||||
|
||||
/**
|
||||
* An implementation of the <tt>Batcher</tt> interface that
|
||||
|
@ -39,12 +37,13 @@ import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
|
|||
*/
|
||||
public class BatchingBatcher extends AbstractBatcher {
|
||||
|
||||
private int batchSize;
|
||||
private Expectation[] expectations;
|
||||
|
||||
public BatchingBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
|
||||
super( connectionManager, interceptor );
|
||||
expectations = new Expectation[ getFactory().getSettings().getJdbcBatchSize() ];
|
||||
private int currentSize;
|
||||
public BatchingBatcher(SQLExceptionHelper exceptionHelper, int jdbcBatchSize) {
|
||||
super( exceptionHelper, jdbcBatchSize );
|
||||
expectations = new Expectation[ jdbcBatchSize ];
|
||||
currentSize = 0;
|
||||
}
|
||||
|
||||
public void addToBatch(Expectation expectation) throws SQLException, HibernateException {
|
||||
|
@ -53,19 +52,19 @@ public class BatchingBatcher extends AbstractBatcher {
|
|||
}
|
||||
PreparedStatement batchUpdate = getStatement();
|
||||
batchUpdate.addBatch();
|
||||
expectations[ batchSize++ ] = expectation;
|
||||
if ( batchSize == getFactory().getSettings().getJdbcBatchSize() ) {
|
||||
expectations[ currentSize++ ] = expectation;
|
||||
if ( currentSize == getJdbcBatchSize() ) {
|
||||
doExecuteBatch( batchUpdate );
|
||||
}
|
||||
}
|
||||
|
||||
protected void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException {
|
||||
if ( batchSize == 0 ) {
|
||||
if ( currentSize == 0 ) {
|
||||
log.debug( "no batched statements to execute" );
|
||||
}
|
||||
else {
|
||||
if ( log.isDebugEnabled() ) {
|
||||
log.debug( "Executing batch size: " + batchSize );
|
||||
log.debug( "Executing batch size: " + currentSize );
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -76,16 +75,15 @@ public class BatchingBatcher extends AbstractBatcher {
|
|||
throw re;
|
||||
}
|
||||
finally {
|
||||
batchSize = 0;
|
||||
currentSize = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void checkRowCounts(int[] rowCounts, PreparedStatement ps) throws SQLException, HibernateException {
|
||||
int numberOfRowCounts = rowCounts.length;
|
||||
if ( numberOfRowCounts != batchSize ) {
|
||||
if ( numberOfRowCounts != currentSize ) {
|
||||
log.warn( "JDBC driver did not return the expected number of row counts" );
|
||||
}
|
||||
for ( int i = 0; i < numberOfRowCounts; i++ ) {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
package org.hibernate.jdbc;
|
||||
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -35,8 +35,14 @@ import org.hibernate.Interceptor;
|
|||
*/
|
||||
public class BatchingBatcherFactory implements BatcherFactory {
|
||||
|
||||
public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
|
||||
return new BatchingBatcher( connectionManager, interceptor );
|
||||
private int jdbcBatchSize;
|
||||
|
||||
public void setJdbcBatchSize(int jdbcBatchSize) {
|
||||
this.jdbcBatchSize = jdbcBatchSize;
|
||||
}
|
||||
|
||||
public Batcher createBatcher(SQLExceptionHelper exceptionHelper) {
|
||||
return new BatchingBatcher( exceptionHelper, jdbcBatchSize );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,9 +28,7 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
|
||||
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
|
||||
|
||||
/**
|
||||
* An implementation of the <tt>Batcher</tt> interface that does no batching
|
||||
|
@ -39,8 +37,8 @@ import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
|
|||
*/
|
||||
public class NonBatchingBatcher extends AbstractBatcher {
|
||||
|
||||
public NonBatchingBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
|
||||
super( connectionManager, interceptor );
|
||||
public NonBatchingBatcher(SQLExceptionHelper exceptionHelper) {
|
||||
super( exceptionHelper, 1 );
|
||||
}
|
||||
|
||||
public void addToBatch(Expectation expectation) throws SQLException, HibernateException {
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
*/
|
||||
package org.hibernate.jdbc;
|
||||
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -35,8 +36,14 @@ import org.hibernate.Interceptor;
|
|||
*/
|
||||
public class NonBatchingBatcherFactory implements BatcherFactory {
|
||||
|
||||
public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
|
||||
return new NonBatchingBatcher( connectionManager, interceptor );
|
||||
public void setJdbcBatchSize(int jdbcBatchSize) {
|
||||
if ( jdbcBatchSize > 1 ) {
|
||||
throw new AssertionFailure( "jdbcBatchSize must be 1 for " + getClass().getName() );
|
||||
}
|
||||
}
|
||||
|
||||
public Batcher createBatcher(SQLExceptionHelper exceptionHelper) {
|
||||
return new NonBatchingBatcher( exceptionHelper );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ import org.hibernate.engine.jdbc.ColumnNameCache;
|
|||
import org.hibernate.event.EventSource;
|
||||
import org.hibernate.event.PostLoadEvent;
|
||||
import org.hibernate.event.PreLoadEvent;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.hql.HolderInstantiator;
|
||||
import org.hibernate.impl.FetchingScrollableResultsImpl;
|
||||
import org.hibernate.impl.ScrollableResultsImpl;
|
||||
|
@ -891,7 +890,7 @@ public abstract class Loader {
|
|||
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeQueryStatement( st, rs );
|
||||
st.close();
|
||||
}
|
||||
|
||||
initializeEntitiesAndCollections( hydratedObjects, rs, session, queryParameters.isReadOnly( session ) );
|
||||
|
@ -1749,16 +1748,12 @@ public abstract class Loader {
|
|||
sql = preprocessSQL( sql, queryParameters, dialect );
|
||||
|
||||
PreparedStatement st = null;
|
||||
|
||||
if (callable) {
|
||||
st = session.getBatcher()
|
||||
.prepareCallableQueryStatement( sql, scroll || useScrollableResultSetToSkip, scrollMode );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher()
|
||||
.prepareQueryStatement( sql, scroll || useScrollableResultSetToSkip, scrollMode );
|
||||
}
|
||||
|
||||
|
||||
st = (
|
||||
scroll || useScrollableResultSetToSkip ?
|
||||
session.getJDBCContext().getConnectionManager().prepareScrollableQueryStatement( sql, scrollMode, callable ) :
|
||||
session.getJDBCContext().getConnectionManager().prepareQueryStatement( sql, callable )
|
||||
);
|
||||
|
||||
try {
|
||||
|
||||
|
@ -1809,11 +1804,11 @@ public abstract class Loader {
|
|||
log.trace( "Bound [" + col + "] parameters total" );
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
session.getBatcher().closeQueryStatement( st, null );
|
||||
st.close();
|
||||
throw sqle;
|
||||
}
|
||||
catch ( HibernateException he ) {
|
||||
session.getBatcher().closeQueryStatement( st, null );
|
||||
st.close();
|
||||
throw he;
|
||||
}
|
||||
|
||||
|
@ -2004,12 +1999,7 @@ public abstract class Loader {
|
|||
ResultSet rs = null;
|
||||
try {
|
||||
Dialect dialect = getFactory().getDialect();
|
||||
if (callable) {
|
||||
rs = session.getBatcher().getResultSet( (CallableStatement) st, dialect );
|
||||
}
|
||||
else {
|
||||
rs = session.getBatcher().getResultSet( st );
|
||||
}
|
||||
rs = st.executeQuery();
|
||||
rs = wrapResultSetIfEnabled( rs , session );
|
||||
|
||||
if ( !dialect.supportsLimitOffset() || !useLimit( selection, dialect ) ) {
|
||||
|
@ -2022,7 +2012,7 @@ public abstract class Loader {
|
|||
return rs;
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
session.getBatcher().closeQueryStatement( st, rs );
|
||||
st.close();
|
||||
throw sqle;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@ import org.hibernate.engine.SessionFactoryImplementor;
|
|||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.engine.SubselectFetch;
|
||||
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.exception.SQLExceptionConverter;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.jdbc.Expectation;
|
||||
|
@ -1084,20 +1083,10 @@ public abstract class AbstractCollectionPersister
|
|||
boolean useBatch = expectation.canBeBatched();
|
||||
String sql = getSQLDeleteString();
|
||||
if ( useBatch ) {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareBatchCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareBatchStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1106,7 +1095,7 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
writeKey( st, id, offset, session );
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().addToBatch( expectation );
|
||||
session.getJDBCContext().getConnectionManager().addToBatch( expectation );
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
|
||||
|
@ -1114,13 +1103,13 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().abortBatch( sqle );
|
||||
session.getJDBCContext().getConnectionManager().abortBatch( sqle );
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1172,20 +1161,10 @@ public abstract class AbstractCollectionPersister
|
|||
String sql = getSQLInsertRowString();
|
||||
|
||||
if ( useBatch ) {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareBatchCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareBatchStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1203,7 +1182,7 @@ public abstract class AbstractCollectionPersister
|
|||
loc = writeElement(st, collection.getElement(entry), loc, session );
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().addToBatch( expectation );
|
||||
session.getJDBCContext().getConnectionManager().addToBatch( expectation );
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
|
||||
|
@ -1214,13 +1193,13 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().abortBatch( sqle );
|
||||
session.getJDBCContext().getConnectionManager().abortBatch( sqle );
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1282,20 +1261,10 @@ public abstract class AbstractCollectionPersister
|
|||
String sql = getSQLDeleteRowString();
|
||||
|
||||
if ( useBatch ) {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareBatchCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareBatchStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -1317,7 +1286,7 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().addToBatch( expectation );
|
||||
session.getJDBCContext().getConnectionManager().addToBatch( expectation );
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
|
||||
|
@ -1326,13 +1295,13 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().abortBatch( sqle );
|
||||
session.getJDBCContext().getConnectionManager().abortBatch( sqle );
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1392,21 +1361,11 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
if ( useBatch ) {
|
||||
if ( st == null ) {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareBatchCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareBatchStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareBatchStatement( sql, callable );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -1422,7 +1381,7 @@ public abstract class AbstractCollectionPersister
|
|||
writeElement(st, collection.getElement(entry), offset, session );
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().addToBatch( expectation );
|
||||
session.getJDBCContext().getConnectionManager().addToBatch( expectation );
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
|
||||
|
@ -1432,13 +1391,13 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().abortBatch( sqle );
|
||||
session.getJDBCContext().getConnectionManager().abortBatch( sqle );
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1744,7 +1703,7 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
public int getSize(Serializable key, SessionImplementor session) {
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement(sqlSelectSizeString);
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement(sqlSelectSizeString);
|
||||
try {
|
||||
getKeyType().nullSafeSet(st, key, 1, session);
|
||||
ResultSet rs = st.executeQuery();
|
||||
|
@ -1756,7 +1715,7 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
|
@ -1779,7 +1738,7 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
private boolean exists(Serializable key, Object indexOrElement, Type indexOrElementType, String sql, SessionImplementor session) {
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement(sql);
|
||||
try {
|
||||
getKeyType().nullSafeSet(st, key, 1, session);
|
||||
indexOrElementType.nullSafeSet( st, indexOrElement, keyColumnNames.length + 1, session );
|
||||
|
@ -1795,7 +1754,7 @@ public abstract class AbstractCollectionPersister
|
|||
return false;
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
|
@ -1810,7 +1769,7 @@ public abstract class AbstractCollectionPersister
|
|||
|
||||
public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner) {
|
||||
try {
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement(sqlSelectRowByIndexString);
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement(sqlSelectRowByIndexString);
|
||||
try {
|
||||
getKeyType().nullSafeSet(st, key, 1, session);
|
||||
getIndexType().nullSafeSet( st, incrementIndexByBase(index), keyColumnNames.length + 1, session );
|
||||
|
@ -1828,7 +1787,7 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
|
|
|
@ -39,7 +39,6 @@ import org.hibernate.engine.SessionFactoryImplementor;
|
|||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.engine.SubselectFetch;
|
||||
import org.hibernate.engine.LoadQueryInfluencers;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.jdbc.Expectation;
|
||||
import org.hibernate.jdbc.Expectations;
|
||||
import org.hibernate.loader.collection.BatchingCollectionInitializer;
|
||||
|
@ -212,21 +211,11 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
|
|||
|
||||
if ( useBatch ) {
|
||||
if ( st == null ) {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareBatchCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareBatchStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareBatchStatement( sql, callable );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -246,7 +235,7 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
|
|||
}
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().addToBatch( expectation );
|
||||
session.getJDBCContext().getConnectionManager().addToBatch( expectation );
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
|
||||
|
@ -254,13 +243,13 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().abortBatch( sqle );
|
||||
session.getJDBCContext().getConnectionManager().abortBatch( sqle );
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
count++;
|
||||
|
|
|
@ -39,7 +39,6 @@ import org.hibernate.engine.SessionFactoryImplementor;
|
|||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.engine.SubselectFetch;
|
||||
import org.hibernate.engine.LoadQueryInfluencers;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.jdbc.Expectation;
|
||||
import org.hibernate.jdbc.Expectations;
|
||||
import org.hibernate.loader.collection.BatchingCollectionInitializer;
|
||||
|
@ -203,18 +202,21 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
expectation = Expectations.appropriateExpectation( getDeleteCheckStyle() );
|
||||
useBatch = expectation.canBeBatched();
|
||||
st = useBatch
|
||||
? session.getBatcher().prepareBatchCallableStatement( sql )
|
||||
: session.getBatcher().prepareCallableStatement( sql );
|
||||
? session.getJDBCContext().getConnectionManager().prepareBatchStatement( sql, true )
|
||||
: session.getJDBCContext().getConnectionManager().prepareStatement( sql, true );
|
||||
offset += expectation.prepare( st );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareBatchStatement( getSQLDeleteRowString() );
|
||||
st = session.getJDBCContext().getConnectionManager().prepareBatchStatement(
|
||||
getSQLDeleteRowString(),
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
int loc = writeKey( st, id, offset, session );
|
||||
writeElementToWhere( st, collection.getSnapshotElement(entry, i), loc, session );
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().addToBatch( expectation );
|
||||
session.getJDBCContext().getConnectionManager().addToBatch( expectation );
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
|
||||
|
@ -226,13 +228,13 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().abortBatch( sqle );
|
||||
session.getJDBCContext().getConnectionManager().abortBatch( sqle );
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,21 +255,11 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
if ( collection.needsUpdating( entry, i, elementType ) ) {
|
||||
if ( useBatch ) {
|
||||
if ( st == null ) {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareBatchCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareBatchStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareBatchStatement( sql, callable );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( callable ) {
|
||||
st = session.getBatcher().prepareCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
st = session.getBatcher().prepareStatement( sql );
|
||||
}
|
||||
st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
|
||||
}
|
||||
|
||||
offset += expectation.prepare( st );
|
||||
|
@ -280,7 +272,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
writeElementToWhere( st, collection.getElement( entry ), loc, session );
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().addToBatch( expectation );
|
||||
session.getJDBCContext().getConnectionManager().addToBatch( expectation );
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
|
||||
|
@ -292,13 +284,13 @@ public class OneToManyPersister extends AbstractCollectionPersister {
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().abortBatch( sqle );
|
||||
session.getJDBCContext().getConnectionManager().abortBatch( sqle );
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ import org.hibernate.engine.SessionFactoryImplementor;
|
|||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.engine.ValueInclusion;
|
||||
import org.hibernate.engine.Versioning;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.PostInsertIdentifierGenerator;
|
||||
import org.hibernate.id.PostInsertIdentityPersister;
|
||||
|
@ -843,7 +842,7 @@ public abstract class AbstractEntityPersister
|
|||
// null sql means that the only lazy properties
|
||||
// are shared PK one-to-one associations which are
|
||||
// handled differently in the Type#nullSafeGet code...
|
||||
ps = session.getBatcher().prepareSelectStatement(lazySelect);
|
||||
ps = session.getJDBCContext().getConnectionManager().prepareSelectStatement(lazySelect);
|
||||
getIdentifierType().nullSafeSet( ps, id, 1, session );
|
||||
rs = ps.executeQuery();
|
||||
rs.next();
|
||||
|
@ -864,7 +863,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1090,7 +1089,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
try {
|
||||
PreparedStatement ps = session.getBatcher().prepareSelectStatement( getSQLSnapshotSelectString() );
|
||||
PreparedStatement ps = session.getJDBCContext().getConnectionManager().prepareSelectStatement( getSQLSnapshotSelectString() );
|
||||
try {
|
||||
getIdentifierType().nullSafeSet( ps, id, 1, session );
|
||||
//if ( isVersioned() ) getVersionType().nullSafeSet( ps, version, getIdentifierColumnSpan()+1, session );
|
||||
|
@ -1117,7 +1116,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
|
@ -1301,7 +1300,7 @@ public abstract class AbstractEntityPersister
|
|||
PreparedStatement st = null;
|
||||
try {
|
||||
try {
|
||||
st = session.getBatcher().prepareStatement( versionIncrementString );
|
||||
st = session.getJDBCContext().getConnectionManager().prepareStatement( versionIncrementString, false );
|
||||
getVersionType().nullSafeSet( st, nextVersion, 1, session );
|
||||
getIdentifierType().nullSafeSet( st, id, 2, session );
|
||||
getVersionType().nullSafeSet( st, currentVersion, 2 + getIdentifierColumnSpan(), session );
|
||||
|
@ -1311,7 +1310,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
|
@ -1349,7 +1348,7 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
try {
|
||||
|
||||
PreparedStatement st = session.getBatcher().prepareSelectStatement( getVersionSelectString() );
|
||||
PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( getVersionSelectString() );
|
||||
try {
|
||||
getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
|
||||
|
@ -1368,7 +1367,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( st );
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2208,7 +2207,7 @@ public abstract class AbstractEntityPersister
|
|||
final String sql = rootPersister.getSequentialSelect( getEntityName() );
|
||||
if ( sql != null ) {
|
||||
//TODO: I am not so sure about the exception handling in this bit!
|
||||
sequentialSelect = session.getBatcher().prepareSelectStatement( sql );
|
||||
sequentialSelect = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
rootPersister.getIdentifierType().nullSafeSet( sequentialSelect, id, 1, session );
|
||||
sequentialResultSet = sequentialSelect.executeQuery();
|
||||
if ( !sequentialResultSet.next() ) {
|
||||
|
@ -2275,7 +2274,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
finally {
|
||||
if ( sequentialSelect != null ) {
|
||||
session.getBatcher().closeStatement( sequentialSelect );
|
||||
sequentialSelect.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2382,20 +2381,10 @@ public abstract class AbstractEntityPersister
|
|||
// Render the SQL query
|
||||
final PreparedStatement insert;
|
||||
if ( useBatch ) {
|
||||
if ( callable ) {
|
||||
insert = session.getBatcher().prepareBatchCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
insert = session.getBatcher().prepareBatchStatement( sql );
|
||||
}
|
||||
insert = session.getJDBCContext().getConnectionManager().prepareBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
if ( callable ) {
|
||||
insert = session.getBatcher().prepareCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
insert = session.getBatcher().prepareStatement( sql );
|
||||
}
|
||||
insert = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -2409,7 +2398,7 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
if ( useBatch ) {
|
||||
// TODO : shouldnt inserts be Expectations.NONE?
|
||||
session.getBatcher().addToBatch( expectation );
|
||||
session.getJDBCContext().getConnectionManager().addToBatch( expectation );
|
||||
}
|
||||
else {
|
||||
expectation.verifyOutcome( insert.executeUpdate(), insert, -1 );
|
||||
|
@ -2418,13 +2407,13 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().abortBatch( sqle );
|
||||
session.getJDBCContext().getConnectionManager().abortBatch( sqle );
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getBatcher().closeStatement( insert );
|
||||
insert.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2511,20 +2500,10 @@ public abstract class AbstractEntityPersister
|
|||
int index = 1; // starting index
|
||||
final PreparedStatement update;
|
||||
if ( useBatch ) {
|
||||
if ( callable ) {
|
||||
update = session.getBatcher().prepareBatchCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
update = session.getBatcher().prepareBatchStatement( sql );
|
||||
}
|
||||
update = session.getJDBCContext().getConnectionManager().prepareBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
if ( callable ) {
|
||||
update = session.getBatcher().prepareCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
update = session.getBatcher().prepareStatement( sql );
|
||||
}
|
||||
update = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -2564,7 +2543,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().addToBatch( expectation );
|
||||
session.getJDBCContext().getConnectionManager().addToBatch( expectation );
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
@ -2574,13 +2553,13 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().abortBatch( sqle );
|
||||
session.getJDBCContext().getConnectionManager().abortBatch( sqle );
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getBatcher().closeStatement( update );
|
||||
update.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2635,20 +2614,10 @@ public abstract class AbstractEntityPersister
|
|||
PreparedStatement delete;
|
||||
int index = 1;
|
||||
if ( useBatch ) {
|
||||
if ( callable ) {
|
||||
delete = session.getBatcher().prepareBatchCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
delete = session.getBatcher().prepareBatchStatement( sql );
|
||||
}
|
||||
delete = session.getJDBCContext().getConnectionManager().prepareBatchStatement( sql, callable );
|
||||
}
|
||||
else {
|
||||
if ( callable ) {
|
||||
delete = session.getBatcher().prepareCallableStatement( sql );
|
||||
}
|
||||
else {
|
||||
delete = session.getBatcher().prepareStatement( sql );
|
||||
}
|
||||
delete = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -2680,7 +2649,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().addToBatch( expectation );
|
||||
session.getJDBCContext().getConnectionManager().addToBatch( expectation );
|
||||
}
|
||||
else {
|
||||
check( delete.executeUpdate(), id, j, expectation, delete );
|
||||
|
@ -2689,13 +2658,13 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
catch ( SQLException sqle ) {
|
||||
if ( useBatch ) {
|
||||
session.getBatcher().abortBatch( sqle );
|
||||
session.getJDBCContext().getConnectionManager().abortBatch( sqle );
|
||||
}
|
||||
throw sqle;
|
||||
}
|
||||
finally {
|
||||
if ( !useBatch ) {
|
||||
session.getBatcher().closeStatement( delete );
|
||||
delete.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3965,10 +3934,10 @@ public abstract class AbstractEntityPersister
|
|||
String selectionSQL,
|
||||
ValueInclusion[] includeds) {
|
||||
|
||||
session.getBatcher().executeBatch(); //force immediate execution of the insert
|
||||
session.getJDBCContext().getConnectionManager().executeBatch(); //force immediate execution of the insert
|
||||
|
||||
try {
|
||||
PreparedStatement ps = session.getBatcher().prepareSelectStatement( selectionSQL );
|
||||
PreparedStatement ps = session.getJDBCContext().getConnectionManager().prepareSelectStatement( selectionSQL );
|
||||
try {
|
||||
getIdentifierType().nullSafeSet( ps, id, 1, session );
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
@ -3994,7 +3963,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
catch( SQLException sqle ) {
|
||||
|
@ -4064,7 +4033,7 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
Object[] snapshot = new Object[ naturalIdPropertyCount ];
|
||||
try {
|
||||
PreparedStatement ps = session.getBatcher().prepareSelectStatement( sql );
|
||||
PreparedStatement ps = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
|
||||
try {
|
||||
getIdentifierType().nullSafeSet( ps, id, 1, session );
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
@ -4089,7 +4058,7 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
}
|
||||
finally {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
|
|
|
@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.util.JTAHelper;
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,8 +30,8 @@ import org.hibernate.ConnectionReleaseMode;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.util.JTAHelper;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
|
||||
import javax.transaction.SystemException;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.util.JTAHelper;
|
||||
|
||||
/**
|
||||
|
@ -53,7 +53,7 @@ public final class CacheSynchronization implements Synchronization {
|
|||
|
||||
public CacheSynchronization(
|
||||
TransactionFactory.Context ctx,
|
||||
JDBCContext jdbcContext,
|
||||
JDBCContext jdbcContext,
|
||||
Transaction transaction,
|
||||
org.hibernate.Transaction tx) {
|
||||
this.ctx = ctx;
|
||||
|
|
|
@ -33,8 +33,8 @@ import org.slf4j.LoggerFactory;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.engine.transaction.SynchronizationRegistry;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
|
||||
/**
|
||||
* {@link Transaction} implementation based on transaction management through a JDBC {@link java.sql.Connection}.
|
||||
|
@ -100,7 +100,6 @@ public class JDBCTransaction implements Transaction {
|
|||
|
||||
if ( timeout>0 ) {
|
||||
jdbcContext.getConnectionManager()
|
||||
.getBatcher()
|
||||
.setTransactionTimeout(timeout);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ import java.util.Properties;
|
|||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
|
||||
/**
|
||||
* Factory for {@link JDBCTransaction} instances.
|
||||
|
|
|
@ -36,7 +36,7 @@ import org.slf4j.LoggerFactory;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.util.JTAHelper;
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,8 +38,8 @@ import org.hibernate.ConnectionReleaseMode;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.internal.util.jndi.JndiHelper;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.util.JTAHelper;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import org.hibernate.ConnectionReleaseMode;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
|
||||
/**
|
||||
* Contract for generating Hibernate {@link Transaction} instances.
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
package org.hibernate.transaction.synchronization;
|
||||
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
import javax.transaction.Status;
|
||||
import javax.transaction.SystemException;
|
||||
import javax.transaction.Transaction;
|
||||
|
@ -31,9 +30,8 @@ import javax.transaction.Transaction;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.transaction.TransactionFactory;
|
||||
import org.hibernate.util.JTAHelper;
|
||||
|
||||
|
@ -158,7 +156,8 @@ public class CallbackCoordinator {
|
|||
private static final BeforeCompletionManagedFlushChecker STANDARD_MANAGED_FLUSH_CHECKER = new BeforeCompletionManagedFlushChecker() {
|
||||
public boolean shouldDoManagedFlush(TransactionFactory.Context ctx, Transaction jtaTransaction)
|
||||
throws SystemException {
|
||||
return !ctx.isFlushModeNever() &&
|
||||
return !ctx.isClosed() &&
|
||||
!ctx.isFlushModeNever() &&
|
||||
ctx.isFlushBeforeCompletionEnabled() &&
|
||||
!JTAHelper.isRollback( jtaTransaction.getStatus() );
|
||||
//actually, this last test is probably unnecessary, since
|
||||
|
|
|
@ -32,7 +32,6 @@ import java.util.Date;
|
|||
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.exception.JDBCExceptionHelper;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -90,8 +89,8 @@ public class DbTimestampType extends TimestampType {
|
|||
private Timestamp usePreparedStatement(String timestampSelectString, SessionImplementor session) {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = session.getBatcher().prepareStatement( timestampSelectString );
|
||||
ResultSet rs = session.getBatcher().getResultSet( ps );
|
||||
ps = session.getJDBCContext().getConnectionManager().prepareStatement( timestampSelectString, false );
|
||||
ResultSet rs = ps.executeQuery();
|
||||
rs.next();
|
||||
Timestamp ts = rs.getTimestamp( 1 );
|
||||
if ( log.isTraceEnabled() ) {
|
||||
|
@ -113,7 +112,7 @@ public class DbTimestampType extends TimestampType {
|
|||
finally {
|
||||
if ( ps != null ) {
|
||||
try {
|
||||
session.getBatcher().closeStatement( ps );
|
||||
ps.close();
|
||||
}
|
||||
catch( SQLException sqle ) {
|
||||
log.warn( "unable to clean up prepared statement", sqle );
|
||||
|
@ -125,7 +124,7 @@ public class DbTimestampType extends TimestampType {
|
|||
private Timestamp useCallableStatement(String callString, SessionImplementor session) {
|
||||
CallableStatement cs = null;
|
||||
try {
|
||||
cs = session.getBatcher().prepareCallableStatement( callString );
|
||||
cs = session.getJDBCContext().getConnectionManager().prepareCallableStatement( callString );
|
||||
cs.registerOutParameter( 1, java.sql.Types.TIMESTAMP );
|
||||
cs.execute();
|
||||
Timestamp ts = cs.getTimestamp( 1 );
|
||||
|
@ -148,7 +147,7 @@ public class DbTimestampType extends TimestampType {
|
|||
finally {
|
||||
if ( cs != null ) {
|
||||
try {
|
||||
session.getBatcher().closeStatement( cs );
|
||||
cs.close();
|
||||
}
|
||||
catch( SQLException sqle ) {
|
||||
log.warn( "unable to clean up callable statement", sqle );
|
||||
|
|
|
@ -8,15 +8,14 @@ import java.sql.PreparedStatement;
|
|||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
|
||||
import org.hibernate.testing.junit.functional.FunctionalTestCase;
|
||||
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.jdbc.BatchingBatcher;
|
||||
import org.hibernate.jdbc.ConnectionManager;
|
||||
import org.hibernate.jdbc.Expectation;
|
||||
import org.hibernate.jdbc.BatcherFactory;
|
||||
import org.hibernate.jdbc.Batcher;
|
||||
|
@ -61,7 +60,7 @@ public class InsertOrderingTest extends FunctionalTestCase {
|
|||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertEquals( 6, StatsBatcher.batchSizes.size() ); // 2 batches of each insert statement
|
||||
assertEquals( 3, StatsBatcher.batchSizes.size() );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
|
@ -82,8 +81,8 @@ public class InsertOrderingTest extends FunctionalTestCase {
|
|||
private static List batchSizes = new ArrayList();
|
||||
private static int currentBatch = -1;
|
||||
|
||||
public StatsBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
|
||||
super( connectionManager, interceptor );
|
||||
public StatsBatcher(SQLExceptionHelper exceptionHelper, int jdbcBatchSize) {
|
||||
super( exceptionHelper, jdbcBatchSize );
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
|
@ -92,16 +91,15 @@ public class InsertOrderingTest extends FunctionalTestCase {
|
|||
batchSQL = null;
|
||||
}
|
||||
|
||||
public PreparedStatement prepareBatchStatement(String sql) throws SQLException {
|
||||
PreparedStatement rtn = super.prepareBatchStatement( sql );
|
||||
if ( batchSQL == null || !batchSQL.equals( sql ) ) {
|
||||
public void setStatement(String sql, PreparedStatement ps) {
|
||||
if ( batchSQL == null || ! batchSQL.equals( sql ) ) {
|
||||
currentBatch++;
|
||||
batchSQL = sql;
|
||||
batchSizes.add( currentBatch, new Counter() );
|
||||
System.out.println( "--------------------------------------------------------" );
|
||||
System.out.println( "Preparing statement [" + sql + "]" );
|
||||
}
|
||||
return rtn;
|
||||
super.setStatement( sql, ps );
|
||||
}
|
||||
|
||||
public void addToBatch(Expectation expectation) throws SQLException, HibernateException {
|
||||
|
@ -114,14 +112,18 @@ public class InsertOrderingTest extends FunctionalTestCase {
|
|||
protected void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException {
|
||||
System.out.println( "executing batch [" + batchSQL + "]" );
|
||||
System.out.println( "--------------------------------------------------------" );
|
||||
batchSQL = null;
|
||||
super.doExecuteBatch( ps );
|
||||
}
|
||||
}
|
||||
|
||||
public static class StatsBatcherFactory implements BatcherFactory {
|
||||
public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
|
||||
return new StatsBatcher( connectionManager, interceptor );
|
||||
private int jdbcBatchSize;
|
||||
|
||||
public void setJdbcBatchSize(int jdbcBatchSize) {
|
||||
this.jdbcBatchSize = jdbcBatchSize;
|
||||
}
|
||||
public Batcher createBatcher(SQLExceptionHelper exceptionHelper) {
|
||||
return new StatsBatcher( exceptionHelper, jdbcBatchSize );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.hibernate.ConnectionReleaseMode;
|
|||
import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionObserver;
|
||||
import org.hibernate.engine.jdbc.internal.proxy.ProxyBuilder;
|
||||
import org.hibernate.stat.ConcurrentStatisticsImpl;
|
||||
import org.hibernate.jdbc.NonBatchingBatcherFactory;
|
||||
import org.hibernate.test.common.BasicTestingJdbcServiceImpl;
|
||||
import org.hibernate.testing.junit.UnitTestCase;
|
||||
|
||||
|
@ -131,7 +131,13 @@ public class AggressiveReleaseTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
public void testBasicRelease() {
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_STATEMENT, services );
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
|
||||
null,
|
||||
ConnectionReleaseMode.AFTER_STATEMENT,
|
||||
services,
|
||||
null,
|
||||
new NonBatchingBatcherFactory()
|
||||
);
|
||||
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
|
||||
ConnectionCounter observer = new ConnectionCounter();
|
||||
logicalConnection.addObserver( observer );
|
||||
|
@ -160,7 +166,13 @@ public class AggressiveReleaseTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
public void testReleaseCircumventedByHeldResources() {
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_STATEMENT, services );
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
|
||||
null,
|
||||
ConnectionReleaseMode.AFTER_STATEMENT,
|
||||
services,
|
||||
null,
|
||||
new NonBatchingBatcherFactory()
|
||||
);
|
||||
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
|
||||
ConnectionCounter observer = new ConnectionCounter();
|
||||
logicalConnection.addObserver( observer );
|
||||
|
@ -182,6 +194,7 @@ public class AggressiveReleaseTest extends UnitTestCase {
|
|||
ps = proxiedConnection.prepareStatement( "select * from SANDBOX_JDBC_TST" );
|
||||
ps.executeQuery();
|
||||
assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
|
||||
assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
|
||||
assertEquals( 2, observer.obtainCount );
|
||||
assertEquals( 1, observer.releaseCount );
|
||||
|
||||
|
@ -213,7 +226,13 @@ public class AggressiveReleaseTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
public void testReleaseCircumventedManually() {
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_STATEMENT, services );
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
|
||||
null,
|
||||
ConnectionReleaseMode.AFTER_STATEMENT,
|
||||
services,
|
||||
null,
|
||||
new NonBatchingBatcherFactory()
|
||||
);
|
||||
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
|
||||
ConnectionCounter observer = new ConnectionCounter();
|
||||
logicalConnection.addObserver( observer );
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.ConnectionReleaseMode;
|
|||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
|
||||
import org.hibernate.engine.jdbc.internal.proxy.ProxyBuilder;
|
||||
import org.hibernate.jdbc.NonBatchingBatcherFactory;
|
||||
import org.hibernate.test.common.BasicTestingJdbcServiceImpl;
|
||||
import org.hibernate.testing.junit.UnitTestCase;
|
||||
|
||||
|
@ -58,7 +59,13 @@ public class BasicConnectionProxyTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
public void testDatabaseMetaDataHandling() throws Throwable {
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_TRANSACTION, services );
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
|
||||
null,
|
||||
ConnectionReleaseMode.AFTER_TRANSACTION,
|
||||
services,
|
||||
null,
|
||||
new NonBatchingBatcherFactory()
|
||||
);
|
||||
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
|
||||
try {
|
||||
DatabaseMetaData metaData = proxiedConnection.getMetaData();
|
||||
|
@ -81,7 +88,13 @@ public class BasicConnectionProxyTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
public void testExceptionHandling() {
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_TRANSACTION, services );
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
|
||||
null,
|
||||
ConnectionReleaseMode.AFTER_TRANSACTION,
|
||||
services,
|
||||
null,
|
||||
new NonBatchingBatcherFactory()
|
||||
);
|
||||
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
|
||||
try {
|
||||
proxiedConnection.prepareStatement( "select count(*) from NON_EXISTENT" ).executeQuery();
|
||||
|
@ -98,7 +111,13 @@ public class BasicConnectionProxyTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
public void testBasicJdbcUsage() throws JDBCException {
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_TRANSACTION, services );
|
||||
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
|
||||
null,
|
||||
ConnectionReleaseMode.AFTER_TRANSACTION,
|
||||
services,
|
||||
null,
|
||||
new NonBatchingBatcherFactory()
|
||||
);
|
||||
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
|
||||
|
||||
try {
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.List;
|
|||
import junit.framework.Test;
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
|
||||
import org.hibernate.testing.junit.functional.FunctionalTestCase;
|
||||
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
|
@ -37,7 +38,6 @@ import org.hibernate.EmptyInterceptor;
|
|||
import org.hibernate.jdbc.BatcherFactory;
|
||||
import org.hibernate.jdbc.NonBatchingBatcher;
|
||||
import org.hibernate.jdbc.Batcher;
|
||||
import org.hibernate.jdbc.ConnectionManager;
|
||||
import org.hibernate.stat.CollectionStatistics;
|
||||
import org.hibernate.loader.collection.BatchingCollectionInitializer;
|
||||
import org.hibernate.persister.collection.AbstractCollectionPersister;
|
||||
|
@ -68,16 +68,20 @@ public class BatchedManyToManyTest extends FunctionalTestCase {
|
|||
}
|
||||
|
||||
public static class TestingBatcherFactory implements BatcherFactory {
|
||||
public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
|
||||
return new TestingBatcher( connectionManager, interceptor );
|
||||
private int jdbcBatchSize;
|
||||
|
||||
public void setJdbcBatchSize(int jdbcBatchSize) {
|
||||
this.jdbcBatchSize = jdbcBatchSize;
|
||||
}
|
||||
public Batcher createBatcher(SQLExceptionHelper exceptionHelper) {
|
||||
return new TestingBatcher( exceptionHelper, jdbcBatchSize );
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestingBatcher extends NonBatchingBatcher {
|
||||
public TestingBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
|
||||
super( connectionManager, interceptor );
|
||||
public TestingBatcher(SQLExceptionHelper exceptionHelper, int jdbcBatchSize) {
|
||||
super( exceptionHelper );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testProperLoaderSetup() {
|
||||
|
|
|
@ -8,6 +8,7 @@ log4j.rootLogger=info, stdout
|
|||
|
||||
log4j.logger.org.hibernate.test=info
|
||||
log4j.logger.org.hibernate.tool.hbm2ddl=debug
|
||||
log4j.logger.org.hibernate.engine.jdbc=trace
|
||||
log4j.logger.org.hibernate.hql.ast.QueryTranslatorImpl=trace
|
||||
log4j.logger.org.hibernate.hql.ast.HqlSqlWalker=trace
|
||||
log4j.logger.org.hibernate.hql.ast.SqlGenerator=trace
|
||||
|
|
|
@ -26,7 +26,7 @@ import javax.transaction.Transaction;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.transaction.CMTTransaction;
|
||||
import org.hibernate.transaction.TransactionFactory;
|
||||
import org.hibernate.util.JTAHelper;
|
||||
|
|
|
@ -23,7 +23,7 @@ package org.hibernate.ejb.transaction;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.transaction.CMTTransactionFactory;
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,11 +46,10 @@ import org.hibernate.engine.QueryParameters;
|
|||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.engine.NonFlushedChanges;
|
||||
import org.hibernate.engine.jdbc.spi.JDBCContext;
|
||||
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
|
||||
import org.hibernate.event.EventListeners;
|
||||
import org.hibernate.impl.CriteriaImpl;
|
||||
import org.hibernate.jdbc.Batcher;
|
||||
import org.hibernate.jdbc.JDBCContext;
|
||||
import org.hibernate.loader.custom.CustomQuery;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.Type;
|
||||
|
@ -105,10 +104,6 @@ public abstract class AbstractDelegateSessionImplementor implements SessionImple
|
|||
return delegate.getFactory();
|
||||
}
|
||||
|
||||
public Batcher getBatcher() {
|
||||
return delegate.getBatcher();
|
||||
}
|
||||
|
||||
public List list(String query, QueryParameters queryParameters) throws HibernateException {
|
||||
return delegate.list(query, queryParameters);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue