FileDocCategorySizeDatePackage
TableGenerator.javaAPI DocHibernate 3.2.510385Tue Mar 20 20:54:46 GMT 2007org.hibernate.id.enhanced

TableGenerator

public class TableGenerator extends org.hibernate.engine.TransactionHelper implements org.hibernate.id.PersistentIdentifierGenerator, org.hibernate.id.Configurable
A "segmented" version of the enhanced table generator. The term "segmented" refers to the fact that this table can hold multiple value generators, segmented by a key.

Configuration parameters:
NAME DEFAULT DESCRIPTION
{@link #TABLE_PARAM} {@link #DEF_TABLE} The name of the table to use to store/retrieve values
{@link #VALUE_COLUMN_PARAM} {@link #DEF_VALUE_COLUMN} The name of column which holds the sequence value for the given segment
{@link #SEGMENT_COLUMN_PARAM} {@link #DEF_SEGMENT_COLUMN} The name of the column which holds the segment key
{@link #SEGMENT_VALUE_PARAM} {@link #DEF_SEGMENT_VALUE} The value indicating which segment is used by this generator; refers to values in the {@link #SEGMENT_COLUMN_PARAM} column
{@link #SEGMENT_LENGTH_PARAM} {@link #DEF_SEGMENT_LENGTH} The data length of the {@link #SEGMENT_COLUMN_PARAM} column; used for schema creation
{@link #INITIAL_PARAM} {@link #DEFAULT_INITIAL_VALUE} The initial value to be stored for the given segment
{@link #INCREMENT_PARAM} {@link #DEFAULT_INCREMENT_SIZE} The increment size for the underlying segment; see the discussion on {@link Optimizer} for more details.
{@link #OPT_PARAM} depends on defined increment size Allows explicit definition of which optimization strategy to use

author
Steve Ebersole

Fields Summary
private static final Log
log
public static final String
TABLE_PARAM
public static final String
DEF_TABLE
public static final String
VALUE_COLUMN_PARAM
public static final String
DEF_VALUE_COLUMN
public static final String
SEGMENT_COLUMN_PARAM
public static final String
DEF_SEGMENT_COLUMN
public static final String
SEGMENT_VALUE_PARAM
public static final String
DEF_SEGMENT_VALUE
public static final String
SEGMENT_LENGTH_PARAM
public static final int
DEF_SEGMENT_LENGTH
public static final String
INITIAL_PARAM
public static final int
DEFAULT_INITIAL_VALUE
public static final String
INCREMENT_PARAM
public static final int
DEFAULT_INCREMENT_SIZE
public static final String
OPT_PARAM
private String
tableName
private String
valueColumnName
private String
segmentColumnName
private String
segmentValue
private int
segmentValueLength
private int
initialValue
private int
incrementSize
private org.hibernate.type.Type
identifierType
private String
query
private String
insert
private String
update
private Optimizer
optimizer
private long
accessCount
Constructors Summary
Methods Summary
public voidconfigure(org.hibernate.type.Type type, java.util.Properties params, org.hibernate.dialect.Dialect dialect)

		tableName = PropertiesHelper.getString( TABLE_PARAM, params, DEF_TABLE );
		if ( tableName.indexOf( '." ) < 0 ) {
			String schemaName = params.getProperty( SCHEMA );
			String catalogName = params.getProperty( CATALOG );
			tableName = Table.qualify( catalogName, schemaName, tableName );
		}

		segmentColumnName = PropertiesHelper.getString( SEGMENT_COLUMN_PARAM, params, DEF_SEGMENT_COLUMN );
		segmentValue = params.getProperty( SEGMENT_VALUE_PARAM );
		if ( StringHelper.isEmpty( segmentValue ) ) {
			log.debug( "explicit segment value for id generator [" + tableName + '." + segmentColumnName + "] suggested; using default [" + DEF_SEGMENT_VALUE + "]" );
			segmentValue = DEF_SEGMENT_VALUE;
		}
		segmentValueLength = PropertiesHelper.getInt( SEGMENT_LENGTH_PARAM, params, DEF_SEGMENT_LENGTH );
		valueColumnName = PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN );
		initialValue = PropertiesHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE );
		incrementSize = PropertiesHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE );
		identifierType = type;

		String query = "select " + valueColumnName +
				" from " + tableName + " tbl" +
				" where tbl." + segmentColumnName + "=?";
		HashMap lockMap = new HashMap();
		lockMap.put( "tbl", LockMode.UPGRADE );
		this.query = dialect.applyLocksToSql( query, lockMap, CollectionHelper.EMPTY_MAP );

		update = "update " + tableName +
				" set " + valueColumnName + "=? " +
				" where " + valueColumnName + "=? and " + segmentColumnName + "=?";

		insert = "insert into " + tableName + " (" + segmentColumnName + ", " + valueColumnName + ") " + " values (?,?)";

		String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL;
		String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
		optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize );
	
public java.io.SerializabledoWorkInCurrentTransaction(java.sql.Connection conn, java.lang.String sql)

		int result;
		int rows;
		do {
			sql = query;
			SQL.debug( sql );
			PreparedStatement queryPS = conn.prepareStatement( query );
			try {
				queryPS.setString( 1, segmentValue );
				ResultSet queryRS = queryPS.executeQuery();
				if ( !queryRS.next() ) {
					PreparedStatement insertPS = null;
					try {
						result = initialValue;
						sql = insert;
						SQL.debug( sql );
						insertPS = conn.prepareStatement( insert );
						insertPS.setString( 1, segmentValue );
						insertPS.setLong( 2, result );
						insertPS.execute();
					}
					finally {
						if ( insertPS != null ) {
							insertPS.close();
						}
					}
				}
				else {
					result = queryRS.getInt( 1 );
				}
				queryRS.close();
			}
			catch ( SQLException sqle ) {
				log.error( "could not read or init a hi value", sqle );
				throw sqle;
			}
			finally {
				queryPS.close();
			}

			sql = update;
			SQL.debug( sql );
			PreparedStatement updatePS = conn.prepareStatement( update );
			try {
				long newValue = optimizer.applyIncrementSizeToSourceValues()
						? result + incrementSize : result + 1;
				updatePS.setLong( 1, newValue );
				updatePS.setLong( 2, result );
				updatePS.setString( 3, segmentValue );
				rows = updatePS.executeUpdate();
			}
			catch ( SQLException sqle ) {
				log.error( "could not update hi value in: " + tableName, sqle );
				throw sqle;
			}
			finally {
				updatePS.close();
			}
		}
		while ( rows == 0 );

		accessCount++;

		return new Integer( result );
	
public synchronized java.io.Serializablegenerate(org.hibernate.engine.SessionImplementor session, java.lang.Object obj)

		return optimizer.generate(
				new AccessCallback() {
					public long getNextValue() {
						return ( ( Number ) doWorkInNewTransaction( session ) ).longValue();
					}
				}
		);
	
public java.lang.ObjectgeneratorKey()

		return tableName;
	
public org.hibernate.type.TypegetIdentifierType()

		return identifierType;
	
public intgetIncrementSize()

		return incrementSize;
	
public intgetInitialValue()

		return initialValue;
	
public OptimizergetOptimizer()

		return optimizer;
	
public java.lang.StringgetSegmentColumnName()

		return segmentColumnName;
	
public java.lang.StringgetSegmentValue()

		return segmentValue;
	
public intgetSegmentValueLength()

		return segmentValueLength;
	
public longgetTableAccessCount()

		return accessCount;
	
public java.lang.StringgetTableName()


	   
		return tableName;
	
public java.lang.StringgetValueColumnName()

		return valueColumnName;
	
public java.lang.String[]sqlCreateStrings(org.hibernate.dialect.Dialect dialect)

		return new String[] {
				new StringBuffer()
						.append( dialect.getCreateTableString() )
						.append( ' " )
						.append( tableName )
						.append( " ( " )
						.append( segmentColumnName )
						.append( ' " )
						.append( dialect.getTypeName( Types.VARCHAR, segmentValueLength, 0, 0 ) )
						.append( ",  " )
						.append( valueColumnName )
						.append( ' " )
						.append( dialect.getTypeName( Types.BIGINT ) )
						.append( " ) " )
						.toString()
		};
	
public java.lang.String[]sqlDropStrings(org.hibernate.dialect.Dialect dialect)

		StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
		if ( dialect.supportsIfExistsBeforeTableName() ) {
			sqlDropString.append( "if exists " );
		}
		sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() );
		if ( dialect.supportsIfExistsAfterTableName() ) {
			sqlDropString.append( " if exists" );
		}
		return new String[] { sqlDropString.toString() };