1 package org.hibernate.id; 3 4 import java.io.Serializable ; 5 import java.sql.Connection ; 6 import java.sql.PreparedStatement ; 7 import java.sql.ResultSet ; 8 import java.sql.SQLException ; 9 import java.sql.Types ; 10 import java.util.Properties ; 11 12 import org.apache.commons.logging.Log; 13 import org.apache.commons.logging.LogFactory; 14 import org.hibernate.HibernateException; 15 import org.hibernate.LockMode; 16 import org.hibernate.dialect.Dialect; 17 import org.hibernate.engine.SessionImplementor; 18 import org.hibernate.engine.TransactionHelper; 19 import org.hibernate.mapping.Table; 20 import org.hibernate.type.Type; 21 import org.hibernate.util.PropertiesHelper; 22 23 44 public class TableGenerator extends TransactionHelper 45 implements PersistentIdentifierGenerator, Configurable { 46 47 48 public static final String COLUMN = "column"; 49 50 51 public static final String DEFAULT_COLUMN_NAME = "next_hi"; 52 53 54 public static final String TABLE = "table"; 55 56 57 public static final String DEFAULT_TABLE_NAME = "hibernate_unique_key"; 58 59 private static final Log log = LogFactory.getLog(TableGenerator.class); 60 61 private String tableName; 62 private String columnName; 63 private String query; 64 private String update; 65 66 public void configure(Type type, Properties params, Dialect dialect) { 67 68 this.tableName = PropertiesHelper.getString(TABLE, params, DEFAULT_TABLE_NAME); 69 this.columnName = PropertiesHelper.getString(COLUMN, params, DEFAULT_COLUMN_NAME); 70 String schemaName = params.getProperty(SCHEMA); 71 String catalogName = params.getProperty(CATALOG); 72 73 if (tableName.indexOf(dialect.getSchemaSeparator() )<0) { 74 tableName = Table.qualify( catalogName, schemaName, tableName, dialect.getSchemaSeparator() ); 75 } 76 77 query = "select " + 78 columnName + 79 " from " + 80 dialect.appendLockHint(LockMode.UPGRADE, tableName) + 81 dialect.getForUpdateString(); 82 83 update = "update " + 84 tableName + 85 " set " + 86 columnName + 87 " = ? where " + 88 columnName + 89 " = ?"; 90 } 91 92 public synchronized Serializable generate(SessionImplementor session, Object object) 93 throws HibernateException { 94 int result = ( (Integer ) doWorkInNewTransaction(session) ).intValue(); 95 return new Integer (result); 96 } 97 98 99 public String [] sqlCreateStrings(Dialect dialect) throws HibernateException { 100 return new String [] { 101 "create table " + tableName + " ( " + columnName + " " + dialect.getTypeName(Types.INTEGER) + " )", 102 "insert into " + tableName + " values ( 0 )" 103 }; 104 } 105 106 public String [] sqlDropStrings(Dialect dialect) { 107 StringBuffer sqlDropString = new StringBuffer () 109 .append("drop table "); 110 if ( dialect.supportsIfExistsBeforeTableName() ) sqlDropString.append("if exists "); 111 sqlDropString.append(tableName) 112 .append( dialect.getCascadeConstraintsString() ); 113 if ( dialect.supportsIfExistsAfterTableName() ) sqlDropString.append(" if exists"); 114 return new String [] { sqlDropString.toString() }; 115 } 116 117 public Object generatorKey() { 118 return tableName; 119 } 120 121 public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException { 122 int result; 123 int rows; 124 do { 125 129 sql = query; 130 SQL.debug(query); 131 PreparedStatement qps = conn.prepareStatement(query); 132 try { 133 ResultSet rs = qps.executeQuery(); 134 if ( !rs.next() ) { 135 String err = "could not read a hi value - you need to populate the table: " + tableName; 136 log.error(err); 137 throw new IdentifierGenerationException(err); 138 } 139 result = rs.getInt(1); 140 rs.close(); 141 } 142 catch (SQLException sqle) { 143 log.error("could not read a hi value", sqle); 144 throw sqle; 145 } 146 finally { 147 qps.close(); 148 } 149 150 sql = update; 151 SQL.debug(update); 152 PreparedStatement ups = conn.prepareStatement(update); 153 try { 154 ups.setInt( 1, result + 1 ); 155 ups.setInt( 2, result ); 156 rows = ups.executeUpdate(); 157 } 158 catch (SQLException sqle) { 159 log.error("could not update hi value in: " + tableName, sqle); 160 throw sqle; 161 } 162 finally { 163 ups.close(); 164 } 165 } 166 while (rows==0); 167 return new Integer (result); 168 } 169 } 170 | Popular Tags |