É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?
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.
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;
}
}
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
vient de définir dbCreate="update"
, et les erreurs disparaissent immédiatement.
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;
};
}