Неудачно: изменение ограничения отбрасывания таблицы XXX YYY в автономном режиме Hibernate/JPA/HSQLDB

Я пытаюсь запустить некоторые примеры Hibernate/JPA, используя базу данных HSQL в памяти. Сообщение об ошибке, которое я получаю, следующее:

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

Соответствующий класс:

@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

}

Встраиваемый:

@Embeddable
public class AnEmbeddable implements Serializable {

    private String s;

    public AnEmbeddable() { }

    public String getS() {
        return s;
    }

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

}

My 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>

Я в Hibernate 4.1.5.Final и HSQLDB 2.2.8.

Кто-нибудь знает, что вызывает эту проблему и как ее решить?


person Jérôme Verstrynge    schedule 21.08.2012    source источник


Ответы (6)


Вы можете игнорировать эти ошибки. Комбинация create-drop и пустой (что всегда имеет место для in-memory) базы данных создает их для каждого объекта базы данных, который он пытается удалить. Причина в том, что нет никаких объектов базы данных для удаления - операторы DROP выполняются для пустой базы данных.

Также с обычной постоянной базой данных такие ошибки возникают, потому что Hibernate не выясняет перед выполнением операторов DROP, существует ли добавленный объект в базе данных или он новый.

person Mikko Maunu    schedule 21.08.2012
comment
Отлично, я, хотя это была проблема в моем коде, которую я не мог найти. Большое спасибо. - person Jérôme Verstrynge; 21.08.2012
comment
Проблема заключается в hibernate.onjira.com/browse/HHH-7002, и я наблюдая такое же поведение с MySQL, так что не только в БД памяти. - person Eugen; 21.11.2012
comment
Кажется, эта проблема исправлена ​​в hibernate 4.3.0 beta 4, поэтому я думаю, что она должна быть в следующем выпуске. hibernate.atlassian.net/browse/HHH-7002 - person TahitianGabriel; 24.07.2013
comment
Я обновился до 4.3.0.Final и все еще вижу ошибку, или в моем случае может быть немного другую: HHH000389: Unsuccessful: alter table ... drop constraint FK_g1uebn6mqk9qiaw45vnacmyo2 if exists и Table "..." not found; SQL statement: ... - person Sander Verhagen; 20.12.2013
comment
Проблема JIRA указывает на коммит GitHub, который содержит изменения в диалекте HSQLDB. Этот вопрос был о H2, и @Eugen упомянул MySQL. Не то же самое. - person Sander Verhagen; 20.12.2013
comment
Я работаю с HSQLDB 2.3.2 и Hibernate 4.3.8, и все равно получаю предупреждение. - person borjab; 27.01.2015
comment
Я работаю с HSQLDB 2.4.0 и Hibernate 4.3.8, все равно получаю ошибку - person McCoy; 06.03.2018
comment
Вы можете игнорировать эти ошибки. каждый раз, когда вы игнорируете ошибку, умирает маленькая панда... #truestory - person GabrielOshiro; 13.09.2018

Это решение сработало для меня, в отличие от другого решения, которое было дано. Видимо пробеги разные.

Это была моя точная ошибка:

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

Это мое решение, переопределяющее диалект H2:

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;
    }
}
person Sander Verhagen    schedule 20.12.2013
comment
Точно так же работает и для hsqldb (org.hibernate.dialect.HSQLDialect) - person gclaussn; 05.01.2015
comment
Обратите внимание, что если вы используете что-то вроде jdbc:h2:mem:play;MODE=MYSQL, ваш диалект по-прежнему является диалектом H2. - person rhmiller_ic; 24.11.2015

Приведенное выше решение @Sander работает и для MYSQL. Просто расширьте MySQL5InnoDBDialect, как показано ниже:

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

Затем в файле источника данных измените следующую строку:

dialect = org.hibernate.dialect.MySQL5InnoDBDialect

to

dialect = my.package.name.ImprovedMySQLDialect
person Emmanuel John    schedule 14.10.2014
comment
и где вы добавляете свой класс в приложение Grails (очевидно, что его нет ни в одной из папок контроллеров/доменов/представлений? - person PathOfNeo; 24.01.2015
comment
Я обычно помещаю его в src/groovy. Просто убедитесь, что вы используете правильное имя пакета. - person Emmanuel John; 24.01.2015
comment
Спасибо, я сделал это. К сожалению, я сдался после X часов попыток сделать все возможное. Я принял тот факт, что мне нужно вручную удалять/создавать мою схему в MySQL каждый раз, когда я меняю отношения в классах домена Grails. - person PathOfNeo; 26.01.2015
comment
К сожалению, это не сработало, оно заглушило ошибки, но вызвало другие ошибки в будущем. В зависимости от вашей схемы базы данных это может работать или не работать для вас. - person lijat; 03.09.2018

Просто установите dbCreate="update", и ошибки сразу исчезнут.

См.: https://stackoverflow.com/a/31257468/715608

person 10GritSandpaper    schedule 06.07.2015

Раздражающие сообщения об ошибках стали еще более неприятными трассировками стека в начале каждого теста с использованием базы данных в памяти с HSQLDB и hbm2ddl.auto=create-drop.

В ответе на отчет об ошибке HSQLDB предлагается использовать DROP TABLE ... CASCADE, а не DROP CONSTRAINT, ЕСЛИ СУЩЕСТВУЕТ. К сожалению, синтаксис HSQLDB для отбрасываемой таблицы таков: DROP TABLE <table> [IF EXISTS] [RESTRICT | CASCADE]; Hibernate Dialect не предоставляет для диалекта простого механизма указания CASCADE после последнего предложения IF EXISTS. Я написал ошибку для этого ограничения.

Однако мне удалось решить эту проблему, создав собственный диалект следующим образом:

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;
  };
}
person wbdarby    schedule 12.07.2016
comment
Я не могу это скомпилировать, не знаю, откуда импортировать экспортер. Моя версия Hibernate — 4.3.8. - person McCoy; 05.03.2018
comment
Я получил это для компиляции с использованием импорта, используемого здесь github.com/Bato/demo-jpa/blob/master/src/main/java/eu/mh/jpa/ похоже на версию этого кода. Импорт где: import org.hibernate.boot.Metadata; импортировать org.hibernate.dialect.HSQLDialect; импортировать org.hibernate.mapping.Table; импортировать org.hibernate.tool.schema.spi.Exporter; - person lijat; 03.09.2018

Мы столкнулись с той же проблемой при попытке создать простое окно входа в систему в Spring. Были две таблицы user и role с типом первичного ключа id BIGINT. Мы сопоставили их (Many-to-Many) с другой таблицей user_roles с двумя столбцами user_id и role_id в качестве внешних ключей.

Проблема заключалась в столбце role_id в таблице user_roles, он имел тип int и несовместим для внешнего ключа с role. При изменении типа на BIGINT ошибки были исправлены.

person Arun Sudhakaran    schedule 03.08.2019