FileDocCategorySizeDatePackage
TableGenerator.javaAPI DocHibernate 3.2.55101Mon Mar 19 16:06:46 GMT 2007org.hibernate.id

TableGenerator

public class TableGenerator extends org.hibernate.engine.TransactionHelper implements PersistentIdentifierGenerator, Configurable
An IdentifierGenerator that uses a database table to store the last generated value. It is not intended that applications use this strategy directly. However, it may be used to build other (efficient) strategies. The returned type is Integer.

The hi value MUST be fetched in a seperate transaction to the Session transaction so the generator must be able to obtain a new connection and commit it. Hence this implementation may not be used when Hibernate is fetching connections when the user is supplying connections.

The returned value is of type integer.

Mapping parameters supported: table, column
see
TableHiLoGenerator
author
Gavin King

Fields Summary
public static final String
COLUMN
The column parameter
public static final String
DEFAULT_COLUMN_NAME
Default column name
public static final String
TABLE
The table parameter
public static final String
DEFAULT_TABLE_NAME
Default table name
private static final Log
log
private String
tableName
private String
columnName
private String
query
private String
update
Constructors Summary
Methods Summary
public voidconfigure(org.hibernate.type.Type type, java.util.Properties params, org.hibernate.dialect.Dialect dialect)


	        

		tableName = PropertiesHelper.getString(TABLE, params, DEFAULT_TABLE_NAME);
		columnName = PropertiesHelper.getString(COLUMN, params, DEFAULT_COLUMN_NAME);
		String schemaName = params.getProperty(SCHEMA);
		String catalogName = params.getProperty(CATALOG);

		if ( tableName.indexOf( '." )<0 ) {
			tableName = Table.qualify( catalogName, schemaName, tableName );
		}

		query = "select " + 
			columnName + 
			" from " + 
			dialect.appendLockHint(LockMode.UPGRADE, tableName) +
			dialect.getForUpdateString();

		update = "update " + 
			tableName + 
			" set " + 
			columnName + 
			" = ? where " + 
			columnName + 
			" = ?";
	
public java.io.SerializabledoWorkInCurrentTransaction(java.sql.Connection conn, java.lang.String sql)

		int result;
		int rows;
		do {
			// The loop ensures atomicity of the
			// select + update even for no transaction
			// or read committed isolation level

			sql = query;
			SQL.debug(query);
			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);
				}
				result = rs.getInt(1);
				rs.close();
			}
			catch (SQLException sqle) {
				log.error("could not read a hi value", sqle);
				throw sqle;
			}
			finally {
				qps.close();
			}

			sql = update;
			SQL.debug(update);
			PreparedStatement ups = conn.prepareStatement(update);
			try {
				ups.setInt( 1, result + 1 );
				ups.setInt( 2, result );
				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 new Integer(result);
	
public synchronized java.io.Serializablegenerate(org.hibernate.engine.SessionImplementor session, java.lang.Object object)

		int result = ( (Integer) doWorkInNewTransaction(session) ).intValue();
		return new Integer(result);
	
public java.lang.ObjectgeneratorKey()

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

		return new String[] {
			dialect.getCreateTableString() + " " + tableName + " ( " + columnName + " " + dialect.getTypeName(Types.INTEGER) + " )",
			"insert into " + tableName + " values ( 0 )"
		};
	
public java.lang.String[]sqlDropStrings(org.hibernate.dialect.Dialect dialect)

		StringBuffer sqlDropString = new StringBuffer( "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() };