JTATableIdGeneratorpublic class JTATableIdGenerator extends Object implements org.hibernate.id.PersistentIdentifierGenerator, org.hibernate.id.ConfigurableA hilo IdentifierGenerator that uses a database
table to store the last generated value.
This implementation is solely for use inside JBoss using JTA for transactions.
TODO implement sequence allocation |
Fields Summary |
---|
public static final String | COLUMNThe column parameter | public static final String | DEFAULT_COLUMN_NAMEDefault column name | public static final String | TABLEThe table parameter | public static final String | DEFAULT_TABLE_NAMEDefault table name | public static final String | ALLOCATION_SIZEThe allocation-size parameter | public static final int | DEFAULT_ALLOCATION_SIZEDefault allocation-size | private static final Log | loglogger for JTATableGenerator | private String | tableNameHolds the name where this generator gets its sequence from | private String | columnNameHolds the name ofthe column where the next sequence value is stored | private String | queryHolds the sql query to retrieve the next high value | private String | updateHolds the sql query to increment the sequence | private org.hibernate.transaction.TransactionManagerLookup | transactionManagerLookupHolds the transaction manager lookup object | private Class | returnClassHolds the class type for the sequence value returned by generate() | private int | allocationSizeHolds the size for the sequence increment. The allocated sequences are managed in memory
and may be lost if the system stops. |
Methods Summary |
---|
public void | configure(org.hibernate.type.Type type, java.util.Properties params, org.hibernate.dialect.Dialect dialect)
this.tableName = PropertiesHelper.getString(TABLE, params, DEFAULT_TABLE_NAME);
this.columnName = PropertiesHelper.getString(COLUMN, params, DEFAULT_COLUMN_NAME);
this.allocationSize = PropertiesHelper.getInt(ALLOCATION_SIZE, params, DEFAULT_ALLOCATION_SIZE);
String schemaName = params.getProperty(SCHEMA);
String catalogName = params.getProperty(CATALOG);
if (true) throw new RuntimeException("DOES ANYBODY USE THIS? It IS CURRENTLY BROKEN");
/*
getSchemaSeparator does not exist in hibernate anymore since 3.1 release
// prepare table name
if (tableName.indexOf(dialect.getSchemaSeparator()) < 0)
{
tableName = Table.qualify(catalogName, schemaName, tableName, dialect.getSchemaSeparator());
}
*/
// prepare SQL statements
query = "select " +
columnName +
" from " +
dialect.appendLockHint(LockMode.UPGRADE, tableName) +
dialect.getForUpdateString();
update = "update " +
tableName +
" set " +
columnName +
" = ? where " +
columnName +
" = ?";
// set up transaction manager lookup
// only JBoss transaction manager is supported
transactionManagerLookup = new JBossTransactionManagerLookup();
// set the sequence type that should be returned
returnClass = type.getReturnedClass();
// debug chosen configuration
if (log.isDebugEnabled())
{
log.debug("configuring id generator: " + this.getClass().getName());
log.debug("tableName=" + tableName);
log.debug("columnName=" + columnName);
log.debug("allocationSize=" + allocationSize);
log.debug("query=" + query);
log.debug("update=" + update);
log.debug("returnClass=" + returnClass);
}
| public synchronized java.io.Serializable | generate(org.hibernate.engine.SessionImplementor session, java.lang.Object object)
// get TransactionManager from JNDI
// no JNDI properties provided -> we are in the container
TransactionManager tm = transactionManagerLookup.getTransactionManager(new Properties());
Transaction surroundingTransaction = null; // for resuming in finally block
Connection conn = null; // for ressource cleanup
String sql = null; // for exception
try
{
long result; // holds the resulting sequence value
// prepare a new transaction context for the generator
surroundingTransaction = tm.suspend();
if (log.isDebugEnabled())
{
log.debug("surrounding tx suspended");
}
tm.begin();
// get connection from managed environment
conn = session.getBatcher().openConnection();
// execute fetching of current sequence value
sql = query;
PreparedStatement qps = conn.prepareStatement(query);
try
{
ResultSet rs = qps.executeQuery();
if (!rs.next())
{
String err = "could not read sequence value - you need to populate the table: " + tableName;
log.error(err);
throw new IdentifierGenerationException(err);
}
result = rs.getLong(1);
rs.close();
}
catch (SQLException sqle)
{
log.error("could not read a sequence value", sqle);
throw sqle;
}
finally
{
qps.close();
}
// increment sequence value
sql = update;
long sequence = result + 1;
PreparedStatement ups = conn.prepareStatement(update);
try
{
ups.setLong(1, sequence);
ups.setLong(2, result);
ups.executeUpdate();
}
catch (SQLException sqle)
{
log.error("could not update sequence value in: " + tableName, sqle);
throw sqle;
}
finally
{
ups.close();
}
// commit transaction to ensure updated sequence is not rolled back
tm.commit();
// transform sequence to the desired type and return the value
Number typedSequence = IdentifierGeneratorFactory.createNumber(sequence, returnClass);
if (log.isDebugEnabled())
{
log.debug("generate() returned: " + typedSequence);
}
return typedSequence;
}
catch (SQLException sqle)
{
throw JDBCExceptionHelper.convert(session.getFactory().getSQLExceptionConverter(),
sqle,
"could not get or update next value",
sql);
}
catch (Exception e)
{
try
{
tm.rollback();
throw new HibernateException(e);
}
catch (SystemException e1)
{
throw new HibernateException(e1);
}
}
finally
{
if (conn != null)
try
{
conn.close();
}
catch (SQLException e)
{
// ignore exception
}
// switch back to surrounding transaction context
if (surroundingTransaction != null)
{
try
{
tm.resume(surroundingTransaction);
if (log.isDebugEnabled())
{
log.debug("surrounding tx resumed");
}
}
catch (Exception e)
{
throw new HibernateException(e);
}
}
}
| public java.lang.Object | generatorKey()
return tableName;
| public java.lang.String[] | sqlCreateStrings(org.hibernate.dialect.Dialect dialect)
return new String[]{
"create table " + tableName + " ( " + columnName + " " + dialect.getTypeName(Types.BIGINT) + " )",
"insert into " + tableName + " values ( 0 )"
};
| public java.lang.String[] | sqlDropStrings(org.hibernate.dialect.Dialect dialect)
//return "drop table " + tableName + dialect.getCascadeConstraintsString();
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()};
|
|