HHH-5985 - Remove TransactionHelper in preference of IsolationDelegate
This commit is contained in:
parent
ddfcc44d76
commit
21cc90fbf4
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-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.engine;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.jdbc.Work;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows work to be done outside the current transaction, by suspending it,
|
|
||||||
* and performing work in a new transaction
|
|
||||||
*
|
|
||||||
* @author Emmanuel Bernard
|
|
||||||
*/
|
|
||||||
public abstract class TransactionHelper {
|
|
||||||
|
|
||||||
// todo : remove this and just have subclasses use IsolationDelegate directly...
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The work to be done
|
|
||||||
*/
|
|
||||||
protected abstract Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Suspend the current transaction and perform work in a new transaction
|
|
||||||
*/
|
|
||||||
public Serializable doWorkInNewTransaction(final SessionImplementor session) throws HibernateException {
|
|
||||||
class WorkToDo implements Work {
|
|
||||||
Serializable generatedValue;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Connection connection) throws SQLException {
|
|
||||||
String sql = null;
|
|
||||||
try {
|
|
||||||
generatedValue = doWorkInCurrentTransaction( connection, sql );
|
|
||||||
}
|
|
||||||
catch( SQLException e ) {
|
|
||||||
throw session.getFactory().getSQLExceptionHelper().convert(
|
|
||||||
e,
|
|
||||||
"could not get or update next value",
|
|
||||||
sql
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WorkToDo work = new WorkToDo();
|
|
||||||
session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( work, true );
|
|
||||||
return work.generatedValue;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -36,6 +36,7 @@ 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.Work;
|
import org.hibernate.jdbc.Work;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -204,6 +205,29 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T coordinateWork(ReturningWork<T> work) {
|
||||||
|
Connection connection = getLogicalConnection().getDistinctConnectionProxy();
|
||||||
|
try {
|
||||||
|
T result = work.execute( connection );
|
||||||
|
getLogicalConnection().afterStatementExecution();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void executeBatch() {
|
public void executeBatch() {
|
||||||
if ( currentBatch != null ) {
|
if ( currentBatch != null ) {
|
||||||
currentBatch.execute();
|
currentBatch.execute();
|
||||||
|
|
|
@ -26,6 +26,8 @@ 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.ReturningWork;
|
||||||
import org.hibernate.jdbc.Work;
|
import org.hibernate.jdbc.Work;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
@ -88,9 +90,12 @@ public interface JdbcCoordinator extends Serializable {
|
||||||
|
|
||||||
public void coordinateWork(Work work);
|
public void coordinateWork(Work work);
|
||||||
|
|
||||||
|
public <T> T coordinateWork(ReturningWork<T> work);
|
||||||
|
|
||||||
public void executeBatch();
|
public void executeBatch();
|
||||||
|
|
||||||
public void cancelLastQuery();
|
public void cancelLastQuery();
|
||||||
|
|
||||||
public void setTransactionTimeOut(int timeout);
|
public void setTransactionTimeOut(int timeout);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.hibernate.jdbc.util.FormatStyle;
|
import org.hibernate.jdbc.util.FormatStyle;
|
||||||
|
import org.hibernate.jdbc.util.Formatter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Centralize logging for SQL statements.
|
* Centralize logging for SQL statements.
|
||||||
|
@ -90,9 +91,13 @@ public class SQLStatementLogger {
|
||||||
*/
|
*/
|
||||||
public void logStatement(String statement) {
|
public void logStatement(String statement) {
|
||||||
// for now just assume a DML log for formatting
|
// for now just assume a DML log for formatting
|
||||||
|
logStatement( statement, FormatStyle.BASIC.getFormatter() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logStatement(String statement, Formatter formatter) {
|
||||||
if ( format ) {
|
if ( format ) {
|
||||||
if ( logToStdout || log.isDebugEnabled() ) {
|
if ( logToStdout || log.isDebugEnabled() ) {
|
||||||
statement = FormatStyle.BASIC.getFormatter().format( statement );
|
statement = formatter.format( statement );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.debug( statement );
|
log.debug( statement );
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.HibernateException;
|
||||||
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.Work;
|
import org.hibernate.jdbc.Work;
|
||||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
|
||||||
|
@ -120,4 +121,68 @@ public class JdbcIsolationDelegate implements IsolationDelegate {
|
||||||
throw sqlExceptionHelper().convert( sqle, "unable to obtain isolated JDBC connection" );
|
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 ) {
|
||||||
|
connection.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
try {
|
||||||
|
if ( transacted && !connection.isClosed() ) {
|
||||||
|
connection.rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception ignore ) {
|
||||||
|
log.info( "unable to rollback connection on exception [" + 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.info( "Unable to release isolated connection [" + ignore + "]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle ) {
|
||||||
|
throw sqlExceptionHelper().convert( sqle, "unable to obtain isolated JDBC connection" );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.hibernate.HibernateException;
|
||||||
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.Work;
|
import org.hibernate.jdbc.Work;
|
||||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
|
||||||
|
@ -181,5 +182,113 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T delegateWork(ReturningWork<T> work, boolean transacted) throws HibernateException {
|
||||||
|
TransactionManager transactionManager = transactionManager();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// First we suspend any current JTA transaction
|
||||||
|
Transaction surroundingTransaction = transactionManager.suspend();
|
||||||
|
if ( log.isDebugEnabled() ) {
|
||||||
|
log.debug( "surrounding JTA transaction suspended [" + surroundingTransaction + "]" );
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hadProblems = false;
|
||||||
|
try {
|
||||||
|
// then perform the requested work
|
||||||
|
if ( transacted ) {
|
||||||
|
return doTheWorkInNewTransaction( work, transactionManager );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return doTheWorkInNoTransaction( work );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( HibernateException e ) {
|
||||||
|
hadProblems = true;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
transactionManager.resume( surroundingTransaction );
|
||||||
|
if ( log.isDebugEnabled() ) {
|
||||||
|
log.debug( "surrounding JTA transaction resumed [" + 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 <T> T doTheWorkInNewTransaction(ReturningWork<T> work, TransactionManager transactionManager) {
|
||||||
|
T result = null;
|
||||||
|
try {
|
||||||
|
// start the new isolated transaction
|
||||||
|
transactionManager.begin();
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = doTheWork( work );
|
||||||
|
// if everything went ok, commit the isolated transaction
|
||||||
|
transactionManager.commit();
|
||||||
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
try {
|
||||||
|
transactionManager.rollback();
|
||||||
|
}
|
||||||
|
catch ( Exception ignore ) {
|
||||||
|
log.info( "Unable to rollback isolated transaction on error [" + 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 );
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T doTheWorkInNoTransaction(ReturningWork<T> work) {
|
||||||
|
return doTheWork( work );
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T doTheWork(ReturningWork<T> work) {
|
||||||
|
try {
|
||||||
|
// obtain our isolated connection
|
||||||
|
Connection connection = connectionProvider().getConnection();
|
||||||
|
try {
|
||||||
|
// do the actual work
|
||||||
|
return 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.info( "Unable to release isolated connection [" + ignore + "]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( SQLException e ) {
|
||||||
|
throw sqlExceptionHelper().convert( e, "unable to obtain isolated JDBC connection" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +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.Work;
|
import org.hibernate.jdbc.Work;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,4 +42,16 @@ public interface IsolationDelegate {
|
||||||
* @throws HibernateException Indicates a problem performing the work.
|
* @throws HibernateException Indicates a problem performing the work.
|
||||||
*/
|
*/
|
||||||
public void delegateWork(Work work, boolean transacted) throws HibernateException;
|
public void delegateWork(Work work, boolean transacted) throws HibernateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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?
|
||||||
|
*
|
||||||
|
* @return The work result
|
||||||
|
*
|
||||||
|
* @throws HibernateException Indicates a problem performing the work.
|
||||||
|
*/
|
||||||
|
public <T> T delegateWork(ReturningWork<T> work, boolean transacted) throws HibernateException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,24 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.id;
|
package org.hibernate.id;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.cfg.ObjectNameNormalizer;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.engine.SessionImplementor;
|
||||||
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
|
import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
|
||||||
|
import org.hibernate.id.enhanced.AccessCallback;
|
||||||
|
import org.hibernate.id.enhanced.OptimizerFactory;
|
||||||
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
|
import org.hibernate.jdbc.ReturningWork;
|
||||||
|
import org.hibernate.jdbc.util.FormatStyle;
|
||||||
|
import org.hibernate.mapping.Table;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
|
@ -31,22 +49,6 @@ import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.LockMode;
|
|
||||||
import org.hibernate.MappingException;
|
|
||||||
import org.hibernate.cfg.ObjectNameNormalizer;
|
|
||||||
import org.hibernate.id.enhanced.AccessCallback;
|
|
||||||
import org.hibernate.id.enhanced.OptimizerFactory;
|
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
|
||||||
import org.hibernate.jdbc.util.FormatStyle;
|
|
||||||
import org.hibernate.dialect.Dialect;
|
|
||||||
import org.hibernate.engine.SessionImplementor;
|
|
||||||
import org.hibernate.engine.TransactionHelper;
|
|
||||||
import org.hibernate.mapping.Table;
|
|
||||||
import org.hibernate.type.Type;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* A hilo <tt>IdentifierGenerator</tt> that returns a <tt>Long</tt>, constructed using
|
* A hilo <tt>IdentifierGenerator</tt> that returns a <tt>Long</tt>, constructed using
|
||||||
|
@ -78,11 +80,8 @@ import org.hibernate.type.Type;
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
* @author <a href="mailto:kr@hbt.de">Klaus Richarz</a>.
|
* @author <a href="mailto:kr@hbt.de">Klaus Richarz</a>.
|
||||||
*/
|
*/
|
||||||
public class MultipleHiLoPerTableGenerator
|
public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenerator, Configurable {
|
||||||
extends TransactionHelper
|
private static final Logger log = LoggerFactory.getLogger( MultipleHiLoPerTableGenerator.class );
|
||||||
implements PersistentIdentifierGenerator, Configurable {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(MultipleHiLoPerTableGenerator.class);
|
|
||||||
|
|
||||||
public static final String ID_TABLE = "table";
|
public static final String ID_TABLE = "table";
|
||||||
public static final String PK_COLUMN_NAME = "primary_key_column";
|
public static final String PK_COLUMN_NAME = "primary_key_column";
|
||||||
|
@ -146,66 +145,73 @@ public class MultipleHiLoPerTableGenerator
|
||||||
return tableName;
|
return tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
|
public synchronized Serializable generate(final SessionImplementor session, Object obj) {
|
||||||
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass );
|
final ReturningWork<IntegralDataTypeHolder> work = new ReturningWork<IntegralDataTypeHolder>() {
|
||||||
int rows;
|
@Override
|
||||||
do {
|
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
||||||
SQL_STATEMENT_LOGGER.logStatement( query, FormatStyle.BASIC );
|
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass );
|
||||||
PreparedStatement qps = conn.prepareStatement( query );
|
SQLStatementLogger statementLogger = session
|
||||||
PreparedStatement ips = null;
|
.getFactory()
|
||||||
try {
|
.getServiceRegistry()
|
||||||
ResultSet rs = qps.executeQuery();
|
.getService( JdbcServices.class )
|
||||||
boolean isInitialized = rs.next();
|
.getSqlStatementLogger();
|
||||||
if ( !isInitialized ) {
|
int rows;
|
||||||
value.initialize( 0 );
|
do {
|
||||||
SQL_STATEMENT_LOGGER.logStatement( insert, FormatStyle.BASIC );
|
statementLogger.logStatement( query, FormatStyle.BASIC.getFormatter() );
|
||||||
ips = conn.prepareStatement( insert );
|
PreparedStatement qps = connection.prepareStatement( query );
|
||||||
value.bind( ips, 1 );
|
PreparedStatement ips = null;
|
||||||
ips.execute();
|
try {
|
||||||
}
|
ResultSet rs = qps.executeQuery();
|
||||||
else {
|
boolean isInitialized = rs.next();
|
||||||
value.initialize( rs, 0 );
|
if ( !isInitialized ) {
|
||||||
}
|
value.initialize( 0 );
|
||||||
rs.close();
|
statementLogger.logStatement( insert, FormatStyle.BASIC.getFormatter() );
|
||||||
}
|
ips = connection.prepareStatement( insert );
|
||||||
catch (SQLException sqle) {
|
value.bind( ips, 1 );
|
||||||
log.error("could not read or init a hi value", sqle);
|
ips.execute();
|
||||||
throw sqle;
|
}
|
||||||
}
|
else {
|
||||||
finally {
|
value.initialize( rs, 0 );
|
||||||
if (ips != null) {
|
}
|
||||||
ips.close();
|
rs.close();
|
||||||
}
|
}
|
||||||
qps.close();
|
catch (SQLException sqle) {
|
||||||
}
|
log.error("could not read or init a hi value", sqle);
|
||||||
|
throw sqle;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (ips != null) {
|
||||||
|
ips.close();
|
||||||
|
}
|
||||||
|
qps.close();
|
||||||
|
}
|
||||||
|
|
||||||
SQL_STATEMENT_LOGGER.logStatement( update, FormatStyle.BASIC );
|
statementLogger.logStatement( update, FormatStyle.BASIC.getFormatter() );
|
||||||
PreparedStatement ups = conn.prepareStatement( update );
|
PreparedStatement ups = connection.prepareStatement( update );
|
||||||
try {
|
try {
|
||||||
value.copy().increment().bind( ups, 1 );
|
value.copy().increment().bind( ups, 1 );
|
||||||
value.bind( ups, 2 );
|
value.bind( ups, 2 );
|
||||||
rows = ups.executeUpdate();
|
rows = ups.executeUpdate();
|
||||||
}
|
}
|
||||||
catch (SQLException sqle) {
|
catch (SQLException sqle) {
|
||||||
log.error("could not update hi value in: " + tableName, sqle);
|
log.error("could not update hi value in: " + tableName, sqle);
|
||||||
throw sqle;
|
throw sqle;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
ups.close();
|
ups.close();
|
||||||
}
|
}
|
||||||
} while ( rows==0 );
|
} while ( rows==0 );
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public synchronized Serializable generate(final SessionImplementor session, Object obj)
|
|
||||||
throws HibernateException {
|
|
||||||
// maxLo < 1 indicates a hilo generator with no hilo :?
|
// maxLo < 1 indicates a hilo generator with no hilo :?
|
||||||
if ( maxLo < 1 ) {
|
if ( maxLo < 1 ) {
|
||||||
//keep the behavior consistent even for boundary usages
|
//keep the behavior consistent even for boundary usages
|
||||||
IntegralDataTypeHolder value = null;
|
IntegralDataTypeHolder value = null;
|
||||||
while ( value == null || value.lt( 1 ) ) {
|
while ( value == null || value.lt( 1 ) ) {
|
||||||
value = (IntegralDataTypeHolder) doWorkInNewTransaction( session );
|
value = session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( work, true );
|
||||||
}
|
}
|
||||||
return value.makeValue();
|
return value.makeValue();
|
||||||
}
|
}
|
||||||
|
@ -213,7 +219,7 @@ public class MultipleHiLoPerTableGenerator
|
||||||
return hiloOptimizer.generate(
|
return hiloOptimizer.generate(
|
||||||
new AccessCallback() {
|
new AccessCallback() {
|
||||||
public IntegralDataTypeHolder getNextValue() {
|
public IntegralDataTypeHolder getNextValue() {
|
||||||
return (IntegralDataTypeHolder) doWorkInNewTransaction( session );
|
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( work, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Middleware LLC.
|
* distributed under license by Red Hat Inc.
|
||||||
*
|
*
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
* 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
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
@ -20,13 +20,11 @@
|
||||||
* Free Software Foundation, Inc.
|
* Free Software Foundation, Inc.
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
package org.hibernate.id;
|
package org.hibernate.id;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.jdbc.util.SQLStatementLogger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An <tt>IdentifierGenerator</tt> that requires creation of database objects.
|
* An <tt>IdentifierGenerator</tt> that requires creation of database objects.
|
||||||
|
@ -99,8 +97,6 @@ public interface PersistentIdentifierGenerator extends IdentifierGenerator {
|
||||||
*/
|
*/
|
||||||
public Object generatorKey();
|
public Object generatorKey();
|
||||||
|
|
||||||
static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Middleware LLC.
|
* distributed under license by Red Hat Inc.
|
||||||
*
|
*
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
* 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
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
@ -20,10 +20,24 @@
|
||||||
* Free Software Foundation, Inc.
|
* Free Software Foundation, Inc.
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
package org.hibernate.id;
|
package org.hibernate.id;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.cfg.ObjectNameNormalizer;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.engine.SessionImplementor;
|
||||||
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
|
import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
|
||||||
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
|
import org.hibernate.jdbc.ReturningWork;
|
||||||
|
import org.hibernate.jdbc.util.FormatStyle;
|
||||||
|
import org.hibernate.mapping.Table;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
|
@ -32,19 +46,6 @@ import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.LockMode;
|
|
||||||
import org.hibernate.cfg.ObjectNameNormalizer;
|
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
|
||||||
import org.hibernate.jdbc.util.FormatStyle;
|
|
||||||
import org.hibernate.dialect.Dialect;
|
|
||||||
import org.hibernate.engine.SessionImplementor;
|
|
||||||
import org.hibernate.engine.TransactionHelper;
|
|
||||||
import org.hibernate.mapping.Table;
|
|
||||||
import org.hibernate.type.Type;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An <tt>IdentifierGenerator</tt> that uses a database
|
* An <tt>IdentifierGenerator</tt> that uses a database
|
||||||
* table to store the last generated value. It is not
|
* table to store the last generated value. It is not
|
||||||
|
@ -70,8 +71,7 @@ import org.hibernate.type.Type;
|
||||||
* @see TableHiLoGenerator
|
* @see TableHiLoGenerator
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public class TableGenerator extends TransactionHelper
|
public class TableGenerator implements PersistentIdentifierGenerator, Configurable {
|
||||||
implements PersistentIdentifierGenerator, Configurable {
|
|
||||||
/* COLUMN and TABLE should be renamed but it would break the public API */
|
/* COLUMN and TABLE should be renamed but it would break the public API */
|
||||||
/** The column parameter */
|
/** The column parameter */
|
||||||
public static final String COLUMN = "column";
|
public static final String COLUMN = "column";
|
||||||
|
@ -139,7 +139,63 @@ public class TableGenerator extends TransactionHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IntegralDataTypeHolder generateHolder(SessionImplementor session) {
|
protected IntegralDataTypeHolder generateHolder(SessionImplementor session) {
|
||||||
return (IntegralDataTypeHolder) doWorkInNewTransaction( session );
|
final SQLStatementLogger statementLogger = session
|
||||||
|
.getFactory()
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( JdbcServices.class )
|
||||||
|
.getSqlStatementLogger();
|
||||||
|
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
||||||
|
new ReturningWork<IntegralDataTypeHolder>() {
|
||||||
|
@Override
|
||||||
|
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
||||||
|
IntegralDataTypeHolder value = buildHolder();
|
||||||
|
int rows;
|
||||||
|
do {
|
||||||
|
// The loop ensures atomicity of the
|
||||||
|
// select + update even for no transaction
|
||||||
|
// or read committed isolation level
|
||||||
|
|
||||||
|
statementLogger.logStatement( query, FormatStyle.BASIC.getFormatter() );
|
||||||
|
PreparedStatement qps = connection.prepareStatement( query );
|
||||||
|
try {
|
||||||
|
ResultSet rs = qps.executeQuery();
|
||||||
|
if ( !rs.next() ) {
|
||||||
|
String err = "could not read a hi value - you need to populate the table: " + tableName;
|
||||||
|
log.error(err);
|
||||||
|
throw new IdentifierGenerationException(err);
|
||||||
|
}
|
||||||
|
value.initialize( rs, 1 );
|
||||||
|
rs.close();
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
log.error("could not read a hi value", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
qps.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
statementLogger.logStatement( update, FormatStyle.BASIC.getFormatter() );
|
||||||
|
PreparedStatement ups = connection.prepareStatement(update);
|
||||||
|
try {
|
||||||
|
value.copy().increment().bind( ups, 1 );
|
||||||
|
value.bind( ups, 2 );
|
||||||
|
rows = ups.executeUpdate();
|
||||||
|
}
|
||||||
|
catch (SQLException sqle) {
|
||||||
|
log.error("could not update hi value in: " + tableName, sqle);
|
||||||
|
throw sqle;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
ups.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (rows==0);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
|
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
|
||||||
|
@ -165,66 +221,6 @@ public class TableGenerator extends TransactionHelper
|
||||||
return tableName;
|
return tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the next value.
|
|
||||||
*
|
|
||||||
* @param conn The sql connection to use.
|
|
||||||
* @param sql n/a
|
|
||||||
*
|
|
||||||
* @return Prior to 3.5 this method returned an {@link Integer}. Since 3.5 it now
|
|
||||||
* returns a {@link IntegralDataTypeHolder}
|
|
||||||
*
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
|
|
||||||
IntegralDataTypeHolder value = buildHolder();
|
|
||||||
int rows;
|
|
||||||
do {
|
|
||||||
// The loop ensures atomicity of the
|
|
||||||
// select + update even for no transaction
|
|
||||||
// or read committed isolation level
|
|
||||||
|
|
||||||
sql = query;
|
|
||||||
SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
|
|
||||||
PreparedStatement qps = conn.prepareStatement(query);
|
|
||||||
try {
|
|
||||||
ResultSet rs = qps.executeQuery();
|
|
||||||
if ( !rs.next() ) {
|
|
||||||
String err = "could not read a hi value - you need to populate the table: " + tableName;
|
|
||||||
log.error(err);
|
|
||||||
throw new IdentifierGenerationException(err);
|
|
||||||
}
|
|
||||||
value.initialize( rs, 1 );
|
|
||||||
rs.close();
|
|
||||||
}
|
|
||||||
catch (SQLException sqle) {
|
|
||||||
log.error("could not read a hi value", sqle);
|
|
||||||
throw sqle;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
qps.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
sql = update;
|
|
||||||
SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
|
|
||||||
PreparedStatement ups = conn.prepareStatement(update);
|
|
||||||
try {
|
|
||||||
value.copy().increment().bind( ups, 1 );
|
|
||||||
value.bind( ups, 2 );
|
|
||||||
rows = ups.executeUpdate();
|
|
||||||
}
|
|
||||||
catch (SQLException sqle) {
|
|
||||||
log.error("could not update hi value in: " + tableName, sqle);
|
|
||||||
throw sqle;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
ups.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (rows==0);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected IntegralDataTypeHolder buildHolder() {
|
protected IntegralDataTypeHolder buildHolder() {
|
||||||
return IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
|
return IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,37 +23,38 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.id.enhanced;
|
package org.hibernate.id.enhanced;
|
||||||
|
|
||||||
import java.sql.Types;
|
import org.hibernate.HibernateException;
|
||||||
import java.sql.Connection;
|
import org.hibernate.LockMode;
|
||||||
import java.sql.SQLException;
|
import org.hibernate.LockOptions;
|
||||||
import java.sql.PreparedStatement;
|
import org.hibernate.MappingException;
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.engine.TransactionHelper;
|
import org.hibernate.cfg.ObjectNameNormalizer;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.SessionImplementor;
|
import org.hibernate.engine.SessionImplementor;
|
||||||
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
|
import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
|
||||||
|
import org.hibernate.id.Configurable;
|
||||||
import org.hibernate.id.IdentifierGeneratorHelper;
|
import org.hibernate.id.IdentifierGeneratorHelper;
|
||||||
import org.hibernate.id.IntegralDataTypeHolder;
|
import org.hibernate.id.IntegralDataTypeHolder;
|
||||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||||
import org.hibernate.id.Configurable;
|
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.jdbc.ReturningWork;
|
||||||
import org.hibernate.dialect.Dialect;
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.MappingException;
|
|
||||||
import org.hibernate.LockOptions;
|
|
||||||
import org.hibernate.LockMode;
|
|
||||||
import org.hibernate.cfg.ObjectNameNormalizer;
|
|
||||||
import org.hibernate.jdbc.util.FormatStyle;
|
import org.hibernate.jdbc.util.FormatStyle;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.util.StringHelper;
|
import org.hibernate.util.StringHelper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An enhanced version of table-based id generation.
|
* An enhanced version of table-based id generation.
|
||||||
|
@ -128,7 +129,7 @@ import org.hibernate.util.StringHelper;
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class TableGenerator extends TransactionHelper implements PersistentIdentifierGenerator, Configurable {
|
public class TableGenerator implements PersistentIdentifierGenerator, Configurable {
|
||||||
private static final Logger log = LoggerFactory.getLogger( TableGenerator.class );
|
private static final Logger log = LoggerFactory.getLogger( TableGenerator.class );
|
||||||
|
|
||||||
public static final String CONFIG_PREFER_SEGMENT_PER_ENTITY = "prefer_entity_table_as_segment_value";
|
public static final String CONFIG_PREFER_SEGMENT_PER_ENTITY = "prefer_entity_table_as_segment_value";
|
||||||
|
@ -176,9 +177,7 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
|
||||||
private Optimizer optimizer;
|
private Optimizer optimizer;
|
||||||
private long accessCount = 0;
|
private long accessCount = 0;
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Object generatorKey() {
|
public Object generatorKey() {
|
||||||
return tableName;
|
return tableName;
|
||||||
}
|
}
|
||||||
|
@ -283,9 +282,7 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
|
||||||
return accessCount;
|
return accessCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
|
public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
|
||||||
identifierType = type;
|
identifierType = type;
|
||||||
|
|
||||||
|
@ -456,93 +453,96 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
|
||||||
return "insert into " + tableName + " (" + segmentColumnName + ", " + valueColumnName + ") " + " values (?,?)";
|
return "insert into " + tableName + " (" + segmentColumnName + ", " + valueColumnName + ") " + " values (?,?)";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public synchronized Serializable generate(final SessionImplementor session, Object obj) {
|
public synchronized Serializable generate(final SessionImplementor session, Object obj) {
|
||||||
|
final SQLStatementLogger statementLogger = session
|
||||||
|
.getFactory()
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( JdbcServices.class )
|
||||||
|
.getSqlStatementLogger();
|
||||||
return optimizer.generate(
|
return optimizer.generate(
|
||||||
new AccessCallback() {
|
new AccessCallback() {
|
||||||
|
@Override
|
||||||
public IntegralDataTypeHolder getNextValue() {
|
public IntegralDataTypeHolder getNextValue() {
|
||||||
return ( IntegralDataTypeHolder ) doWorkInNewTransaction( session );
|
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
||||||
|
new ReturningWork<IntegralDataTypeHolder>() {
|
||||||
|
@Override
|
||||||
|
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
||||||
|
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
|
||||||
|
int rows;
|
||||||
|
do {
|
||||||
|
statementLogger.logStatement( selectQuery, FormatStyle.BASIC.getFormatter() );
|
||||||
|
PreparedStatement selectPS = connection.prepareStatement( selectQuery );
|
||||||
|
try {
|
||||||
|
selectPS.setString( 1, segmentValue );
|
||||||
|
ResultSet selectRS = selectPS.executeQuery();
|
||||||
|
if ( !selectRS.next() ) {
|
||||||
|
value.initialize( initialValue );
|
||||||
|
PreparedStatement insertPS = null;
|
||||||
|
try {
|
||||||
|
statementLogger.logStatement( insertQuery, FormatStyle.BASIC.getFormatter() );
|
||||||
|
insertPS = connection.prepareStatement( insertQuery );
|
||||||
|
insertPS.setString( 1, segmentValue );
|
||||||
|
value.bind( insertPS, 2 );
|
||||||
|
insertPS.execute();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if ( insertPS != null ) {
|
||||||
|
insertPS.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value.initialize( selectRS, 1 );
|
||||||
|
}
|
||||||
|
selectRS.close();
|
||||||
|
}
|
||||||
|
catch ( SQLException e ) {
|
||||||
|
log.error( "could not read or init a hi value", e );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
selectPS.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
statementLogger.logStatement( updateQuery, FormatStyle.BASIC.getFormatter() );
|
||||||
|
PreparedStatement updatePS = connection.prepareStatement( updateQuery );
|
||||||
|
try {
|
||||||
|
final IntegralDataTypeHolder updateValue = value.copy();
|
||||||
|
if ( optimizer.applyIncrementSizeToSourceValues() ) {
|
||||||
|
updateValue.add( incrementSize );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updateValue.increment();
|
||||||
|
}
|
||||||
|
updateValue.bind( updatePS, 1 );
|
||||||
|
value.bind( updatePS, 2 );
|
||||||
|
updatePS.setString( 3, segmentValue );
|
||||||
|
rows = updatePS.executeUpdate();
|
||||||
|
}
|
||||||
|
catch ( SQLException e ) {
|
||||||
|
log.error( "could not updateQuery hi value in: " + tableName, e );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
updatePS.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( rows == 0 );
|
||||||
|
|
||||||
|
accessCount++;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
|
|
||||||
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
|
|
||||||
int rows;
|
|
||||||
do {
|
|
||||||
SQL_STATEMENT_LOGGER.logStatement( selectQuery, FormatStyle.BASIC );
|
|
||||||
PreparedStatement selectPS = conn.prepareStatement( selectQuery );
|
|
||||||
try {
|
|
||||||
selectPS.setString( 1, segmentValue );
|
|
||||||
ResultSet selectRS = selectPS.executeQuery();
|
|
||||||
if ( !selectRS.next() ) {
|
|
||||||
value.initialize( initialValue );
|
|
||||||
PreparedStatement insertPS = null;
|
|
||||||
try {
|
|
||||||
SQL_STATEMENT_LOGGER.logStatement( insertQuery, FormatStyle.BASIC );
|
|
||||||
insertPS = conn.prepareStatement( insertQuery );
|
|
||||||
insertPS.setString( 1, segmentValue );
|
|
||||||
value.bind( insertPS, 2 );
|
|
||||||
insertPS.execute();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if ( insertPS != null ) {
|
|
||||||
insertPS.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
value.initialize( selectRS, 1 );
|
|
||||||
}
|
|
||||||
selectRS.close();
|
|
||||||
}
|
|
||||||
catch ( SQLException sqle ) {
|
|
||||||
log.error( "could not read or init a hi value", sqle );
|
|
||||||
throw sqle;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
selectPS.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
SQL_STATEMENT_LOGGER.logStatement( updateQuery, FormatStyle.BASIC );
|
|
||||||
PreparedStatement updatePS = conn.prepareStatement( updateQuery );
|
|
||||||
try {
|
|
||||||
final IntegralDataTypeHolder updateValue = value.copy();
|
|
||||||
if ( optimizer.applyIncrementSizeToSourceValues() ) {
|
|
||||||
updateValue.add( incrementSize );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updateValue.increment();
|
|
||||||
}
|
|
||||||
updateValue.bind( updatePS, 1 );
|
|
||||||
value.bind( updatePS, 2 );
|
|
||||||
updatePS.setString( 3, segmentValue );
|
|
||||||
rows = updatePS.executeUpdate();
|
|
||||||
}
|
|
||||||
catch ( SQLException sqle ) {
|
|
||||||
log.error( "could not updateQuery hi value in: " + tableName, sqle );
|
|
||||||
throw sqle;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
updatePS.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ( rows == 0 );
|
|
||||||
|
|
||||||
accessCount++;
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
|
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
new StringBuffer()
|
new StringBuffer()
|
||||||
|
@ -565,9 +565,7 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
|
public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
|
||||||
StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
|
StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
|
||||||
if ( dialect.supportsIfExistsBeforeTableName() ) {
|
if ( dialect.supportsIfExistsBeforeTableName() ) {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Middleware LLC.
|
* distributed under license by Red Hat Inc.
|
||||||
*
|
*
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
* 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
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
@ -20,39 +20,36 @@
|
||||||
* Free Software Foundation, Inc.
|
* Free Software Foundation, Inc.
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
package org.hibernate.id.enhanced;
|
package org.hibernate.id.enhanced;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.engine.SessionImplementor;
|
||||||
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
|
import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
|
||||||
|
import org.hibernate.id.IdentifierGenerationException;
|
||||||
|
import org.hibernate.id.IdentifierGeneratorHelper;
|
||||||
|
import org.hibernate.id.IntegralDataTypeHolder;
|
||||||
|
import org.hibernate.jdbc.ReturningWork;
|
||||||
|
import org.hibernate.jdbc.util.FormatStyle;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.LockMode;
|
|
||||||
import org.hibernate.dialect.Dialect;
|
|
||||||
import org.hibernate.engine.SessionImplementor;
|
|
||||||
import org.hibernate.engine.TransactionHelper;
|
|
||||||
import org.hibernate.id.IdentifierGenerationException;
|
|
||||||
import org.hibernate.id.IdentifierGeneratorHelper;
|
|
||||||
import org.hibernate.id.IntegralDataTypeHolder;
|
|
||||||
import org.hibernate.jdbc.util.FormatStyle;
|
|
||||||
import org.hibernate.jdbc.util.SQLStatementLogger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes a table used to mimic sequence behavior
|
* Describes a table used to mimic sequence behavior
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class TableStructure extends TransactionHelper implements DatabaseStructure {
|
public class TableStructure implements DatabaseStructure {
|
||||||
private static final Logger log = LoggerFactory.getLogger( TableStructure.class );
|
private static final Logger log = LoggerFactory.getLogger( TableStructure.class );
|
||||||
private static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false );
|
|
||||||
|
|
||||||
private final String tableName;
|
private final String tableName;
|
||||||
private final String valueColumnName;
|
private final String valueColumnName;
|
||||||
|
@ -87,55 +84,98 @@ public class TableStructure extends TransactionHelper implements DatabaseStructu
|
||||||
" where " + valueColumnName + "=?";
|
" where " + valueColumnName + "=?";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return tableName;
|
return tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public int getInitialValue() {
|
public int getInitialValue() {
|
||||||
return initialValue;
|
return initialValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public int getIncrementSize() {
|
public int getIncrementSize() {
|
||||||
return incrementSize;
|
return incrementSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public int getTimesAccessed() {
|
public int getTimesAccessed() {
|
||||||
return accessCounter;
|
return accessCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public void prepare(Optimizer optimizer) {
|
public void prepare(Optimizer optimizer) {
|
||||||
applyIncrementSizeToSourceValues = optimizer.applyIncrementSizeToSourceValues();
|
applyIncrementSizeToSourceValues = optimizer.applyIncrementSizeToSourceValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public AccessCallback buildCallback(final SessionImplementor session) {
|
public AccessCallback buildCallback(final SessionImplementor session) {
|
||||||
return new AccessCallback() {
|
return new AccessCallback() {
|
||||||
|
@Override
|
||||||
public IntegralDataTypeHolder getNextValue() {
|
public IntegralDataTypeHolder getNextValue() {
|
||||||
return ( IntegralDataTypeHolder ) doWorkInNewTransaction( session );
|
return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
|
||||||
|
new ReturningWork<IntegralDataTypeHolder>() {
|
||||||
|
@Override
|
||||||
|
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
|
||||||
|
final SQLStatementLogger statementLogger = session
|
||||||
|
.getFactory()
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( JdbcServices.class )
|
||||||
|
.getSqlStatementLogger();
|
||||||
|
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType );
|
||||||
|
int rows;
|
||||||
|
do {
|
||||||
|
statementLogger.logStatement( selectQuery, FormatStyle.BASIC.getFormatter() );
|
||||||
|
PreparedStatement selectStatement = connection.prepareStatement( selectQuery );
|
||||||
|
try {
|
||||||
|
ResultSet selectRS = selectStatement.executeQuery();
|
||||||
|
if ( !selectRS.next() ) {
|
||||||
|
String err = "could not read a hi value - you need to populate the table: " + tableName;
|
||||||
|
log.error( err );
|
||||||
|
throw new IdentifierGenerationException( err );
|
||||||
|
}
|
||||||
|
value.initialize( selectRS, 1 );
|
||||||
|
selectRS.close();
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle ) {
|
||||||
|
log.error( "could not read a hi value", sqle );
|
||||||
|
throw sqle;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
selectStatement.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
statementLogger.logStatement( updateQuery, FormatStyle.BASIC.getFormatter() );
|
||||||
|
PreparedStatement updatePS = connection.prepareStatement( updateQuery );
|
||||||
|
try {
|
||||||
|
final int increment = applyIncrementSizeToSourceValues ? incrementSize : 1;
|
||||||
|
final IntegralDataTypeHolder updateValue = value.copy().add( increment );
|
||||||
|
updateValue.bind( updatePS, 1 );
|
||||||
|
value.bind( updatePS, 2 );
|
||||||
|
rows = updatePS.executeUpdate();
|
||||||
|
}
|
||||||
|
catch ( SQLException e ) {
|
||||||
|
log.error( "could not updateQuery hi value in: " + tableName, e );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
updatePS.close();
|
||||||
|
}
|
||||||
|
} while ( rows == 0 );
|
||||||
|
|
||||||
|
accessCounter++;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
|
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
dialect.getCreateTableString() + " " + tableName + " ( " + valueColumnName + " " + dialect.getTypeName( Types.BIGINT ) + " )",
|
dialect.getCreateTableString() + " " + tableName + " ( " + valueColumnName + " " + dialect.getTypeName( Types.BIGINT ) + " )",
|
||||||
|
@ -143,9 +183,7 @@ public class TableStructure extends TransactionHelper implements DatabaseStructu
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
|
public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
|
||||||
StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
|
StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
|
||||||
if ( dialect.supportsIfExistsBeforeTableName() ) {
|
if ( dialect.supportsIfExistsBeforeTableName() ) {
|
||||||
|
@ -157,55 +195,4 @@ public class TableStructure extends TransactionHelper implements DatabaseStructu
|
||||||
}
|
}
|
||||||
return new String[] { sqlDropString.toString() };
|
return new String[] { sqlDropString.toString() };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
protected Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
|
|
||||||
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType );
|
|
||||||
int rows;
|
|
||||||
do {
|
|
||||||
SQL_STATEMENT_LOGGER.logStatement( selectQuery, FormatStyle.BASIC );
|
|
||||||
PreparedStatement selectPS = conn.prepareStatement( selectQuery );
|
|
||||||
try {
|
|
||||||
ResultSet selectRS = selectPS.executeQuery();
|
|
||||||
if ( !selectRS.next() ) {
|
|
||||||
String err = "could not read a hi value - you need to populate the table: " + tableName;
|
|
||||||
log.error( err );
|
|
||||||
throw new IdentifierGenerationException( err );
|
|
||||||
}
|
|
||||||
value.initialize( selectRS, 1 );
|
|
||||||
selectRS.close();
|
|
||||||
}
|
|
||||||
catch ( SQLException sqle ) {
|
|
||||||
log.error( "could not read a hi value", sqle );
|
|
||||||
throw sqle;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
selectPS.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
SQL_STATEMENT_LOGGER.logStatement( updateQuery, FormatStyle.BASIC );
|
|
||||||
PreparedStatement updatePS = conn.prepareStatement( updateQuery );
|
|
||||||
try {
|
|
||||||
final int increment = applyIncrementSizeToSourceValues ? incrementSize : 1;
|
|
||||||
final IntegralDataTypeHolder updateValue = value.copy().add( increment );
|
|
||||||
updateValue.bind( updatePS, 1 );
|
|
||||||
value.bind( updatePS, 2 );
|
|
||||||
rows = updatePS.executeUpdate();
|
|
||||||
}
|
|
||||||
catch ( SQLException sqle ) {
|
|
||||||
log.error( "could not updateQuery hi value in: " + tableName, sqle );
|
|
||||||
throw sqle;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
updatePS.close();
|
|
||||||
}
|
|
||||||
} while ( rows == 0 );
|
|
||||||
|
|
||||||
accessCounter++;
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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 discrete piece of work following the lines of {@link Work} but returning a result.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface ReturningWork<T> {
|
||||||
|
/**
|
||||||
|
* Execute the discrete work encapsulated by this work instance using the supplied connection.
|
||||||
|
*
|
||||||
|
* @param connection The connection on which to perform the work.
|
||||||
|
*
|
||||||
|
* @return The work result
|
||||||
|
*
|
||||||
|
* @throws SQLException Thrown during execution of the underlying JDBC interaction.
|
||||||
|
* @throws org.hibernate.HibernateException Generally indicates a wrapped SQLException.
|
||||||
|
*/
|
||||||
|
public T execute(Connection connection) throws SQLException;
|
||||||
|
}
|
Loading…
Reference in New Issue