Changeset 5388


Ignore:
Timestamp:
Aug 17, 2010, 10:01:25 AM (13 years ago)
Author:
Nicklas Nordborg
Message:

References #1488: Update to Hibernate 3.5.2

Fixes problems with schema update by replacing the Hibernate tool with our own implementation. Most of the work is still done by Hibernate, but we now have the chance to modify or skip certain SQL statements.

Location:
trunk
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/config/dist/log4j.properties

    r4740 r5388  
    7474### log schema export/update ###
    7575#log4j.logger.org.hibernate.tool.hbm2ddl=debug
     76#log4j.logger.net.sf.basedb.core.hibernate.SchemaGenerator=debug
    7677
    7778### log HQL parse trees
  • trunk/src/core/net/sf/basedb/core/HibernateUtil.java

    r5386 r5388  
    4141import net.sf.basedb.core.hibernate.EntityQueryWrapper;
    4242import net.sf.basedb.core.hibernate.ExecuteUpdateWork;
     43import net.sf.basedb.core.hibernate.SchemaGenerator;
    4344import net.sf.basedb.core.hibernate.TypeWrapper;
    4445import net.sf.basedb.core.hibernate.JdbcWork;
     
    9091import org.hibernate.mapping.PrimaryKey;
    9192import org.hibernate.cfg.Configuration;
    92 import org.hibernate.tool.hbm2ddl.SchemaExport;
    93 import org.hibernate.tool.hbm2ddl.SchemaUpdate;
    9493import org.hibernate.metadata.ClassMetadata;
    9594import org.hibernate.dialect.Dialect;
     
    504503 
    505504  /**
    506     Create the all tables in the database. We use the {@link SchemaUpdate} tool
    507     provided by Hibernate. The database must exists and we recommend that
    508     it is empty to begin with.
    509   */
    510   static void createStaticTables(boolean update)
     505    Create the all tables in the database. The database must exists and we
     506    recommend that it is empty to begin with.
     507  */
     508  static void createStaticTables(boolean update, ProgressReporter progress)
    511509    throws BaseException
    512510  {
    513511    assert sf != null : "HibernateUtil has not been initialised";
    514     if (!update && !isEmptyDatabase())
    515     {
    516       throw new BaseException("Database already has tables.");
    517     }
    518     try
    519     {
    520       List exceptions;
    521       if (update)
     512
     513    if (update)
     514    {
     515      int currentSchemaVersion = Application.getSchemaVersion();       
     516      if (currentSchemaVersion < 0)
    522517      {
    523         int currentSchemaVersion = Application.getSchemaVersion();       
    524         if (currentSchemaVersion < 0)
    525         {
    526           throw new BaseException("Couldn't load current schema version of database");
    527         }
    528         else if (Install.NEW_SCHEMA_VERSION < currentSchemaVersion)
    529         {
    530           throw new BaseException("Can't update to schema version " + Install.NEW_SCHEMA_VERSION +
    531               " of database, cause you already have schema version " + currentSchemaVersion + " installed");
    532         }
    533         // Note! This doesn't create indexes correctly. Use dbIndexes method.
    534         SchemaUpdate se = new SchemaUpdate(cfg);
    535         se.setHaltOnError(true);
    536         se.execute(false, true);
    537         exceptions = se.getExceptions();
     518        throw new BaseException("Couldn't load current schema version of database");
    538519      }
    539       else
     520      else if (Install.NEW_SCHEMA_VERSION < currentSchemaVersion)
    540521      {
    541         SchemaExport se = new SchemaExport(cfg);
    542         se.setHaltOnError(true);
    543         se.execute(false, true, false, true);
    544         exceptions = se.getExceptions();
     522        throw new BaseException("Can't update to schema version " + Install.NEW_SCHEMA_VERSION +
     523            " of database, cause you already have schema version " + currentSchemaVersion + " installed");
    545524      }
    546       if (exceptions != null && exceptions.size() > 0)
     525    }
     526    else
     527    {
     528      if (!isEmptyDatabase())
    547529      {
    548         throw new BaseException((Throwable)exceptions.get(0));
     530        throw new BaseException("Database already has tables.");
    549531      }
    550532    }
    551     catch (HibernateException ex)
    552     {
    553       throw new BaseException(ex);
     533
     534    Session session = null;
     535    Transaction tx = null;
     536    try
     537    {
     538      SchemaGenerator schemaGenerator = new SchemaGenerator(cfg, dialect, dbEngine, update, progress);
     539      session = HibernateUtil.newSession();
     540      tx = HibernateUtil.newTransaction(session);
     541      session.doWork(schemaGenerator);
     542      HibernateUtil.commit(tx);
     543    }
     544    catch (Exception ex)
     545    {
     546      if (tx != null) HibernateUtil.rollback(tx);
     547      throw new BaseException(ex);
     548    }
     549    finally
     550    {
     551      if (session != null) HibernateUtil.close(session);
    554552    }
    555553  }
  • trunk/src/core/net/sf/basedb/core/Install.java

    r5384 r5388  
    8282import java.util.HashMap;
    8383import java.util.Set;
    84 import java.util.TimerTask;
    8584
    8685import org.jdom.Document;
     
    122121  {
    123122    String message = "";
    124     TimerTask timer = null;
    125     if (progress != null)
    126     {
    127       progress.display(0, "Building database...");
    128       // The timer will append a dot to the progress reporter every second
    129       timer = new TimerTask()
    130         {
    131           public void run()
    132           {
    133             progress.append(".");
    134           }
    135         };
    136     }
    137     try
    138     {
    139       if (timer != null) Application.getCoreTimer().schedule(timer, 1000, 1000);
     123    try
     124    {
    140125      Application.start(true, false, false);
    141       HibernateUtil.createStaticTables(update);
     126      if (progress != null) progress.display(0, "Building database...");
     127      HibernateUtil.createStaticTables(update, progress);
    142128      message = "Database built successfully.";
    143129    }
     
    149135    finally
    150136    {
    151       if (timer != null)
    152       {
    153         timer.cancel();
    154         timer = null;
    155       }
    156137      if (progress != null)
    157138      {
  • trunk/src/core/net/sf/basedb/core/Update.java

    r5384 r5388  
    28572857      // Commit the changes
    28582858      HibernateUtil.commit(tx);
    2859       log.info("updateToSchemaVersion79: OK");
     2859      log.info("updateToSchemaVersion80: OK");
    28602860    }
    28612861    catch (BaseException ex)
    28622862    {
    28632863      if (tx != null) HibernateUtil.rollback(tx);
    2864       log.error("updateToSchemaVersion79: FAILED", ex);
     2864      log.error("updateToSchemaVersion80: FAILED", ex);
    28652865      throw ex;
    28662866    }
  • trunk/src/core/net/sf/basedb/core/dbengine/AbstractDbEngine.java

    r4912 r5388  
    2323
    2424import java.util.regex.Pattern;
     25
     26import org.hibernate.dialect.Dialect;
    2527
    2628/**
     
    177179    return null;
    178180  }
     181  /**
     182    Remove "not null" constraints from "alter table ... add column"
     183    statements that doesn't supply a default value for the new column
     184    when updating.
     185    @since 2.16
     186  */
     187  @Override
     188  public String inspectSchemaGenerationSQL(String sql, Dialect dialect,
     189      boolean update)
     190  {
     191    String addColumn = dialect.getAddColumnString();
     192    if (update && sql.contains("alter table") && sql.contains(addColumn) &&
     193        sql.contains("not null") && !sql.contains("default"))
     194    {
     195      sql = sql.replace("not null", "");
     196    }
     197    return sql;
     198  }
     199
    179200  // -------------------------------------------
    180201
  • trunk/src/core/net/sf/basedb/core/dbengine/DbEngine.java

    r4912 r5388  
    2424
    2525import java.util.Set;
     26
     27import net.sf.basedb.core.hibernate.SchemaGenerator;
    2628
    2729import org.hibernate.dialect.Dialect;
     
    314316  public String getCaseSensitiveVarchar(int length);
    315317 
     318  /**
     319    Let the DbEninge inspect a schema generation sql statment and
     320    possible modify it before it is sent to the database. This
     321    method is called from the {@link SchemaGenerator} class
     322    when creating or updating a database.
     323    @param sql The original SQL statment as generated by Hibernate
     324    @param dialect The Hibernate dialect currently in use
     325    @param update TRUE if we are updating an existing database,
     326      FALSE if we are creating a new one
     327    @return The SQL statement which may have been modified or null
     328      to skip executing the statment
     329    @since 2.16
     330  */
     331  public String inspectSchemaGenerationSQL(String sql, Dialect dialect, boolean update);
     332 
    316333}
  • trunk/src/core/net/sf/basedb/core/dbengine/PostgresDbEngine.java

    r4517 r5388  
    2323
    2424import java.util.Set;
     25
     26import org.hibernate.dialect.Dialect;
    2527
    2628/**
     
    209211    return value + " ~ " + regexp;
    210212  }
     213  /**
     214    Skip all "create index" statements since Hibernate doesn't generate those
     215    with unique names. PostgreSQL users should always run the ./updateindexes.sh
     216    tool which will create the missing indexes.
     217    @since 2.16
     218  */
     219  @Override
     220  public String inspectSchemaGenerationSQL(String sql, Dialect dialect,
     221      boolean update)
     222  {
     223    sql = super.inspectSchemaGenerationSQL(sql, dialect, update);
     224    if (sql != null && sql.startsWith("create index"))
     225    {
     226      sql = null;
     227    }
     228    return sql;
     229  }
    211230  // -------------------------------------------
    212231 
Note: See TracChangeset for help on using the changeset viewer.