Hibernate: hbm2ddl.auto = ¿actualización en producción?


339

¿Está bien ejecutar aplicaciones de Hibernate configuradas hbm2ddl.auto=updatepara actualizar el esquema de la base de datos en un entorno de producción?


66
Nosotros lo hacemos. Nunca tuve ningún problema.
Cretzel

44
Muy buena pregunta Lo enfrento ahora. Entonces, ahora 2018: después de 10 años, ¿cuál es su opinión? ¿Es seguro usar la actualización de Hibernate en bases de datos de producción de clientes importantes con esquemas complejos?
Kirill Ch

Respuestas:


388

No, no es seguro.

A pesar de los mejores esfuerzos del equipo de Hibernate, simplemente no puede confiar en las actualizaciones automáticas en producción . Escriba sus propios parches, revíselos con DBA, pruébelos y luego aplíquelos manualmente.

Teóricamente, si la actualización hbm2ddl funcionó en desarrollo, también debería funcionar en producción. Pero en realidad, no siempre es el caso.

Incluso si funcionó bien, puede ser subóptimo. Los DBA se pagan tanto por una razón.


33
¿Por qué no es seguro?
Cretzel

74
No es seguro porque los parches aplicados pueden tener efectos secundarios que hbm2ddl difícilmente puede predecir (como deshabilitar los desencadenantes que se instalaron para modificar la tabla). Para esquemas complejos, la forma más segura es manual. Automático con pruebas de regresión es distante segundo. Todo en mi humilde opinión.
Vladimir Dyuzhev

18
También la actualización de un esquema db debe ser manejada por los profesionales (dbas). Recuperarse de un mal cambio de db es difícil en el mejor de los casos. Vova no lo mencionó, pero qué sucede si la actualización de hibernate decide soltar una columna y volver a agregarla porque el tipo o el tamaño cambiaron. ¿Y digamos que la columna es todas las direcciones de correo electrónico de sus usuarios? :-) adiós, adiós compañía ..... Desea que el cambio DDL se genere automáticamente, pero absolutamente quiere que un humano inspeccione el cambio.
Pat

99
¿No hace una copia de seguridad de sus bases de datos antes de una actualización?
Jacob

21
Fwiw, en este momento la actualización del esquema de Hibernate no deja caer tablas o columnas.
Brian Deterling

70

Lo hacemos en producción, aunque con una aplicación que no es crítica para la misión y sin DBA altamente remunerados en el personal. Es solo un proceso manual menos que está sujeto a errores humanos: la aplicación puede detectar la diferencia y hacer lo correcto, además de que probablemente lo haya probado en varios entornos de desarrollo y prueba.

Una advertencia: en un entorno en clúster, es posible que desee evitarlo porque pueden aparecer varias aplicaciones al mismo tiempo e intentar modificar el esquema que podría ser malo. O coloque algún mecanismo en el que solo una instancia pueda actualizar el esquema.


2
Lo usamos también en producción, caso de uso similar. Plataforma de análisis que no es de misión crítica. Hemos implementado 16K veces en 4 entornos (4 años) sin tanto problema con la hibernación. Somos un equipo pequeño y en su mayoría somos principiantes de SQL RDBS y tenemos más confianza en el esquema de manejo de Hibernate que nosotros mismos. Me pregunto cuál es la tasa de error para tener un DBA en el personal que gestiona las migraciones y los cambios de esquema. ¿Es mejor que 0 en ~ 16K implementaciones?
user3263752

¿Qué dirías sobre este comentario de Pat? stackoverflow.com/questions/221379/…
Shiva kumar el

52

Los creadores de Hibernate desalientan hacerlo en un entorno de producción en su libro "Java Persistence with Hibernate" :

ADVERTENCIA: Hemos visto a usuarios de Hibernate tratando de usar SchemaUpdate para actualizar el esquema de una base de datos de producción automáticamente. Esto puede terminar rápidamente en un desastre y su DBA no lo permitirá.


1
¿Fue eso escrito en 2006?
user3263752

28

Consulte LiquiBase XML para mantener un registro de cambios de actualizaciones. Nunca lo había usado hasta este año, pero descubrí que es muy fácil de aprender y que el control de revisión de DB / migración / gestión de cambios es muy infalible. Trabajo en un proyecto Groovy / Grails, y Grails usa Hibernate debajo de todo su ORM (llamado "GORM"). Usamos Liquibase para administrar todos los cambios en el esquema SQL, lo cual hacemos con bastante frecuencia a medida que nuestra aplicación evoluciona con nuevas características.

