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

j'essaye d'exécuter quelques exemples D'hibernation/JPA en utilisant un DB HSQL en mémoire. Le message d'erreur que je reçois est le suivant:

13:54:21,427 ERROR SchemaExport:425 - HHH000389: Unsuccessful: alter table ReferringItem_map drop constraint FK5D4A98E0361647B8
13:54:21,427 ERROR SchemaExport:426 - user lacks privilege or object not found: PUBLIC.REFERRINGITEM_MAP
13:54:21,427 ERROR SchemaExport:425 - HHH000389: Unsuccessful: alter table ReferringItem_myCollection drop constraint FK75BA3266361647B8
13:54:21,427 ERROR SchemaExport:426 - user lacks privilege or object not found: PUBLIC.REFERRINGITEM_MYCOLLECTION
13:54:21,428 ERROR SchemaExport:425 - HHH000389: Unsuccessful: alter table ReferringItem_myList drop constraint FK6D37AA66361647B8
13:54:21,428 ERROR SchemaExport:426 - user lacks privilege or object not found: PUBLIC.REFERRINGITEM_MYLIST
13:54:21,428 ERROR SchemaExport:425 - HHH000389: Unsuccessful: alter table ReferringItem_mySet drop constraint FK3512699A361647B8
13:54:21,429 ERROR SchemaExport:426 - user lacks privilege or object not found: PUBLIC.REFERRINGITEM_MYSET

la classe correspondante est:

@Entity
public class ReferringItem implements Serializable {

    @Id
    private long id;

    @ElementCollection
    private Collection<AnEmbeddable> myCollection
        = new ArrayList<AnEmbeddable>();

    @ElementCollection(fetch=FetchType.EAGER)
    private Set<Long> mySet = new HashSet<Long>();

    @ElementCollection(targetClass=String.class)
    private List myList = new ArrayList();

    @ElementCollection
    private Map<String,AnEmbeddable> map
        = new HashMap<String,AnEmbeddable>();

    public ReferringItem() { }

    // Setters & Getters

}

La intégrable est:

@Embeddable
public class AnEmbeddable implements Serializable {

    private String s;

    public AnEmbeddable() { }

    public String getS() {
        return s;
    }

    public void setS(String s) {
        this.s = s;
    }

}

Mon persistence.xml :

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">

    <persistence-unit name="JPA" transaction-type="RESOURCE_LOCAL">

        <provider>org.hibernate.ejb.HibernatePersistence</provider>

        <class>com.jverstry.jpa.AuthorizedTypes.AuthorizedTypes</class>
        <class>com.jverstry.jpa.AuthorizedTypes.OtherEntity</class>
        <class>com.jverstry.jpa.AuthorizedTypes.SomeEmbeddable</class>

        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:testdb"/>
            <property name="javax.persistence.jdbc.user" value="sa"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>

    </persistence-unit>

</persistence>

je suis en hibernation 4.1.5.Final et HSQLDB 2.2.8 .

est-ce que quelqu'un sait ce qui cause ce problème et comment le résoudre?

38
demandé sur Jérôme Verstrynge 2012-08-21 16:03:07

5 réponses

Vous pouvez ignorer ces erreurs. La combinaison de create-drop et de la base de données en mémoire Produit ceux-ci pour chaque objet de base de données qu'il essaie de laisser tomber. La raison étant qu'il n'y a pas d'objets de base de données à supprimer - les instructions DROP sont exécutées contre une base de données vide.

aussi avec la base de données permanente normale de telles erreurs viennent, parce que Hibernate ne comprend pas avant d'exécuter des déclarations de chute est-ce que l'objet ajouté existe dans la base de données ou est-il Nouveau.

51
répondu Mikko Maunu 2012-08-21 13:08:10

Cette solution a fonctionné pour moi, par opposition à l'autre solution qui est donnée. Apparemment, les distances varient.

C'était mon erreur exacte:

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

C'est ma solution, supplantant le dialecte H2:

package com.totaalsoftware.incidentmanager;

import org.hibernate.dialect.H2Dialect;

/**
 * Workaround.
 * 
 * @see https://hibernate.onjira.com/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;
    }
}
27
répondu Sander Verhagen 2013-12-20 07:21:28

la Solution @Sander fournie ci-dessus fonctionne aussi pour MYSQL. Il suffit D'étendre MySQL5InnoDBDialect à la place comme ci-dessous:

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;
    }
}

ensuite, dans votre fichier datasource, changez la ligne suivante:

dialect = org.hibernate.dialect.MySQL5InnoDBDialect

à

dialect = my.package.name.ImprovedMySQLDialect
12
répondu Emmanuel John 2014-12-16 13:55:42

vient de définir dbCreate="update" , et les erreurs disparaissent immédiatement.

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

11
répondu 10GritSandpaper 2017-05-23 10:31:15

les messages d'erreur gênants sont devenus des traces de pile plus désagréables au début de chaque test en utilisant une base de données en mémoire avec HSQLDB et hbm2ddl.auto=create-drop.

la réponse à un rapport de bogue HSQLDB suggérait l'utilisation d'une table de chute ... Contrainte de CASCADE plutôt que de chute si elle existe. Malheureusement, la syntaxe HSQLDB pour drop table est DROP TABLE <table> [IF EXISTS] [RESTRICT | CASCADE]; . après la clause finale de L'IF EXISTS. J'ai écrit un bug pour cette limitation.

cependant, j'ai pu surmonter le problème en créant un dialecte personnalisé comme suit:

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;
  };
}
2
répondu wbdarby 2016-07-12 15:43:51