i use the following code for validating the schema of the DB against the hibernate mapping.
it notifies if a column/sequence/table that hibernate excpected is missing when my server is started.
Code:
public class MyConfiguration extends Configuration{
/**
* looks for missing columns/sequences/index/tables in the DB
*/
public void validate() {
Iterator classesIterator = getClassMappings();
Connection connection = null;
List validationMessages = new ArrayList();
try {
connection = JDBCUtils.getDataSourceConnection();
DatabaseMetadata meta = new DatabaseMetadata(connection, Dialect.getDialect(getProperties()));
while (classesIterator.hasNext()) {
PersistentClass persistentClass = (PersistentClass)classesIterator.next();
validateTable(persistentClass, connection, meta, validationMessages,getDBUserName());
}
} catch (Exception e) {
log.error(e);
} finally{
JDBCUtils.closeConnection(connection);
}
if (!validationMessages.isEmpty()) {
for (String validationMessage : validationMessage){
log.info(validationMessage);
}
}
}
/**
* validate a table schema
* @param persistentClass
* @param connection JDBC connection
* @param meta
* @param validationMessages
* @param schema The schema name
* @throws java.sql.SQLException
*/
public void validateTable(PersistentClass persistentClass,
Connection connection,
DatabaseMetadata meta,
List validationMessages,
String schema) throws SQLException {
Table table = persistentClass.getTable();
String tableName = table.getName();
Iterator columnIterator=table.getColumnIterator();
Iterator indexIterator=table.getIndexIterator();
StringBuffer warningString = null;
String cat = connection.getCatalog();
TableMetadata tableMetaData = meta.getTableMetadata(tableName, schema, cat);
if (tableMetaData == null) {
warningString = new StringBuffer("Table ").append(tableName).append(" does not exist in the DB!");
validationMessages.add(warningString.toString());
} else {
while ( columnIterator.hasNext() ) {
String columnName = ((Column) columnIterator.next()).getName().trim();
ColumnMetadata columnInfo=tableMetaData.getColumnMetadata( columnName );
if (columnInfo==null) {
if (warningString == null) {
warningString = new StringBuffer("The following columns are missing in table ")
.append(table.getName()).append(": ").append(columnName);
} else {
warningString.append(", ").append(columnName);
}
}
}
if (warningString != null) {
validationMessages.add(warningString.toString());
}
warningString = new StringBuffer();
while (indexIterator.hasNext()) {
String indexName = ((Index)indexIterator.next()).getName();
validateIndex(indexName,warningString,tableMetaData);
}
if (warningString != null && warningString.length() > 0) {
validationMessages.add(warningString.toString());
}
}
// validate sequeunce
SimpleValue identifier = (SimpleValue)persistentClass.getIdentifier();
if ("sequence".equals((identifier.getIdentifierGeneratorStrategy()))) {
String sequenceName = identifier.getIdentifierGeneratorProperties().getProperty("sequence").toUpperCase();
if (!meta.isSequence(sequenceName)){
validationMessages.add("Sequence "+sequenceName+" is missing in the DB! please define it!");
}
}
}
/**
* validate a single index
* @param indexName
* @param warningString
*/
private void validateIndex(String indexName,StringBuffer warningString,TableMetadata tableMetaData) {
IndexMetadata indexInfo = tableMetaData.getIndexMetadata( indexName);
if (indexInfo == null) {
if (warningString.length() == 0) {
warningString.append("The following indexes are missing in table ")
.append(tableMetaData.getName())
.append(": ").append(indexName);
} else {
warningString.append(", ").append(indexName);
}
}
}
/**
* get username of the schema
* @return
*/
public static String getDBUserName() throws SQLException{
Connection connection = JDBCUtils.getConnection();
try {
return connection.getMetaData().getUserName();
} finally {
JDBCUtils.closeConnection(connection);
}
}
}