Básicamente, mantiene un archivo XML de conjuntos de cambios que continúa agregando a medida que su aplicación evoluciona. Este archivo se mantiene en git (o lo que sea que esté usando) con el resto de su proyecto. Cuando se implementa su aplicación, Liquibase verifica su tabla de registro de cambios en la base de datos a la que se está conectando para que sepa lo que ya se ha aplicado, luego aplica de manera inteligente cualquier conjunto de cambios que aún no se haya aplicado desde el archivo. Funciona absolutamente bien en la práctica, y si lo usa para todos sus cambios de esquema, puede estar 100% seguro de que el código que extrae y despliega siempre podrá conectarse a un esquema de base de datos totalmente compatible.

Lo sorprendente es que puedo tomar una base de datos mysql de pizarra totalmente en blanco en mi computadora portátil, iniciar la aplicación y de inmediato el esquema está configurado para mí. También facilita la prueba de los cambios de esquema al aplicarlos primero a un dev local o a un db provisional.

La manera más fácil de comenzar probablemente sería tomar su base de datos existente y luego usar Liquibase para generar un archivo baseline.xml inicial. Luego, en el futuro, puede agregarlo y dejar que liquibase se haga cargo de la administración de los cambios de esquema.

http://www.liquibase.org/


Perfecto, justo a lo que estaba a punto de cambiar. Creo que lo mejor, ir un paso adelante sería agregar hbm2ddl.auto=updatepara que sus asignaciones de Clase / DB estén validadas y tenga un control completo de la creación de DB a través de liquibase. ¿Qué piensas?
bholagabbar

Vaya, quise decirvalidate
bholagabbar

liquibase es mejor en la gestión de secuencias de comandos utilizando "incluir-importar" como soporte y soporte de versiones y atributo "Tipo" para archivos que le ayuda a tener diferentes archivos SQL para diferentes entornos que tienen relación padre-hijo. en pocas palabras, vaya a la administración tradicional de SQL. en producción. Para el desarrollo, necesitamos velocidad para la producción, necesitamos garantías, estabilidad y respaldo.
Karan Kaw

26

Yo votaría no. Hibernate no parece entender cuándo los tipos de datos para las columnas han cambiado. Ejemplos (usando MySQL):

String with @Column(length=50)  ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)

@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed

Probablemente también hay otros ejemplos, como subir la longitud de una columna de cadena por encima de 255 y ver que se convierte a texto, texto medio, etc.

De acuerdo, no creo que haya realmente una manera de "convertir tipos de datos" sin crear una nueva columna, copiar los datos y eliminar la columna anterior. Pero en el momento en que su base de datos tiene columnas que no reflejan el mapeo actual de Hibernate, está viviendo de manera muy peligrosa ...

Flyway es una buena opción para tratar este problema:

http://flywaydb.org


1
Acabo de probar la primera parte de su ejemplo, en mi caso cambiar @Column(length = 45)a @Column(length = 255). Puede verificar que Hibernate 4.3.6.Final actualizó correctamente el esquema de la base de datos utilizando hbm2ddl.auto=update. (Una cosa para mencionar es que la base de datos actualmente no tiene ningún dato, solo la estructura)
Steve Steve

Es muy posible que hayan solucionado ese error en algún lugar durante los últimos ~ 6 años más o menos. Sin embargo, si tenía datos en el esquema e hizo un cambio que resultó en una disminución en el ancho de la columna, se encontrará con errores o truncamiento de datos no administrado.
cliff.meyers

1
flywaydb necesita un script SQL diseñado manualmente, debería ser mejor que lo que un programa automático puede hacer, pero quién podría escribir un script grande, entonces es un problema.
Bằng Rikimaru

25

Hibernate tiene que poner el descargo de responsabilidad sobre no usar actualizaciones automáticas en productos para cubrirse cuando las personas que no saben lo que están haciendo lo usan en situaciones en las que no deberían usarse.

Por supuesto, las situaciones en las que no debe usarse superan en gran medida las situaciones en las que está bien.

Lo he usado durante años en muchos proyectos diferentes y nunca he tenido un solo problema. Esa no es una respuesta tonta, y no es una codificación de vaquero. Es un hecho histórico.

Una persona que dice "nunca lo hagas en producción" está pensando en un conjunto específico de despliegues de producción, a saber, aquellos con los que está familiarizado (su empresa, su industria, etc.).

El universo de "despliegues de producción" es vasto y variado.

Un desarrollador experimentado de Hibernate sabe exactamente qué DDL va a resultar de una configuración de mapeo dada. Siempre que pruebe y valide que lo que espera termina en el DDL (en dev, qa, puesta en escena, etc.), está bien.

Cuando agrega muchas funciones, las actualizaciones automáticas de esquemas pueden ahorrarle tiempo real.

La lista de cosas que las actualizaciones automáticas no manejarán es interminable, pero algunos ejemplos son la migración de datos, agregar columnas no anulables, cambios de nombre de columna, etc.

También debe tener cuidado en entornos agrupados.

Pero, de nuevo, si supieras todo esto, no harías esta pregunta. Hmm . . OK, si está haciendo esta pregunta, debe esperar hasta tener mucha experiencia con Hibernate y las actualizaciones de esquemas automáticos antes de pensar en usarlo en prod.


19

Como expliqué en este artículo , no es una buena idea usarlo hbm2ddl.autoen producción.

La única forma de administrar el esquema de la base de datos es usar scripts de migración incrementales porque:

  • los scripts residirán en VCS a lo largo de su código base. Cuando finaliza la compra de una rama, recrea todo el esquema desde cero.
  • los scripts incrementales pueden probarse en un servidor de control de calidad antes de aplicarse en producción
  • no hay necesidad de intervención manual ya que Flyway puede ejecutar los scripts , por lo tanto, reduce la posibilidad de errores humanos asociados con la ejecución manual de scripts.

Incluso la Guía del usuario de Hibernate le aconseja que evite usar la hbm2ddlherramienta para entornos de producción.

ingrese la descripción de la imagen aquí


Esta es una respuesta perfecta y de acuerdo con ella. Pero realmente encuentro la idea de crear el primer script de base de datos manualmente engorroso (es decir, V1_0__initial_script.sql en el caso del ejemplo en el enlace). ¿Hay alguna manera de que pueda crear un script desde mi base de datos de desarrollo existente que Hibernate creó para mí y almacenar en V1_0_intial_script.sql?
HopeKing

1
Use SchemaExportcomo lo demuestra este caso de prueba .
Vlad Mihalcea

Gracias. Encontré un volcado de una sola línea "mysqldump -u root -p --no-data dbname> schema.sql". ¿Hay algún inconveniente en usar el volcado generado a partir de esto?
HopeKing

1
No hay problema al usar un volcado de base de datos.
Vlad Mihalcea

8

Lo hacemos en un proyecto que se ejecuta en producción desde hace meses y nunca tuvimos un problema hasta ahora. Tenga en cuenta los 2 ingredientes necesarios para esta receta:

  1. Diseñe su modelo de objetos con un enfoque de compatibilidad con versiones anteriores, que es despreciar los objetos y atributos en lugar de eliminarlos / alterarlos. Esto significa que si necesita cambiar el nombre de un objeto o atributo, deje el antiguo como está, agregue el nuevo y escriba algún tipo de script de migración. Si necesita cambiar una asociación entre objetos, si ya está en producción, esto significa que su diseño estaba equivocado en primer lugar, así que trate de pensar en una nueva forma de expresar la nueva relación, sin afectar los datos antiguos.

  2. Siempre haga una copia de seguridad de la base de datos antes de la implementación.

Mi sensación es, después de leer esta publicación, que el 90% de las personas que participan en esta discusión están horrorizadas solo con la idea de usar automatizaciones como esta en un entorno de producción. Algunos lanzan la pelota al DBA. Tómese un momento para considerar que no todos los entornos de producción proporcionarán un DBA y que no muchos equipos de desarrollo pueden permitirse uno (al menos para proyectos de tamaño mediano). Entonces, si estamos hablando de equipos donde todos tienen que hacer todo, la pelota está sobre ellos.

En este caso, ¿por qué no tratar de tener lo mejor de ambos mundos? Herramientas como esta están aquí para ayudar, lo que, con un diseño y un plan cuidadosos, puede ayudar en muchas situaciones. Y créanme, los administradores pueden ser difíciles de convencer inicialmente, pero si saben que la pelota no está en sus manos, les encantará.

Personalmente, nunca volvería a escribir guiones a mano para extender ningún tipo de esquema, pero esa es solo mi opinión. Y después de comenzar a adoptar bases de datos sin esquema NoSQL recientemente, puedo ver que más que pronto, todas estas operaciones basadas en esquemas pertenecerán al pasado, por lo que será mejor que comience a cambiar su perspectiva y mirar hacia el futuro.


44
No estoy de acuerdo con el comentario NoSQL. Definitivamente está en aumento y tiene su lugar, pero hay muchas aplicaciones que dependen absolutamente del cumplimiento de ACID para la integridad de los datos con la concurrencia y las transacciones que NoSQL simplemente no puede proporcionar.
jpswain

7

No me arriesgaría porque podría terminar perdiendo datos que deberían haberse conservado. hbm2ddl.auto = update es puramente una manera fácil de mantener actualizada su base de datos de desarrollo.


2
¿No hace una copia de seguridad de sus bases de datos antes de una actualización?
Jacob

66
Sí, por supuesto que sí, pero es mucho trabajo restaurar desde una copia de seguridad. No vale la pena la molestia de restaurar las copias de seguridad cuando también puede actualizar su base de datos de manera ordenada.
Jaap Coomans

6
  • En mi caso (Hibernate 3.5.2, Postgresql, Ubuntu), la configuración hibernate.hbm2ddl.auto=updatesolo creó nuevas tablas y creó nuevas columnas en tablas ya existentes.

  • No soltó tablas, ni soltó columnas, ni alteró columnas. Puede llamarse una opción segura, pero algo así hibernate.hbm2ddl.auto=create_tables add_columnssería más claro.


6

No es seguro, no se recomienda, pero es posible.

Tengo experiencia en una aplicación que usa la opción de actualización automática en producción.

Bueno, los principales problemas y riesgos encontrados en esta solución son:

  • Implementar en la base de datos incorrecta . Si comete el error de ejecutar el servidor de aplicaciones con una versión anterior de la aplicación (EAR / WAR / etc) en la base de datos incorrecta ... Tendrá muchas columnas, tablas, claves externas y errores nuevos. El mismo problema puede ocurrir con un simple error en el archivo de origen de datos (copie / pegue el archivo y olvidó cambiar la base de datos). En resumen, la situación puede ser un desastre en su base de datos.
  • El servidor de aplicaciones tarda demasiado en iniciarse . Esto ocurre porque Hibernate intenta encontrar todas las tablas / columnas / etc. creadas cada vez que inicia la aplicación. Necesita saber qué (tabla, columna, etc.) necesita ser creado. Este problema solo empeorará a medida que crezcan las tablas de la base de datos.
  • Las herramientas de bases de datos son casi imposibles de usar . Para crear scripts DDL o DML de la base de datos para que se ejecuten con una nueva versión, debe pensar en lo que creará la actualización automática después de iniciar el servidor de aplicaciones. Por ejemplo, si necesita llenar una nueva columna con algunos datos, debe iniciar el servidor de aplicaciones, esperar a que Hibernate cree la nueva columna y ejecutar el script SQL solo después de eso. Como puede ver, las herramientas de migración de bases de datos (como Flyway, Liquibase, etc.) son casi imposibles de usar con la actualización automática habilitada.
  • Los cambios en la base de datos no están centralizados . Con la posibilidad de que Hibernate cree tablas y todo lo demás, es difícil ver los cambios en la base de datos en cada versión de la aplicación, porque la mayoría de ellos se realizan automáticamente.
  • Fomenta la basura en la base de datos . Debido al uso "fácil" de la actualización automática, existe la posibilidad de que su equipo no descarte las columnas y las tablas antiguas, porque la actualización automática de hibernación no puede hacer eso.
  • Desastre inminente . El riesgo inminente de que ocurra algún desastre en la producción (como algunas personas mencionadas en otras respuestas). Incluso con una aplicación ejecutándose y siendo actualizada durante años, no creo que sea una opción segura. Nunca me sentí seguro con esta opción utilizada.

Por lo tanto, no recomendaré usar la actualización automática en producción.

Si realmente desea utilizar la actualización automática en producción, le recomiendo:

  • Redes separadas . Su entorno de prueba no puede acceder al entorno de homólogo. Esto ayuda a evitar que una implementación que se suponía que estaba en el entorno de prueba cambia la base de datos de homologación.
  • Gestionar orden de guiones . Debe organizar sus scripts para que se ejecuten antes de su implementación (cambio de tabla de estructura, caída de tabla / columnas) y script después de la implementación (información de relleno para las nuevas columnas / tablas).

Y, a diferencia de las otras publicaciones, no creo que la actualización automática habilitada esté relacionada con DBA "muy bien pagados" (como se menciona en otras publicaciones). Los DBA tienen cosas más importantes que hacer que escribir declaraciones SQL para crear / cambiar / eliminar tablas y columnas. Los desarrolladores pueden realizar y automatizar estas sencillas tareas cotidianas y solo se pueden aprobar para que el equipo del DBA las revise, sin necesidad de que Hibernate y los DBA estén "muy bien pagados" para escribirlas.


4

No, nunca lo hagas. Hibernate no maneja la migración de datos. Sí, hará que su esquema se vea correctamente, pero no garantiza que no se pierdan datos valiosos de producción en el proceso.


4
  • Por lo general, las aplicaciones empresariales en grandes organizaciones se ejecutan con privilegios reducidos.

  • El nombre de usuario de la base de datos puede no tener DDLprivilegios para agregar columnas, lo que hbm2ddl.auto=updaterequiere.


Este es un problema que encuentro con frecuencia. Intentamos usar hibernate para la creación inicial de DB, pero a menudo no es posible hacerlo.
Dan

55
No es un "problema", esto es lo correcto.
Vladimir Dyuzhev

2

Estoy de acuerdo con Vladimir. Los administradores de mi empresa definitivamente no lo apreciarían si incluso sugiriera tal curso.

Además, crear un script SQL en lugar de confiar ciegamente en Hibernate le brinda la oportunidad de eliminar campos que ya no se usan. Hibernate no hace eso.

Y encuentro que comparar el esquema de producción con el nuevo esquema te da una mejor perspectiva de lo que has cambiado en el modelo de datos. Ya sabes, por supuesto, porque lo hiciste, pero ahora ves todos los cambios de una vez. Incluso los que te hacen decir "¡¿Qué diablos ?!".

Hay herramientas que pueden hacer un esquema delta para usted, por lo que ni siquiera es un trabajo duro. Y luego sabes exactamente lo que va a pasar.


"Hay herramientas que pueden hacer un esquema delta para usted": ¿Podría señalar algunas de estas herramientas?
Daniel Cassidy

Creo que apexsql.com/sql_tools_diff.asp hace esto, y posiblemente más aplicaciones. Por lo general, lo hago a mano volcando el esquema y difuminando (usando diff).
extraneon

2

El esquema de las aplicaciones puede evolucionar con el tiempo; Si tiene varias instalaciones, que pueden estar en diferentes versiones, debe tener alguna forma de asegurarse de que su aplicación, algún tipo de herramienta o script sea capaz de migrar esquemas y datos de una versión paso a paso a cualquiera.

Tener toda su persistencia en las asignaciones (o anotaciones) de Hibernate es una muy buena manera de mantener bajo control la evolución del esquema.

Debe considerar que la evolución del esquema tiene varios aspectos a considerar:

  1. evolución del esquema de la base de datos al agregar más columnas y tablas

  2. caída de viejas columnas, tablas y relaciones

  3. llenar nuevas columnas con valores predeterminados

Las herramientas de Hibernate son importantes en particular en caso de que (como en mi experiencia) tenga diferentes versiones de la misma aplicación en muchos tipos diferentes de bases de datos.

El punto 3 es muy sensible en caso de que esté utilizando Hibernate, ya que si introduce una nueva propiedad con valor booleano o una numérica, si Hibernate encuentra algún valor nulo en dichas columnas, si se produce una excepción.

Entonces, lo que haría es: de hecho, use la capacidad de las herramientas de Hibernate para la actualización del esquema, pero debe agregar junto con ella algunos datos y devolución de llamada de mantenimiento del esquema, como para completar valores predeterminados, descartar columnas que ya no se usan y similares. De esta forma, obtiene las ventajas (guiones de actualización de esquemas independientes de la base de datos y evita la codificación duplicada de las actualizaciones, en persistencia y en guiones), pero también cubre todos los aspectos de la operación.

Entonces, por ejemplo, si una actualización de versión consiste simplemente en agregar una propiedad con valor varchar (por lo tanto, columna), que puede ser nula de forma predeterminada, con la actualización automática, habrá terminado. Donde más complejidad es necesaria, más trabajo será necesario.

Esto supone que la aplicación cuando se actualiza es capaz de actualizar su esquema (se puede hacer), lo que también significa que debe tener los derechos de usuario para hacerlo en el esquema. Si la política del cliente lo impide (probablemente en el caso de Lizard Brain), deberá proporcionar los scripts específicos de la base de datos.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.