HHH-6010 : Remove duplication in code involving Work and ReturningWork
This commit is contained in:
parent
53bc7d1bb4
commit
b30ff014ad
|
@ -25,6 +25,8 @@
|
||||||
package org.hibernate;
|
package org.hibernate;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
|
||||||
|
import org.hibernate.jdbc.ReturningWork;
|
||||||
import org.hibernate.jdbc.Work;
|
import org.hibernate.jdbc.Work;
|
||||||
import org.hibernate.stat.SessionStatistics;
|
import org.hibernate.stat.SessionStatistics;
|
||||||
|
|
||||||
|
@ -917,6 +919,17 @@ public interface Session extends Serializable {
|
||||||
*/
|
*/
|
||||||
public void doWork(Work work) throws HibernateException;
|
public void doWork(Work work) throws HibernateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for allowing users to perform JDBC related work using the Connection
|
||||||
|
* managed by this Session, returning the result from calling <code>work.execute()</code>
|
||||||
|
* ({@link ReturningWork<T>.execute(Connection)}/
|
||||||
|
*
|
||||||
|
* @param work The work to be performed.
|
||||||
|
* @return the result from calling <code>work.execute()</code>.
|
||||||
|
* @throws HibernateException Generally indicates wrapped {@link java.sql.SQLException}
|
||||||
|
*/
|
||||||
|
public <T> T doReturningWork(ReturningWork<T> work) throws HibernateException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect the session from its underlying JDBC connection. This is intended for use in cases where the
|
* Disconnect the session from its underlying JDBC connection. This is intended for use in cases where the
|
||||||
* application has supplied the JDBC connection to the session and which require long-sessions (aka, conversations).
|
* application has supplied the JDBC connection to the session and which require long-sessions (aka, conversations).
|
||||||
|
|
|
@ -42,8 +42,9 @@ import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
|
||||||
import org.hibernate.engine.transaction.spi.TransactionContext;
|
import org.hibernate.engine.transaction.spi.TransactionContext;
|
||||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||||
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||||
import org.hibernate.jdbc.Work;
|
import org.hibernate.jdbc.WorkExecutor;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,32 +185,11 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void coordinateWork(Work work) {
|
|
||||||
Connection connection = getLogicalConnection().getDistinctConnectionProxy();
|
|
||||||
try {
|
|
||||||
work.execute( connection );
|
|
||||||
getLogicalConnection().afterStatementExecution();
|
|
||||||
}
|
|
||||||
catch ( SQLException e ) {
|
|
||||||
throw sqlExceptionHelper().convert( e, "error executing work" );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
if ( ! connection.isClosed() ) {
|
|
||||||
connection.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (SQLException e) {
|
|
||||||
LOG.debug("Error closing connection proxy", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T coordinateWork(ReturningWork<T> work) {
|
public <T> T coordinateWork(WorkExecutorVisitable<T> work) {
|
||||||
Connection connection = getLogicalConnection().getDistinctConnectionProxy();
|
Connection connection = getLogicalConnection().getDistinctConnectionProxy();
|
||||||
try {
|
try {
|
||||||
T result = work.execute( connection );
|
T result = work.accept( new WorkExecutor<T>(), connection );
|
||||||
getLogicalConnection().afterStatementExecution();
|
getLogicalConnection().afterStatementExecution();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,7 @@ package org.hibernate.engine.jdbc.spi;
|
||||||
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
||||||
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||||
import org.hibernate.id.IntegralDataTypeHolder;
|
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
|
||||||
import org.hibernate.jdbc.Work;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
@ -88,9 +86,7 @@ public interface JdbcCoordinator extends Serializable {
|
||||||
|
|
||||||
public void afterTransaction();
|
public void afterTransaction();
|
||||||
|
|
||||||
public void coordinateWork(Work work);
|
public <T> T coordinateWork(WorkExecutorVisitable<T> work);
|
||||||
|
|
||||||
public <T> T coordinateWork(ReturningWork<T> work);
|
|
||||||
|
|
||||||
public void executeBatch();
|
public void executeBatch();
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@ import org.hibernate.HibernateLogger;
|
||||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||||
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
||||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||||
import org.hibernate.jdbc.Work;
|
import org.hibernate.jdbc.WorkExecutor;
|
||||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public class JdbcIsolationDelegate implements IsolationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delegateWork(Work work, boolean transacted) throws HibernateException {
|
public <T> T delegateWork(WorkExecutorVisitable<T> work, boolean transacted) throws HibernateException {
|
||||||
boolean wasAutoCommit = false;
|
boolean wasAutoCommit = false;
|
||||||
try {
|
try {
|
||||||
// todo : should we use a connection proxy here?
|
// todo : should we use a connection proxy here?
|
||||||
|
@ -72,69 +72,7 @@ public class JdbcIsolationDelegate implements IsolationDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
work.execute( connection );
|
T result = work.accept( new WorkExecutor<T>(), connection );
|
||||||
|
|
||||||
if ( transacted ) {
|
|
||||||
connection.commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
try {
|
|
||||||
if ( transacted && !connection.isClosed() ) {
|
|
||||||
connection.rollback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( Exception ignore ) {
|
|
||||||
LOG.unableToRollbackConnection(ignore);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( e instanceof HibernateException ) {
|
|
||||||
throw (HibernateException) e;
|
|
||||||
}
|
|
||||||
else if ( e instanceof SQLException ) {
|
|
||||||
throw sqlExceptionHelper().convert( (SQLException) e, "error performing isolated work" );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new HibernateException( "error performing isolated work", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if ( transacted && wasAutoCommit ) {
|
|
||||||
try {
|
|
||||||
connection.setAutoCommit( true );
|
|
||||||
}
|
|
||||||
catch ( Exception ignore ) {
|
|
||||||
LOG.trace("was unable to reset connection back to auto-commit");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
connectionProvider().closeConnection( connection );
|
|
||||||
}
|
|
||||||
catch ( Exception ignore ) {
|
|
||||||
LOG.unableToReleaseIsolatedConnection(ignore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( SQLException sqle ) {
|
|
||||||
throw sqlExceptionHelper().convert( sqle, "unable to obtain isolated JDBC connection" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T delegateWork(ReturningWork<T> work, boolean transacted) throws HibernateException {
|
|
||||||
boolean wasAutoCommit = false;
|
|
||||||
try {
|
|
||||||
// todo : should we use a connection proxy here?
|
|
||||||
Connection connection = connectionProvider().getConnection();
|
|
||||||
try {
|
|
||||||
if ( transacted ) {
|
|
||||||
if ( connection.getAutoCommit() ) {
|
|
||||||
wasAutoCommit = true;
|
|
||||||
connection.setAutoCommit( false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T result = work.execute( connection );
|
|
||||||
|
|
||||||
if ( transacted ) {
|
if ( transacted ) {
|
||||||
connection.commit();
|
connection.commit();
|
||||||
|
|
|
@ -34,8 +34,8 @@ import org.hibernate.HibernateLogger;
|
||||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||||
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
||||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||||
import org.hibernate.jdbc.Work;
|
import org.hibernate.jdbc.WorkExecutor;
|
||||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -76,109 +76,7 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delegateWork(Work work, boolean transacted) throws HibernateException {
|
public <T> T delegateWork(WorkExecutorVisitable<T> work, boolean transacted) throws HibernateException {
|
||||||
TransactionManager transactionManager = transactionManager();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// First we suspend any current JTA transaction
|
|
||||||
Transaction surroundingTransaction = transactionManager.suspend();
|
|
||||||
LOG.debugf("Surrounding JTA transaction suspended [%s]", surroundingTransaction);
|
|
||||||
|
|
||||||
boolean hadProblems = false;
|
|
||||||
try {
|
|
||||||
// then perform the requested work
|
|
||||||
if ( transacted ) {
|
|
||||||
doTheWorkInNewTransaction( work, transactionManager );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
doTheWorkInNoTransaction( work );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( HibernateException e ) {
|
|
||||||
hadProblems = true;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
transactionManager.resume( surroundingTransaction );
|
|
||||||
LOG.debugf("Surrounding JTA transaction resumed [%s]", surroundingTransaction);
|
|
||||||
}
|
|
||||||
catch( Throwable t ) {
|
|
||||||
// if the actually work had an error use that, otherwise error based on t
|
|
||||||
if ( !hadProblems ) {
|
|
||||||
//noinspection ThrowFromFinallyBlock
|
|
||||||
throw new HibernateException( "Unable to resume previously suspended transaction", t );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( SystemException e ) {
|
|
||||||
throw new HibernateException( "Unable to suspend current JTA transaction", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doTheWorkInNewTransaction(Work work, TransactionManager transactionManager) {
|
|
||||||
try {
|
|
||||||
// start the new isolated transaction
|
|
||||||
transactionManager.begin();
|
|
||||||
|
|
||||||
try {
|
|
||||||
doTheWork( work );
|
|
||||||
// if everythign went ok, commit the isolated transaction
|
|
||||||
transactionManager.commit();
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
try {
|
|
||||||
transactionManager.rollback();
|
|
||||||
}
|
|
||||||
catch ( Exception ignore ) {
|
|
||||||
LOG.unableToRollbackIsolatedTransaction(e, ignore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( SystemException e ) {
|
|
||||||
throw new HibernateException( "Unable to start isolated transaction", e );
|
|
||||||
}
|
|
||||||
catch ( NotSupportedException e ) {
|
|
||||||
throw new HibernateException( "Unable to start isolated transaction", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doTheWorkInNoTransaction(Work work) {
|
|
||||||
doTheWork( work );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doTheWork(Work work) {
|
|
||||||
try {
|
|
||||||
// obtain our isolated connection
|
|
||||||
Connection connection = connectionProvider().getConnection();
|
|
||||||
try {
|
|
||||||
// do the actual work
|
|
||||||
work.execute( connection );
|
|
||||||
}
|
|
||||||
catch ( HibernateException e ) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
throw new HibernateException( "Unable to perform isolated work", e );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
// no matter what, release the connection (handle)
|
|
||||||
connectionProvider().closeConnection( connection );
|
|
||||||
}
|
|
||||||
catch ( Throwable ignore ) {
|
|
||||||
LOG.unableToReleaseIsolatedConnection(ignore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( SQLException sqle ) {
|
|
||||||
throw sqlExceptionHelper().convert( sqle, "unable to obtain isolated JDBC connection" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T delegateWork(ReturningWork<T> work, boolean transacted) throws HibernateException {
|
|
||||||
TransactionManager transactionManager = transactionManager();
|
TransactionManager transactionManager = transactionManager();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -203,7 +101,7 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
transactionManager.resume( surroundingTransaction );
|
transactionManager.resume( surroundingTransaction );
|
||||||
LOG.debugf("Surrounding JTA transaction resumed [%s]", surroundingTransaction);
|
LOG.debugf( "Surrounding JTA transaction resumed [%s]", surroundingTransaction );
|
||||||
}
|
}
|
||||||
catch( Throwable t ) {
|
catch( Throwable t ) {
|
||||||
// if the actually work had an error use that, otherwise error based on t
|
// if the actually work had an error use that, otherwise error based on t
|
||||||
|
@ -219,7 +117,7 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T doTheWorkInNewTransaction(ReturningWork<T> work, TransactionManager transactionManager) {
|
private <T> T doTheWorkInNewTransaction(WorkExecutorVisitable<T> work, TransactionManager transactionManager) {
|
||||||
T result = null;
|
T result = null;
|
||||||
try {
|
try {
|
||||||
// start the new isolated transaction
|
// start the new isolated transaction
|
||||||
|
@ -248,17 +146,17 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T doTheWorkInNoTransaction(ReturningWork<T> work) {
|
private <T> T doTheWorkInNoTransaction(WorkExecutorVisitable<T> work) {
|
||||||
return doTheWork( work );
|
return doTheWork( work );
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T doTheWork(ReturningWork<T> work) {
|
private <T> T doTheWork(WorkExecutorVisitable<T> work) {
|
||||||
try {
|
try {
|
||||||
// obtain our isolated connection
|
// obtain our isolated connection
|
||||||
Connection connection = connectionProvider().getConnection();
|
Connection connection = connectionProvider().getConnection();
|
||||||
try {
|
try {
|
||||||
// do the actual work
|
// do the actual work
|
||||||
return work.execute( connection );
|
return work.accept( new WorkExecutor<T>(), connection );
|
||||||
}
|
}
|
||||||
catch ( HibernateException e ) {
|
catch ( HibernateException e ) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -280,6 +178,5 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
||||||
throw sqlExceptionHelper().convert( e, "unable to obtain isolated JDBC connection" );
|
throw sqlExceptionHelper().convert( e, "unable to obtain isolated JDBC connection" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,7 @@
|
||||||
package org.hibernate.engine.transaction.spi;
|
package org.hibernate.engine.transaction.spi;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||||
import org.hibernate.jdbc.Work;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract for performing work in a manner that isolates it from any current transaction.
|
* Contract for performing work in a manner that isolates it from any current transaction.
|
||||||
|
@ -33,16 +32,6 @@ import org.hibernate.jdbc.Work;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface IsolationDelegate {
|
public interface IsolationDelegate {
|
||||||
/**
|
|
||||||
* Perform the given work in isolation from current transaction.
|
|
||||||
*
|
|
||||||
* @param work The work to be performed.
|
|
||||||
* @param transacted Should the work itself be done in a (isolated) transaction?
|
|
||||||
*
|
|
||||||
* @throws HibernateException Indicates a problem performing the work.
|
|
||||||
*/
|
|
||||||
public void delegateWork(Work work, boolean transacted) throws HibernateException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform the given work in isolation from current transaction.
|
* Perform the given work in isolation from current transaction.
|
||||||
*
|
*
|
||||||
|
@ -53,5 +42,5 @@ public interface IsolationDelegate {
|
||||||
*
|
*
|
||||||
* @throws HibernateException Indicates a problem performing the work.
|
* @throws HibernateException Indicates a problem performing the work.
|
||||||
*/
|
*/
|
||||||
public <T> T delegateWork(ReturningWork<T> work, boolean transacted) throws HibernateException;
|
public <T> T delegateWork(WorkExecutorVisitable<T> work, boolean transacted) throws HibernateException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ import org.hibernate.event.EventSource;
|
||||||
import org.hibernate.hql.ast.HqlSqlWalker;
|
import org.hibernate.hql.ast.HqlSqlWalker;
|
||||||
import org.hibernate.hql.ast.SqlGenerator;
|
import org.hibernate.hql.ast.SqlGenerator;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.jdbc.Work;
|
import org.hibernate.jdbc.AbstractWork;
|
||||||
import org.hibernate.persister.entity.Queryable;
|
import org.hibernate.persister.entity.Queryable;
|
||||||
import org.hibernate.sql.InsertSelect;
|
import org.hibernate.sql.InsertSelect;
|
||||||
import org.hibernate.sql.Select;
|
import org.hibernate.sql.Select;
|
||||||
|
@ -137,7 +137,7 @@ public abstract class AbstractStatementExecutor implements StatementExecutor {
|
||||||
" from " + persister.getTemporaryIdTableName();
|
" from " + persister.getTemporaryIdTableName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TemporaryTableCreationWork implements Work {
|
private static class TemporaryTableCreationWork extends AbstractWork {
|
||||||
private final Queryable persister;
|
private final Queryable persister;
|
||||||
|
|
||||||
private TemporaryTableCreationWork(Queryable persister) {
|
private TemporaryTableCreationWork(Queryable persister) {
|
||||||
|
@ -209,7 +209,7 @@ public abstract class AbstractStatementExecutor implements StatementExecutor {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static class TemporaryTableDropWork implements Work {
|
private static class TemporaryTableDropWork extends AbstractWork {
|
||||||
private final Queryable persister;
|
private final Queryable persister;
|
||||||
private final SessionImplementor session;
|
private final SessionImplementor session;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,8 @@ import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
|
||||||
import org.hibernate.id.enhanced.AccessCallback;
|
import org.hibernate.id.enhanced.AccessCallback;
|
||||||
import org.hibernate.id.enhanced.OptimizerFactory;
|
import org.hibernate.id.enhanced.OptimizerFactory;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
import org.hibernate.jdbc.AbstractReturningWork;
|
||||||
|
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
@ -147,7 +148,7 @@ public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenera
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Serializable generate(final SessionImplementor session, Object obj) {
|
public synchronized Serializable generate(final SessionImplementor session, Object obj) {
|
||||||
final ReturningWork<IntegralDataTypeHolder> work = new ReturningWork<IntegralDataTypeHolder>() {
|
final WorkExecutorVisitable<IntegralDataTypeHolder> work = new AbstractReturningWork<IntegralDataTypeHolder>() {
|
||||||
@Override
|
@Override
|
||||||
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
||||||
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass );
|
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass );
|
||||||
|
|
|
@ -40,7 +40,7 @@ import org.hibernate.engine.jdbc.internal.FormatStyle;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
|
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
import org.hibernate.jdbc.AbstractReturningWork;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
@ -144,7 +144,7 @@ public class TableGenerator implements PersistentIdentifierGenerator, Configurab
|
||||||
.getService( JdbcServices.class )
|
.getService( JdbcServices.class )
|
||||||
.getSqlStatementLogger();
|
.getSqlStatementLogger();
|
||||||
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
||||||
new ReturningWork<IntegralDataTypeHolder>() {
|
new AbstractReturningWork<IntegralDataTypeHolder>() {
|
||||||
@Override
|
@Override
|
||||||
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
||||||
IntegralDataTypeHolder value = buildHolder();
|
IntegralDataTypeHolder value = buildHolder();
|
||||||
|
|
|
@ -50,7 +50,7 @@ import org.hibernate.id.IntegralDataTypeHolder;
|
||||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
import org.hibernate.jdbc.AbstractReturningWork;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
@ -465,7 +465,7 @@ public class TableGenerator implements PersistentIdentifierGenerator, Configurab
|
||||||
@Override
|
@Override
|
||||||
public IntegralDataTypeHolder getNextValue() {
|
public IntegralDataTypeHolder getNextValue() {
|
||||||
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
||||||
new ReturningWork<IntegralDataTypeHolder>() {
|
new AbstractReturningWork<IntegralDataTypeHolder>() {
|
||||||
@Override
|
@Override
|
||||||
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
||||||
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
|
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
|
||||||
|
|
|
@ -39,7 +39,7 @@ import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
|
||||||
import org.hibernate.id.IdentifierGenerationException;
|
import org.hibernate.id.IdentifierGenerationException;
|
||||||
import org.hibernate.id.IdentifierGeneratorHelper;
|
import org.hibernate.id.IdentifierGeneratorHelper;
|
||||||
import org.hibernate.id.IntegralDataTypeHolder;
|
import org.hibernate.id.IntegralDataTypeHolder;
|
||||||
import org.hibernate.jdbc.ReturningWork;
|
import org.hibernate.jdbc.AbstractReturningWork;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,7 +115,7 @@ public class TableStructure implements DatabaseStructure {
|
||||||
@Override
|
@Override
|
||||||
public IntegralDataTypeHolder getNextValue() {
|
public IntegralDataTypeHolder getNextValue() {
|
||||||
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
||||||
new ReturningWork<IntegralDataTypeHolder>() {
|
new AbstractReturningWork<IntegralDataTypeHolder>() {
|
||||||
@Override
|
@Override
|
||||||
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
||||||
final SqlStatementLogger statementLogger = session
|
final SqlStatementLogger statementLogger = session
|
||||||
|
|
|
@ -125,7 +125,10 @@ import org.hibernate.event.SaveOrUpdateEventListener;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
|
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||||
|
import org.hibernate.jdbc.ReturningWork;
|
||||||
import org.hibernate.jdbc.Work;
|
import org.hibernate.jdbc.Work;
|
||||||
|
import org.hibernate.jdbc.WorkExecutor;
|
||||||
import org.hibernate.loader.criteria.CriteriaLoader;
|
import org.hibernate.loader.criteria.CriteriaLoader;
|
||||||
import org.hibernate.loader.custom.CustomLoader;
|
import org.hibernate.loader.custom.CustomLoader;
|
||||||
import org.hibernate.loader.custom.CustomQuery;
|
import org.hibernate.loader.custom.CustomQuery;
|
||||||
|
@ -1975,8 +1978,29 @@ public final class SessionImpl
|
||||||
persistenceContext.setReadOnly(entity, readOnly);
|
persistenceContext.setReadOnly(entity, readOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doWork(Work work) throws HibernateException {
|
public void doWork(final Work work) throws HibernateException {
|
||||||
transactionCoordinator.getJdbcCoordinator().coordinateWork( work );
|
WorkExecutorVisitable<Void> realWork = new WorkExecutorVisitable<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void accept(WorkExecutor<Void> workExecutor, Connection connection) throws SQLException {
|
||||||
|
workExecutor.executeWork( work, connection );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
doWork( realWork );
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T doReturningWork(final ReturningWork<T> work) throws HibernateException {
|
||||||
|
WorkExecutorVisitable<T> realWork = new WorkExecutorVisitable<T>() {
|
||||||
|
@Override
|
||||||
|
public T accept(WorkExecutor<T> workExecutor, Connection connection) throws SQLException {
|
||||||
|
return workExecutor.executeReturningWork( work, connection );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return doWork( realWork );
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T doWork(WorkExecutorVisitable<T> work) throws HibernateException {
|
||||||
|
return transactionCoordinator.getJdbcCoordinator().coordinateWork( work );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterScrollOperation() {
|
public void afterScrollOperation() {
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, 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.jdbc;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract implementation of {@link ReturningWork} that accepts a {@link WorkExecutor}
|
||||||
|
* visitor for executing a discrete piece of work and returning a result.
|
||||||
|
*
|
||||||
|
* This class is intended to be used for work that returns a value when executed.
|
||||||
|
*
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public abstract class AbstractReturningWork<T> implements ReturningWork<T>, WorkExecutorVisitable<T> {
|
||||||
|
/**
|
||||||
|
* Accepts a {@link WorkExecutor} visitor for executing the discrete work
|
||||||
|
* encapsulated by this work instance using the supplied connection.
|
||||||
|
*
|
||||||
|
* @param executor The visitor that executes the work
|
||||||
|
* @param connection The connection on which to perform the work.
|
||||||
|
*
|
||||||
|
* @return the valued returned by {@link #execute(java.sql.Connection)}.
|
||||||
|
*
|
||||||
|
* @throws SQLException Thrown during execution of the underlying JDBC interaction.
|
||||||
|
* @throws org.hibernate.HibernateException Generally indicates a wrapped SQLException.
|
||||||
|
*/
|
||||||
|
public T accept(WorkExecutor<T> executor, Connection connection) throws SQLException {
|
||||||
|
return executor.executeReturningWork( this, connection );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, 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.jdbc;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract implementation of {@link Work} that accepts a {@link WorkExecutor}
|
||||||
|
* visitor for executing a discrete piece of work.
|
||||||
|
*
|
||||||
|
* This class is intended to be used for work that does not return a value when
|
||||||
|
* executed.
|
||||||
|
*
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public abstract class AbstractWork implements Work, WorkExecutorVisitable<Void> {
|
||||||
|
/**
|
||||||
|
* Accepts a {@link WorkExecutor} visitor for executing the discrete work
|
||||||
|
* encapsulated by this work instance using the supplied connection.
|
||||||
|
*
|
||||||
|
* Because {@link Work} does not return a value when executed
|
||||||
|
* (via {@link Work#execute(java.sql.Connection)}, this method
|
||||||
|
* always returns null.
|
||||||
|
*
|
||||||
|
* @param connection The connection on which to perform the work.
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*
|
||||||
|
* @throws SQLException Thrown during execution of the underlying JDBC interaction.
|
||||||
|
* @throws org.hibernate.HibernateException Generally indicates a wrapped SQLException.
|
||||||
|
*/
|
||||||
|
public Void accept(WorkExecutor<Void> executor, Connection connection) throws SQLException {
|
||||||
|
return executor.executeWork( this, connection );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, 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.jdbc;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A visitor used for executing a discrete piece of work encapsulated in a
|
||||||
|
* {@link Work} or {@link ReturningWork} instance..
|
||||||
|
*
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class WorkExecutor<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the discrete work encapsulated by a {@link Work} instance
|
||||||
|
* using the supplied connection.
|
||||||
|
*
|
||||||
|
* Because {@link Work} does not return a value when executed
|
||||||
|
* (via {@link Work#execute(java.sql.Connection)}, this method
|
||||||
|
* always returns null.
|
||||||
|
*
|
||||||
|
* @param work The @link ReturningWork} instance encapsulating the discrete work
|
||||||
|
* @param connection The connection on which to perform the work.
|
||||||
|
*
|
||||||
|
* @return null>.
|
||||||
|
*
|
||||||
|
* @throws SQLException Thrown during execution of the underlying JDBC interaction.
|
||||||
|
* @throws org.hibernate.HibernateException Generally indicates a wrapped SQLException.
|
||||||
|
*/
|
||||||
|
public <T> T executeWork(Work work, Connection connection) throws SQLException {
|
||||||
|
work.execute( connection );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the discrete work encapsulated by a {@link ReturningWork} instance
|
||||||
|
* using the supplied connection, returning the result of
|
||||||
|
* {@link ReturningWork#execute(java.sql.Connection)}
|
||||||
|
*
|
||||||
|
* @param work The @link ReturningWork} instance encapsulating the discrete work
|
||||||
|
* @param connection The connection on which to perform the work.
|
||||||
|
*
|
||||||
|
* @return the valued returned by <code>work.execute(connection)</code>.
|
||||||
|
*
|
||||||
|
* @throws SQLException Thrown during execution of the underlying JDBC interaction.
|
||||||
|
* @throws org.hibernate.HibernateException Generally indicates a wrapped SQLException.
|
||||||
|
*/
|
||||||
|
public <T> T executeReturningWork(ReturningWork<T> work, Connection connection) throws SQLException {
|
||||||
|
return work.execute( connection );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, 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.jdbc;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface provides a way to execute unrelated "work" objects using
|
||||||
|
* polymorphism.
|
||||||
|
*
|
||||||
|
* Instances of this interface can accept a {@link WorkExecutor} visitor
|
||||||
|
* for executing a discrete piece of work, and return an implementation-defined
|
||||||
|
* result.
|
||||||
|
*
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public interface WorkExecutorVisitable<T> {
|
||||||
|
/**
|
||||||
|
* Accepts a {@link WorkExecutor} visitor for executing a discrete
|
||||||
|
* piece of work, and returns an implementation-defined result..
|
||||||
|
*
|
||||||
|
* @param executor The visitor that executes the work.
|
||||||
|
* @param connection The connection on which to perform the work.
|
||||||
|
*
|
||||||
|
* @return an implementation-defined result
|
||||||
|
*
|
||||||
|
* @throws SQLException Thrown during execution of the underlying JDBC interaction.
|
||||||
|
* @throws org.hibernate.HibernateException Generally indicates a wrapped SQLException.
|
||||||
|
*/
|
||||||
|
public T accept(WorkExecutor<T> executor, Connection connection) throws SQLException;
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import java.sql.Statement;
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import org.hibernate.JDBCException;
|
import org.hibernate.JDBCException;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.jdbc.ReturningWork;
|
||||||
import org.hibernate.jdbc.Work;
|
import org.hibernate.jdbc.Work;
|
||||||
import org.hibernate.testing.junit.functional.FunctionalTestCase;
|
import org.hibernate.testing.junit.functional.FunctionalTestCase;
|
||||||
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
|
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
|
||||||
|
@ -108,6 +109,52 @@ public class GeneralWorkTest extends FunctionalTestCase {
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testGeneralReturningUsage() throws Throwable {
|
||||||
|
Session session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
Person p = new Person( "Abe", "Lincoln" );
|
||||||
|
session.save( p );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
long count = session.doReturningWork(
|
||||||
|
new ReturningWork<Long>() {
|
||||||
|
public Long execute(Connection connection) throws SQLException {
|
||||||
|
// in this current form, users must handle try/catches themselves for proper resource release
|
||||||
|
Statement statement = null;
|
||||||
|
long personCount = 0;
|
||||||
|
try {
|
||||||
|
statement = connection.createStatement();
|
||||||
|
ResultSet resultSet = null;
|
||||||
|
try {
|
||||||
|
resultSet = statement.executeQuery( "select count(*) from T_JDBC_PERSON" );
|
||||||
|
resultSet.next();
|
||||||
|
personCount = resultSet.getLong( 1 );
|
||||||
|
assertEquals( 1L, personCount );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
releaseQuietly( resultSet );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
releaseQuietly( statement );
|
||||||
|
}
|
||||||
|
return personCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
assertEquals( 1L, count );
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
session.delete( p );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
private void releaseQuietly(Statement statement) {
|
private void releaseQuietly(Statement statement) {
|
||||||
if ( statement == null ) {
|
if ( statement == null ) {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue