2010-09-27 10 views
13

Estoy configurando un servicio Java independiente con una base de datos HSQL en proceso en la memoria.La base de datos HSQL interna se queja de los privilegios

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="manager"> 

<class>tr.silvercar.data.entities.User</class> 
<properties> 
<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" /> 
<property name="javax.persistence.jdbc.user" value="sa" /> 
<property name="javax.persistence.jdbc.password" value="" /> 
<property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:testdb" /> 

<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" /> 
<property name="hibernate.max_fetch_depth" value="3" /> 

<!-- cache configuration --> 
<!-- 
<property name="hibernate.ejb.classcache.org.hibernate.ejb.test.Item" 
    value="read-write" /> 
<property 
    name="hibernate.ejb.collectioncache.org.hibernate.ejb.test.Item.distributors" 
    value="read-write, RegionName" /> 
--> 
</properties> 

</persistence-unit> 

</persistence> 

Código

emf = Persistence.createEntityManagerFactory("manager"); 

    User newUser = new User(); 
    newUser.setName("Testgebruiker"); 
    newUser.setCredits(100); 

    System.out.println("Inserting user"); 
    EntityManager em = emf.createEntityManager(); 
    em.persist(newUser); 
    em.close(); 

    System.out.println("Getting user"); 
    em = emf.createEntityManager(); 
    User u = (User) em.createQuery("SELECT u FROM User u").getSingleResult(); 
    em.close(); 
    System.out.println(u); 

Parecería a mí que desde la base de datos está en la memoria, y Hibernate debe generar tablas, para que no lo hago Necesito hacer otra cosa. Sin embargo, al llamar getSingleResult consigo la excepción:

org.hsqldb.HsqlException: user lacks privilege or object not found: USER 
+0

No sé qué está sucediendo allí con esto en la base de datos de memoria ...: S Tal vez [fredt] (http://stackoverflow.com/users/361828/fredt) aparecerá con una buena explicación. Por si acaso, ¿qué versión de HSQLDB estás usando? –

+0

@Pascal Estoy usando 2.0 –

+0

Quizás intente con 1.8.1.3, solo para estar seguro. –

Respuesta

14

Es necesario utilizar Hibernate 3.5.6 o posterior, junto con la versión 2.2.x HSQLDB o posterior. De lo contrario, las jarras Hibernte más antiguas funcionan con HSQLDB 1.8.x. El nombre de la tabla no es un problema. He desarrollado el dialecto y ejecuto las pruebas de Hibernate para esta versión, pero Pascal sabe mucho más sobre el uso de Hibernate que yo y ha ayudado a mucha gente aquí.

+0

Interesante, no estaba al tanto de estos requisitos (¿restricciones?) En las versiones. +1 –

+1

Me encontré con esta pregunta después de obtener el mismo error después de agregar una nueva columna a una entidad que chocó con una palabra reservada de SQL - 'WHEN' en este caso. Las propiedades de la entidad no se enumeran en la pregunta, pero en mi caso, al agregar una anotación con escape (backticks) se resolvió el problema: '' @Column (name = "' when' ")' '. Tal vez el nombre de la columna simplemente apesta :-) – penfold

+0

¿Hibernate actualmente es compatible con HSQLDB 2.2.8? – Bas

0

Yo también he enfrentado el mismo error. Se resolvió cuando di la ruta de acceso absoluta del archivo de script en "connection.url".

< property name = "connection.url"> JDBC: hsqldb: file: C: \ Hibernate-ejemplo \ database \ mibd; apagado = true </property>

+0

Gracias, pero estoy usando una base de datos almacenada en la memoria, no en un archivo. –

0

Cuando tuve este error, me di cuenta que estaba usando la clase de proveedor de mal en persistence.xml

Para Hibernate debe ser

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

Y para EclipseLink debe ser

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 

también debe tener en cuenta que los diferentes nombres se utilizan en persistence.xml y al crear Persistence.createEntityManagerFactory("name")

12

Me encuentro con el mismo problema y ninguna de las soluciones proporcionadas (realmente) me ayudó (y hay bastantes más publicaciones aquí en Stackoverflow que están estrechamente relacionadas), pero finalmente lo descubrí. Por lo tanto, pensé en compartir mis hallazgos (lo siento por la publicación un poco larga):

En mi caso convertí algunos UnitTests existentes utilizando una base de datos MySQL a HSQLDB para que la dependencia externa se pueda eliminar. Todo esto parece fácil si observas descripciones como: http://eskatos.wordpress.com/2007/10/15/unit-test-jpa-entities-with-in-memory-database/ Pero resultó ser un poco más complicado.

