2011-11-12 17 views
5

simplemente configuré un proyecto hasta ahora bastante minimalista proyecto maven/jpa/hibernate, donde intento persistir un objeto.EntityManager no escribe en la base de datos

Mi clase es un muy simple:

@Entity 
public class Person { 
    @Id @GeneratedValue 
    private int id; 
    private String name; 
} 

Mi persistence.xml es muy básico, así:

<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="Fahrplan_v2"> 
     <class>model.Person</class> 
     <properties> 
      <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" /> 
      <property name="hibernate.connection.url" value="jdbc:hsqldb:file:data/db/db" /> 
      <property name="hibernate.connection.username" value="sa" /> 
      <property name="hibernate.connection.password" value="" /> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" /> 
      <property name="hibernate.hbm2ddl.auto" value="update" /> 
     </properties> 
    </persistence-unit> 
</persistence> 

Y, por último, aquí está el código que utilizo para conservar el objeto:

EntityManager em = entityManagerFactory.createEntityManager(); 
em.getTransaction().begin(); 
em.persist(person); 
// em.flush(); <- does not effect outcome. 
em.getTransaction().commit(); 
em.close(); 

Ahora hay dos cosas que esperaría que ocurrieran aquí: Primero, esperaría que la tabla Person fuera cr eated (debido a hibernate.hbm2ddl.auto = update). Esto ha sucedido una vez, y escribió correctamente

CREATE MEMORY TABLE PUBLIC.PERSON(
    ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY, 
    NAME VARCHAR(255) 
) 

pero no puedo reproducir eso en absoluto. Cada vez que inicio mi programa, se crean los archivos de la base de datos hsqldb, pero no se crean tablas.

En segundo lugar, esperaría que el objeto persistente se almacenara en la base de datos, pero no es así. Además, la creación manual del esquema de la base de datos no resuelve el problema, así que eso no es lo que lo está causando. El código persistente se ejecuta sin excepciones o advertencias en la salida, todo se ve perfectamente bien. Pero el objeto simplemente no llega a la base de datos. El objeto tampoco se encuentra cuando se consulta al administrador de entidades con un "de Persona".

Sin embargo, la consulta parece ser lo único que SI FUNCIONA. Puedo insertar manualmente un dato en la base de datos y la consulta "de persona" lo recuperará con éxito.

entonces, ¿hay algún indicio de lo que estoy haciendo mal aquí?

+1

Hum bien, así que voy a publicar como un comentario porque yo no estoy autorizado para responder a mi propia pregunta (¿todavía?): me encontré con mi problema. em.getTransaction(). commit(); Thread.sleep (1000); em.close(); hizo el truco. después de mi caso de prueba, la JVM se cerró tan rápido que hsqldb simplemente no tuvo tiempo suficiente para conservar los datos comprometidos en el disco. No me preguntes por qué la JVM no se mantiene activa, no hago ninguna llamada a System.exit() ni nada, mi método de prueba junit simplemente termina ahí. Por alguna razón, la JVM no se mantiene activa por lo que supongo que es otro hilo que debería persistir en mi objeto. – MisterD

+0

Tiene permiso para responder a su pregunta, de hecho es alentado a hacerlo. Lea las preguntas frecuentes. Su pregunta es buena, por lo tanto, resuma la respuesta muy bien para que todos se beneficien. – Siddharth

Respuesta

5

Agregando a la buena respuesta por axtavt y aclarar Cómo funcionó su sueño (1000): Para situaciones de desarrollo en las que desea una persistencia absolutamente sincrónica, apague la función write_delay predeterminada.

<property name="hibernate.connection.url" 
     value="jdbc:hsqldb:file:data/db/db;shutdown=true;hsqldb.write_delay_millis=0"/>    

Esto significa que cada declaración se escribe en el disco antes de que se devuelva el resultado a la persona que llama. Naturalmente, en funcionamiento normal, puede aumentar este valor. El valor predeterminado es 500 ms, que necesita la suspensión (1000). La información proporcionada es para HSQLDB versión 2.2.x.

3

es necesario agregar shutdown=true a la URL de base de datos (o emitir una explict SHUTDOWN de comandos) con el fin de cerrar correctamente por una base de datos en proceso HSQLDB:

<property name="hibernate.connection.url" 
    value="jdbc:hsqldb:file:data/db/db;shutdown=true" />    

Ver también:

+0

Ah sí, se me olvidó mencionar que lo tuve antes y lo eliminé porque pensé que podría contribuir al problema. no funciona con o sin ella. :( – MisterD

0

Espero que esto ayude a alguien. La sugerencia de establecer el retraso de escritura en 0 ms funciona, pero no funciona desde la url a menos que esté creando un nuevo db. Para que se aplica, ejecuta en una secuencia de comandos mientras está conectado a la base de datos utilizando la sentencia SQL a continuación:

set files write delay false 

Así, por ejemplo, se puede ejecutar mediante el SQLtool.jar de este modo:

java -jar /path/to/sqltool.jar -sql "set files write delay false;" --inlinerc=<rc spec here> 
Cuestiones relacionadas