com.ironiacorp.persistence.hibernate.HibernateBootstrap.java Source code

Java tutorial

Introduction

Here is the source code for com.ironiacorp.persistence.hibernate.HibernateBootstrap.java

Source

/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    
Copyright (C) 2005 Marco Aurlio Graciotto Silva <magsilva@gmail.com>
 */

package com.ironiacorp.persistence.hibernate;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.cfg.Configuration;
// import org.hibernate.connection.ConnectionProvider;
// import org.hibernate.connection.ConnectionProviderFactory;
import org.hibernate.dialect.Dialect;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;

import com.ironiacorp.datastructure.array.ArrayUtil;

import java.util.List;
import java.util.LinkedList;
import java.util.Properties;

import java.sql.SQLException;

/**
 * Helper class to initiate a Hibernate setup.
 * 
 * @author Marco Aurlio Graciotto Silva
 */
public class HibernateBootstrap {
    /**
     * Commons Logging instance.
     */
    private static Log log = LogFactory.getLog(HibernateBootstrap.class);

    /**
     * Configuration used by Hibernate, responsable for mapping the objects to
     * an relational database.
     */
    private Configuration config;

    /**
     * Check the exceptions thrown while running the update or create scripts
     * for the current Hibernate configuration.
     * 
     * @param ddl
     *            The SchemaExport or SchemaUpdate used.
     * @throws IllegalArgumentException
     *             If the argument is not a SchemaExport or SchemaUpdate
     *             instance.
     */
    @SuppressWarnings("unchecked")
    private List<Exception> handleExceptions(Object ddl) {
        if (!(ddl instanceof SchemaExport ^ ddl instanceof SchemaUpdate)) {
            throw new IllegalArgumentException();
        }

        List<Exception> exceptions = null;
        List<Exception> errors = new LinkedList<Exception>();

        if (ddl instanceof SchemaExport) {
            SchemaExport schema = (SchemaExport) ddl;
            exceptions = schema.getExceptions();
        } else {
            SchemaUpdate schema = (SchemaUpdate) ddl;
            exceptions = schema.getExceptions();
        }

        if (!exceptions.isEmpty()) {
            for (Object o : exceptions) {
                Exception e = (Exception) o;
                SQLException sqle = null;
                String dialect = null;

                log.debug(e);

                if (e instanceof SQLException) {
                    sqle = (SQLException) e;
                    log.debug("SQL error code: " + sqle.getErrorCode());
                    log.debug("SQL state: " + sqle.getSQLState());

                    // Filter exceptions.
                    dialect = config.getProperty("dialect");
                    if (dialect.equals("org.hibernate.dialect.MySQLDialect")
                            || dialect.equals("org.hibernate.dialect.MySQLInnoDBDialect")
                            || dialect.equals("org.hibernate.dialect.MySQLMyISAMDialect")) {
                        e = handleMySQLError(sqle);
                    }
                }

                if (e != null) {
                    errors.add(e);
                }
            }
        }
        return errors;
    }

    /**
     * Handles an specific MySQL error.
     * 
     * @param sqle
     *            The SQLException to be analysed.
     * 
     * @return The exception (if the error is unrecoverable) or null if the
     *         problem was solved (or simply ignored).
     */
    public Exception handleMySQLError(SQLException sqle) {
        switch (sqle.getErrorCode()) {
        case 1146:
            log.debug("Ignoring error", sqle);
            sqle = null;
            break;
        default:
            log.debug("Cannot recover from error", sqle);
        }
        return sqle;
    }

    /**
     * Create the database.
     * 
     * @throws RuntimeException
     *             If an error is found when running the DDL script.
     */
    public void createDB() {
        log.debug("Creating the database");
        log.debug(getCreateDDLScript());
        SchemaExport ddl = new SchemaExport(config);
        List<Exception> exceptions = null;

        ddl.create(false, true);
        exceptions = handleExceptions(ddl);
        if (!exceptions.isEmpty()) {
            throw new RuntimeException("exception.bootstrap.createdb", (Exception) ddl.getExceptions().get(0));
        }
    }

    /**
     * Update the database.
     * 
     * @throws RuntimeException
     *             If an error is found when running the DDL script.
     */
    public void updateDB() {
        log.debug("Updating the database");
        log.debug(getUpdateDDLScript());
        SchemaUpdate ddl = new SchemaUpdate(config);
        List<Exception> exceptions = null;

        ddl.execute(false, true);
        exceptions = handleExceptions(ddl);
        if (!exceptions.isEmpty()) {
            throw new RuntimeException("exception.bootstrap.updatedb", (Exception) ddl.getExceptions().get(0));
        }
    }

    /**
     * Drop the entire database.
     * 
     * @throws RuntimeException
     *             If an error is found when running the DDL script.
     */
    public void dropDB() {
        log.debug("Dropping the database");
        log.debug(getDropDDLScript());
        SchemaExport ddl = new SchemaExport(config);
        List<Exception> exceptions = null;

        ddl.drop(false, true);
        exceptions = handleExceptions(ddl);
        if (!exceptions.isEmpty()) {
            throw new RuntimeException("exception.bootstrap.dropdb", (Exception) ddl.getExceptions().get(0));
        }
    }

    /**
     * Get the DDL script to drop the database.
     */
    public String getDropDDLScript() {
        Dialect dialect = Dialect.getDialect(config.getProperties());
        String[] script = config.generateDropSchemaScript(dialect);
        return ArrayUtil.toString(script);
    }

    /**
     * Get the DDL script to create the database.
     */
    public String getCreateDDLScript() {
        Dialect dialect = Dialect.getDialect(config.getProperties());
        String[] script = config.generateSchemaCreationScript(dialect);
        return ArrayUtil.toString(script);
    }

    /**
     * Get the DDL script to update the database.
     */
    public String getUpdateDDLScript() {
        Dialect dialect = Dialect.getDialect(config.getProperties());
        Properties props = new Properties();
        //      ConnectionProvider connectionProvider = null;
        DatabaseMetadata dm = null;

        props.putAll(dialect.getDefaultProperties());
        props.putAll(config.getProperties());
        /*      connectionProvider = ConnectionProviderFactory.newConnectionProvider(props);
            
              try {
                 dm = new DatabaseMetadata(connectionProvider.getConnection(), dialect);
              } catch (SQLException e) {
                 log.debug("Could not get database DDL script", e);
              }
        */
        String[] script = config.generateSchemaUpdateScript(dialect, dm);
        return ArrayUtil.toString(script);
    }

    /**
     * Get the current Hibernate configuration.
     * 
     * @return Hibernate configuration.
     */
    public Configuration getConfig() {
        return config;
    }

    /**
     * Start the bootstrap.
     * 
     * @param home
     *            The application home directory.
     */
    public HibernateBootstrap() {
        log.debug("Loading Hibernate configuration");
        config = new Configuration();
        config.configure();
    }

}