I experimentaron con

  1. versiones diferentes (como se sugiere más arriba),
  2. los parámetros create y ifexists (ver: http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html),
  3. especificando diferentes credenciales de usuario (nombre de usuario = "sa", contraseña = "" es correcto),
  4. especificando actualizar, crear y crear-soltar como hibernate.hbm2ddl.auto (ver http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html),
  5. el uso de diferentes tipos de DataSources: c3p0, el DBCP, ...
  6. ...

Pero ninguno de los que realmente hizo ninguna diferencia (los errores se diferenciaba por cierto.). Aparte del mensaje user lacks privilege or object not found de error, el más informativo que pude conseguir fue la siguiente: SQL Error: -20, SQLState: IM001 (que se traduce como "Controlador no admite esta función") e incluso de manera más explícita encontré esto en los registros: [2012-09-24 14:50:45,796] ERROR main::org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions(144) | This function is not supported

Entonces algo claramente se rompió. Resulta que mayor problema resulta ser una combinación de dos cosas: 1. Me sin mirar adecuadamente a través de la salida del registro, ya que en realidad contenía la clave 2. Una anotación errónea

En cuanto a 1:

el problema fue que la salida contiene una gran cantidad de líneas que se parecían a los siguientes (which can apparently be ignored, y hay incluso una ticket for H2):

[2012-09-25 10:07:13,453] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(426) | HHH000389: Unsuccessful: alter table SimpleSubscription drop constraint FKAD76A00F168752B2 
[2012-09-25 10:07:13,453] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(427) | user lacks privilege or object not found: PUBLIC.SIMPLESUBSCRIPTION 
Hibernate: alter table SimpleSubscriptionChange drop constraint FKB3B8189FFC3506ED 
[2012-09-25 10:07:13,453] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(426) | HHH000389: Unsuccessful: alter table SimpleSubscriptionChange drop constraint FKB3B8189FFC3506ED 
[2012-09-25 10:07:13,453] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(427) | user lacks privilege or object not found: PUBLIC.SIMPLESUBSCRIPTIONCHANGE 
Hibernate: alter table SimpleSubscriptionChange_languages drop constraint FK5A45F07BFC21A8E6 

En cuanto a 2:

Entre todas esas líneas estaban ocultas las siguientes líneas, que en realidad regala lo que es el error:

[2012-09-25 10:07:13,468] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(426) | HHH000389: Unsuccessful: create table Rule (id bigint generated by default as identity (start with 1), creationTime timestamp not null, deleted BIT not null, lastUpdateTime timestamp, version integer not null, fetcher varchar(255), hash integer not null, primary key (id), unique (id)) 
[2012-09-25 10:07:13,468] ERROR main::org.hibernate.tool.hbm2ddl.SchemaExport.perform(427) | a UNIQUE constraint already exists on the set of columns in statement [create table Rule (id bigint generated by default as identity (start with 1), creationTime timestamp not null, deleted BIT not null, lastUpdateTime timestamp, version integer not null, fetcher varchar(255), hash integer not null, primary key (id), unique (id))] 

Así que la cuestión es que el BaseEntity que se define tiene una anotación errónea de la identificación:

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
@Column(nullable = false, unique = true) 
private Long id; 

El campo ya está identificado como una ID (es decir, como clave principal), y por lo tanto no puede tener una anotación única (y también el nullable es superfluo). El cambio de este a:

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
@Column(name = "id") 
private Long id; 

y todo funciona bien :-)

+1

El problema de la anotación de identificación errónea para la identificación también me ayudó en mi caso. Muchas gracias por compartir. SQLserver parece ser menos estricto en las anotaciones erróneas (o redundantes) ... –

+0

Cambiar GenerationType de AUTO a IDENTITY funciona para mí – dalvarezmartinez1

0

Pruebe explícitamente especificando el nombre de esquema de la tabla/secuencia se hace referencia.

Acabo de enfrentar un problema similar en el que no se reconocía mi secuencia y luego me di cuenta de que en mi anotación Hibernate @ SequenceGenerator no añadí el esquema a la secuencia ref.

call next value for EXAMPLE_SCHEMA.TEST_SEQ 
4

Me encontré con un problema similar, pero en mi caso el problema ocurrió debido a las definiciones de columna.He utilizado las definiciones de MySQL de esta manera:

@Id 
@GeneratedValue 
@Column(columnDefinition = "INT(11)") 
private long id; 

Esto parece no ser apoyado por HSQL, y he cambiado la definición de esto:

@Id 
@GeneratedValue 
@Column(columnDefinition = "INTEGER") 
private long id; 

Y entonces las pruebas trabajado de nuevo.

+0

¡¡Gracias !! Esto solucionó el problema en mi caso. –

+0

¡Gracias! funcionó para mí ... En realidad usé @Column (columnDefinition = "text") – Darshan

0

HSQL no utiliza el longtext pero el tipo LONGVARCHAR. Cambiarlo resolvió un problema similar para mí, donde se quejaba de los privilegios necesarios.

Cuestiones relacionadas