2012-09-01 12 views
5

Tengo un proyecto muy usado en el que estoy trabajando actualmente actualizando. Hay varios lugares donde se puede instalar este proyecto, y en el futuro no es seguro qué versión se usa y a qué versión se puede actualizar en el futuro. En este momento, todos son iguales.Crear una consulta de tabla de creación de HSQL de la clase

Mi problema se debe al hecho de que puede haber muchos cambios en las clases de entidad de hibernación, y debe ser fácil actualizar a una versión más nueva sin problemas y sin pérdida de contenido de la base de datos. Simplemente reemplace WAR y comience y debería migrar por sí mismo.

Que yo sepa Hibernate no altera las tablas a menos que hibernate.hbm2ddl.auto = create, pero que en realidad descarta todos los datos?

Así que ahora cuando el contexto Spring se ha cargado completamente, ejecuta un bean que migrará la base de datos a la versión actual pasando por todos los cambios de la versiónX a la versiónY (qué versión estaba guardada previamente en la base de datos) y altera manualmente la tabla.

No es hacer unos pocos ALTER TABLE no modificable para agregar algunas columnas mucha molestia, pero cuando se trata de añadir nuevas tablas completas, se siente tonto tener que escribir todo eso ...

Así que mi pregunta (s) es la siguiente:

  • ¿hay alguna manera de enviar una clase de entidad y un dialecto de Hibernate código en algún lugar, y volver una consulta SQL válida para la creación de una mesa?

  • ¿Y aún mejor, de alguna manera crear una cadena SQL para agregar una columna a una tabla, dialecto seguro?

espero que esto no es una pregunta tonta, y no me he perdido algo obvio cuando se trata de Hibernate ...

Respuesta

2

No creo que usted será capaz de automatizar completamente este. Hibernate tiene la herramienta hbm2ddl (disponible como una tarea ant o un plugin maven) para generar las sentencias DDL requeridas desde la configuración de hibernación para crear una base de datos vacía, pero no conozco ninguna herramienta que pueda hacer una "diferencia" automática entre dos versiones. En cualquier caso, probablemente sea mejor que haga el diff cuidadosamente con la mano, ya que solo conoce su modelo de objetos lo suficientemente bien como para poder elegir los valores predeterminados correctos para las nuevas propiedades de las entidades existentes, etc.

Una vez que haya resuelto sus diferencias, puede usar una herramienta como liquibase para administrarlas y manejar realmente las actualizaciones en una base de datos al momento de inicio de la aplicación.

+1

De acuerdo, me conformé con que esta era la mejor respuesta. Todavía tengo reservas para liquidarme como una dependencia o ajustar mis anotaciones Spring + Hibernate +, pero hizo un gran trabajo al crear consultas SQL codificadas que puedo usar para mi propia solución personalizada. Gracias. – Stmated

+1

Marque esta respuesta de Dipesh: http://stackoverflow.com/a/12259980/433789 – sdouglass

+1

Dejar que Hibernate hacer su propia actualización automática funciona bien en casos simples como la adición de nuevas columnas anulables, pero no puede hacer frente a los más complejos migraciones como cambiar el nombre o eliminar columnas, cambiar tipos, etc. Imagine una situación en la que está agregando una columna nueva cuyo valor debe calcularse en función de los valores de las columnas existentes (en lugar de tener un valor predeterminado estático que funcione para todas las filas existentes)) –

2

tal vez debería intentar un enfoque diferente. En lugar de generar un esquema en la actualización en tiempo de ejecución, realice uno 'a mano' (aunque podría basarse en un script generado de hibernación).

Almacene un número de versión en la base de datos y cree un script de actualización para cada próxima versión. Lo único que tiene que hacer ahora es determinar en qué versión de la base de datos se encuentra actualmente y ejecutar secuencialmente los scripts de actualización necesarios para que llegue a la versión actual.

Para hacerlo más robusto puede realizar una prueba de unidad/integración que ejecuta todas las actualizaciones de bases de datos posibles y comprueba la integridad de la base de datos resultante.

Utilicé este método para una aplicación que construí y funciona sin problemas. Otro ejemplo de implementación de este patrón es Android. Tienen un método de actualización en su API

http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)

+1

Creo que voy a tomar esto como la respuesta aceptada. Lamentablemente, me siento raro dando la recompensa, ya que no es realmente una respuesta a mi pregunta; y es la solución que estaba planeando recurrir si mi pregunta se consideraba imposible. Pero supongo que fue el que más coincidía con mis propias ideas de no incluir dependencias adicionales y cosas por el estilo. Gracias – Stmated

+1

En serio, debería echarle un buen vistazo a Liquibase y, en particular, a su [soporte de hibernación] (http://liquibase.org/manual/hibernate) ... –

+1

Lo hice; aunque tenía algunas reservas en contra de ella cuando leía la documentación. Podría ser que no leí lo suficiente, y no entendí cómo mezclarlo bien con mi entorno. Podría regresar con una aceptación revisada, si las cosas cambian. – Stmated

4

has necesitado

hibernate.hbm2ddl.auto=update 

que conserva toda la base de datos con los datos y añadir sólo las columnas y las tablas que haya cambiado en la entidad.

+1

Esto es lo que uso, funciona muy bien. – sdouglass

2

No utilice el ddl de Hibernate. Descarta tus datos si deseas migrar. Te sugiero que eches un vistazo a Liquibase. Liquibase es un control de versión de base de datos. Funciona usando conjuntos de cambios. Cada conjunto de cambios se puede crear manualmente o puede dejar que Liquibase lea su configuración de Hibernate y genere un conjunto de cambios.

Liquibase se puede iniciar a través de la primavera por lo que debe encajar perfectamente con su proyecto ;-)

Cuestiones relacionadas