java - diferencia - jpa vs hibernate
No exitoso: altere la restricción de caída de la tabla XXX YYY en Hibernate/JPA/HSQLDB independiente (5)
Esta solución funcionó para mí, a diferencia de la otra solución que se da. Aparentemente, los kilómetros varían.
Este fue mi error exacto:
HHH000389: Unsuccessful: alter table ... drop constraint FK_g1uebn6mqk9qiaw45vnacmyo2 if exists
Table "..." not found; SQL statement: ...
Esta es mi solución, anulando el dialecto 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;
}
}
Estoy intentando ejecutar algunos ejemplos de Hibernate / JPA usando un DB HSQL en memoria. El mensaje de error que recibo es el siguiente:
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 clase correspondiente es:
@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
}
El incrustable es:
@Embeddable
public class AnEmbeddable implements Serializable {
private String s;
public AnEmbeddable() { }
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
}
Mi 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>
Estoy en Hibernate 4.1.5.Final
y HSQLDB 2.2.8
.
¿Alguien sabe qué está causando este problema y cómo resolverlo?
La Solución @Sander proporcionada anteriormente también funciona para MYSQL. Simplemente extienda MySQL5InnoDBDialect en su lugar como se muestra a continuación:
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;
}
}
Luego, en su archivo de fuente de datos, cambie la siguiente línea:
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
a
dialect = my.package.name.ImprovedMySQLDialect
Los mensajes de error molestos se convirtieron en rastros de pila más desagradables al comienzo de cada prueba usando una base de datos en memoria con HSQLDB y hbm2ddl.auto = create-drop.
La respuesta a un informe de error HSQLDB sugirió el uso de DROP TABLE ... CASCADE en lugar de DROP CONSTRAINT IF EXISTS. Desafortunadamente, la sintaxis de HSQLDB para la tabla desplegable es DROP TABLE <table> [IF EXISTS] [RESTRICT | CASCADE];
DROP TABLE <table> [IF EXISTS] [RESTRICT | CASCADE];
Hibernate Dialect no proporciona un mecanismo fácil para que un dialecto especifique CASCADE siguiendo la cláusula final IF EXISTS. Escribí un error para esta limitación.
Sin embargo, pude superar el problema creando un dialecto personalizado de la siguiente manera:
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;
};
}
Puede ignorar estos errores. La combinación de create-drop
base de datos de create-drop
en memoria produce estos para cada objeto de base de datos que intenta descartar. La razón es que no hay objetos de la base de datos para eliminar: las declaraciones DROP se ejecutan contra la base de datos vacía.
También con la base de datos permanente normal, tales errores llegan, porque Hibernate no se da cuenta antes de ejecutar las declaraciones DROP si el objeto agregado existe en la base de datos o si es nuevo.
Simplemente configure dbCreate="update"
, y los errores desaparecerán inmediatamente.
Ver: https://.com/a/31257468/715608