Unsuccessful: alter table XXX drop constraint YYY in Hibernate/JPA/HSQLDB standalone

后端 未结 6 1441
忘掉有多难
忘掉有多难 2020-12-04 12:13

I am trying to run some Hibernate/JPA examples using an in-memory HSQL DB. The error message I get is the following:

13:54:21,427 ERROR SchemaExport:425 - HH         


        
相关标签:
6条回答
  • 2020-12-04 12:47

    This solution worked for me, as opposed to the other solution that's given. Apparently mileages vary.

    This was my exact error:

    HHH000389: Unsuccessful: alter table ... drop constraint FK_g1uebn6mqk9qiaw45vnacmyo2 if exists
    Table "..." not found; SQL statement: ...
    

    This is my solution, overriding the H2 dialect:

    package com.totaalsoftware.incidentmanager;
    
    import org.hibernate.dialect.H2Dialect;
    
    /**
     * Workaround.
     * 
     * @see https://hibernate.atlassian.net/browse/hhh-7002
     * 
     */
    public class ImprovedH2Dialect extends H2Dialect {
        @Override
        public String getDropSequenceString(String sequenceName) {
            // Adding the "if exists" clause to avoid warnings
            return "drop sequence if exists " + sequenceName;
        }
    
        @Override
        public boolean dropConstraints() {
            // We don't need to drop constraints before dropping tables, that just
            // leads to error messages about missing tables when we don't have a
            // schema in the database
            return false;
        }
    }
    
    0 讨论(0)
  • 2020-12-04 12:51

    Just set dbCreate="update", and the errors go away immediately.

    See: https://stackoverflow.com/a/31257468/715608

    0 讨论(0)
  • 2020-12-04 12:52

    The annoying error messages became more obnoxious stack traces at the start of every test using an in-memory database with HSQLDB and hbm2ddl.auto=create-drop.

    The response to an HSQLDB bug report suggested the use of DROP TABLE ... CASCADE rather than DROP CONSTRAINT IF EXISTS. Unfortunately the HSQLDB syntax for drop table is DROP TABLE <table> [IF EXISTS] [RESTRICT | CASCADE]; Hibernate Dialect does not provide an easy mechanism for a Dialect to specify CASCADE following the final IF EXISTS clause. I wrote a bug for this limitation.

    However, I was able to overcome the issue by creating a custom Dialect as follows:

    public class HsqlDialectReplacement extends HSQLDialect {
    
      @Override
      public String getDropTableString( String tableName ) {
        // Append CASCADE to formatted DROP TABLE string
        final String superDrop = super.getDropTableString( tableName );
        return superDrop + " cascade";
      }
    
      @Override
      public boolean dropConstraints() {
          // Do not explicitly drop constraints, use DROP TABLE ... CASCADE
          return false;
      }
    
      @Override
      public Exporter<Table> getTableExporter() {
        // Must override TableExporter because it also formulates DROP TABLE strings
        synchronized( this ) {
          if( null == overrideExporter ) {
            overrideExporter = new HsqlExporter( super.getTableExporter() );
          }
        }
    
        return overrideExporter;
      }
    
      private Exporter<Table> overrideExporter = null;
    
      private static class HsqlExporter implements Exporter<Table> {
        HsqlExporter( Exporter<Table> impl ) {
          this.impl = impl;
        }
    
        @Override
        public String[] getSqlCreateStrings( Table exportable, Metadata metadata ) {
          return impl.getSqlCreateStrings( exportable, metadata );
        }
    
        @Override
        public String[] getSqlDropStrings( Table exportable, Metadata metadata ) {
          final String[] implDrop = impl.getSqlDropStrings( exportable, metadata );
          final String[] dropStrings = new String[implDrop.length];
          for( int i=0; i<implDrop.length; ++i ) {
            dropStrings[i] = implDrop[i] + " cascade";
          }
          return dropStrings;
        }
    
        private final Exporter<Table> impl;
      };
    }
    
    0 讨论(0)
  • 2020-12-04 13:01

    You can ignore these errors. Combination of create-drop and empty (which is the case always for in-memory) database produces these for every database object it tries to drop. Reason being that there is not any database objects to remove - DROP statements are executed against empty database.

    Also with normal permanent database such a errors do come, because Hibernate does not figure out before executing DROP statements does added object exist in database or is it new.

    0 讨论(0)
  • 2020-12-04 13:05

    The Solution @Sander provided above works for MYSQL too. Just extend MySQL5InnoDBDialect instead like below:

    import org.hibernate.dialect.MySQL5InnoDBDialect;
    
    public class ImprovedMySQLDialect extends MySQL5InnoDBDialect {
        @Override
        public String getDropSequenceString(String sequenceName) {
            // Adding the "if exists" clause to avoid warnings
            return "drop sequence if exists " + sequenceName;
        }
    
        @Override
        public boolean dropConstraints() {
            // We don't need to drop constraints before dropping tables, that just leads to error
            // messages about missing tables when we don't have a schema in the database
            return false;
        }
    }
    

    Then in your datasource file change the following line:

    dialect = org.hibernate.dialect.MySQL5InnoDBDialect
    

    to

    dialect = my.package.name.ImprovedMySQLDialect
    
    0 讨论(0)
  • 2020-12-04 13:09

    We faced same issue while trying to create a simple login window in Spring. There were two tables user and role both with primary key id type of BIGINT. These we mapped (Many-to-Many) into another table user_roles with two columns user_id and role_id as foreign keys.

    The problem was the role_id column in user_roles table, it was of int type and not compatible for the foreign key to role. When the type was modified to BIGINT errors were rectified.

    0 讨论(0)
提交回复
热议问题