Posso executar aplicativos do Hibernate configurados hbm2ddl.auto=update
para atualizar o esquema do banco de dados em um ambiente de produção?
Posso executar aplicativos do Hibernate configurados hbm2ddl.auto=update
para atualizar o esquema do banco de dados em um ambiente de produção?
Respostas:
Não, é inseguro.
Apesar dos melhores esforços da equipe do Hibernate, você simplesmente não pode contar com atualizações automáticas na produção . Escreva seus próprios patches, revise-os com o DBA, teste-os e aplique-os manualmente.
Teoricamente, se o hbm2ddl update funcionou no desenvolvimento, também deveria funcionar na produção. Mas, na realidade, nem sempre é o caso.
Mesmo se funcionou bem, pode ser abaixo do ideal. Os DBAs são pagos por um motivo.
Fazemos isso em produção, embora com um aplicativo que não é essencial e sem DBAs altamente pagos na equipe. É apenas um processo manual a menos que está sujeito a erro humano - o aplicativo pode detectar a diferença e fazer a coisa certa, além de que você provavelmente já o testou em vários ambientes de desenvolvimento e teste.
Uma ressalva - em um ambiente em cluster, convém evitá-lo porque vários aplicativos podem surgir ao mesmo tempo e tentar modificar o esquema que pode ser ruim. Ou coloque algum mecanismo em que apenas uma instância tenha permissão para atualizar o esquema.
Os criadores do Hibernate desencorajam isso em um ambiente de produção em seu livro "Java Persistence with Hibernate" :
AVISO: Vimos usuários do Hibernate tentando usar o SchemaUpdate para atualizar o esquema de um banco de dados de produção automaticamente. Isso pode terminar rapidamente em desastre e não será permitido pelo seu DBA.
Confira o XML do LiquiBase para manter um registro de alterações. Eu nunca o havia usado até este ano, mas achei muito fácil aprender e tornar o controle de revisão de banco de dados / migração / gerenciamento de alterações muito infalível. Eu trabalho em um projeto Groovy / Grails, e o Grails usa o Hibernate abaixo de todo o seu ORM (chamado "GORM"). Usamos o Liquibase para gerenciar todas as alterações de esquema SQL, o que fazemos com bastante frequência à medida que nosso aplicativo evolui com novos recursos.
Basicamente, você mantém um arquivo XML de conjuntos de alterações aos quais continua adicionando à medida que seu aplicativo evolui. Este arquivo é mantido no git (ou o que você estiver usando) com o restante do seu projeto. Quando seu aplicativo é implantado, o Liquibase verifica a tabela de registro de alterações no banco de dados ao qual você está se conectando, para saber o que já foi aplicado e, de maneira inteligente, aplica apenas quaisquer conjuntos de alterações que ainda não foram aplicados no arquivo. Na prática, ele funciona muito bem e, se você o usar para todas as alterações de esquema, poderá estar 100% confiante de que o código que você faz o checkout e implanta sempre poderá se conectar a um esquema de banco de dados totalmente compatível.
O mais impressionante é que posso pegar um banco de dados mysql em branco no meu laptop, iniciar o aplicativo e imediatamente o esquema está configurado para mim. Também facilita o teste de alterações de esquema, aplicando-as a um local-dev ou banco de dados de teste primeiro.
A maneira mais fácil de começar provavelmente seria usar o banco de dados existente e usar o Liquibase para gerar um arquivo baseline.xml inicial. No futuro, você pode simplesmente anexá-lo e deixar o liquibase assumir o gerenciamento das alterações de esquema.
hbm2ddl.auto=update
para que seus mapeamentos de Class / DB sejam validados e você tenha controle completo da criação do DB por meio do liquibase. O que você acha?
validate
Eu votaria não. O Hibernate parece não entender quando os tipos de dados das colunas foram alterados. Exemplos (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
Provavelmente também existem outros exemplos, como aumentar o comprimento de uma coluna String para mais de 255 e vê-la converter em texto, texto médio, etc.
É verdade que não acho que exista uma maneira de "converter tipos de dados" sem criar uma nova coluna, copiar os dados e remover a coluna antiga. Mas no minuto em que seu banco de dados possui colunas que não refletem o mapeamento atual do Hibernate, você está vivendo muito perigosamente ...
O Flyway é uma boa opção para lidar com esse problema:
@Column(length = 45)
para @Column(length = 255)
. Pode verificar se o Hibernate 4.3.6.Final atualizou corretamente o esquema do banco de dados usando hbm2ddl.auto=update
. (Uma coisa a mencionar é o banco de dados não tem actualmente quaisquer dados nele -. Apenas a estrutura)
O Hibernate precisa exonerar-se de não usar as atualizações automáticas no prod para se cobrir quando as pessoas que não sabem o que estão fazendo o usam em situações em que não devem ser usadas.
As situações em que não devem ser usadas superam em muito as situações em que está OK.
Eu o uso há anos em muitos projetos diferentes e nunca tive um único problema. Essa não é uma resposta idiota, e não é uma codificação de cowboy. É um fato histórico.
Uma pessoa que diz "nunca faça isso na produção" está pensando em um conjunto específico de implantações de produção, a saber, aquelas com as quais está familiarizado (sua empresa, sua indústria, etc.).
O universo das "implantações de produção" é vasto e variado.
Um desenvolvedor experiente do Hibernate sabe exatamente o que o DDL resultará de uma determinada configuração de mapeamento. Contanto que você teste e valide que o que você espera acaba no DDL (em dev, qa, preparo etc.), você estará bem.
Quando você adiciona muitos recursos, as atualizações automáticas de esquema podem economizar tempo real.
A lista de atualizações automáticas que não serão tratadas é interminável, mas alguns exemplos são a migração de dados, a adição de colunas não anuláveis, alterações no nome da coluna, etc.
Além disso, você precisa tomar cuidado em ambientes em cluster.
Mas, novamente, se você soubesse tudo isso, não faria essa pergunta. Hmm . . . OK, se você está fazendo esta pergunta, deve esperar até ter muita experiência com o Hibernate e as atualizações automáticas de esquema antes de pensar em usá-lo no prod.
Como expliquei neste artigo , não é uma boa ideia usar hbm2ddl.auto
na produção.
A única maneira de gerenciar o esquema do banco de dados é usar scripts de migração incremental porque:
Até o Guia do Usuário do Hibernate recomenda evitar a utilização da hbm2ddl
ferramenta em ambientes de produção.
SchemaExport
conforme demonstrado neste caso de teste .
Fazemos isso em um projeto em execução há meses e nunca tivemos um problema até agora. Lembre-se dos 2 ingredientes necessários para esta receita:
Projete seu modelo de objeto com uma abordagem de compatibilidade com versões anteriores, que substitui objetos e atributos em vez de removê-los / alterá-los. Isso significa que, se você precisar alterar o nome de um objeto ou atributo, deixe o antigo como está, adicione o novo e escreva algum tipo de script de migração. Se você precisar alterar uma associação entre objetos, se você já estiver em produção, isso significa que seu design estava errado em primeiro lugar; portanto, tente pensar em uma nova maneira de expressar o novo relacionamento, sem afetar os dados antigos.
Sempre faça backup do banco de dados antes da implantação.
Meu senso é - depois de ler este post - que 90% das pessoas que participam dessa discussão ficam horrorizadas apenas com o pensamento de usar automações como essa em um ambiente de produção. Alguns jogam a bola no DBA. Reserve um momento para considerar que nem todos os ambientes de produção fornecem um DBA e poucas equipes de desenvolvimento podem pagar um (pelo menos para projetos de tamanho médio). Então, se estamos falando de equipes em que todos precisam fazer tudo, a bola está neles.
Nesse caso, por que não tentar ter o melhor dos dois mundos? Ferramentas como esta estão aqui para ajudar, as quais - com um design e plano cuidadosos - podem ajudar em muitas situações. E acredite, os administradores podem inicialmente ser difíceis de convencer, mas se souberem que a bola não está em suas mãos, eles vão adorar.
Pessoalmente, eu nunca voltaria a escrever scripts manualmente para estender qualquer tipo de esquema, mas essa é apenas a minha opinião. E depois de começar a adotar os bancos de dados NoSQL sem esquema recentemente, posso ver que, em breve, todas essas operações baseadas em esquema pertencerão ao passado, então é melhor começar a mudar sua perspectiva e olhar para frente.
Eu não correria o risco, porque você pode acabar perdendo dados que deveriam ter sido preservados. hbm2ddl.auto = update é uma maneira fácil de manter seu banco de dados atualizado.
No meu caso (Hibernate 3.5.2, Postgresql, Ubuntu), a configuração hibernate.hbm2ddl.auto=update
criou apenas novas tabelas e criou novas colunas em tabelas já existentes.
Ele não eliminou tabelas, nem eliminou colunas, nem alterou colunas. Pode ser chamado de opção segura, mas algo como hibernate.hbm2ddl.auto=create_tables add_columns
seria mais claro.
Não é seguro, não é recomendado, mas é possível.
Tenho experiência em um aplicativo usando a opção de atualização automática na produção.
Bem, os principais problemas e riscos encontrados nesta solução são:
Portanto, não recomendamos o uso da atualização automática na produção.
Se você realmente deseja usar a atualização automática na produção, recomendo:
E, diferente das outras postagens, acho que a atualização automática não está relacionada a DBAs "muito bem pagos" (como mencionado em outras postagens). Os DBAs têm coisas mais importantes a fazer do que escrever instruções SQL para criar / alterar / excluir tabelas e colunas. Essas tarefas simples do dia-a-dia podem ser executadas e automatizadas pelos desenvolvedores e passadas apenas para a equipe do DBA revisar, não necessitando de Hibernate e DBAs "muito bem pagos" para escrevê-los.
Normalmente, aplicativos corporativos em grandes organizações são executados com privilégios reduzidos.
O nome de usuário do banco de dados pode não ter DDL
privilégio para adicionar colunas hbm2ddl.auto=update
necessárias.
Eu concordo com o Vladimir. Os administradores da minha empresa definitivamente não apreciariam se eu sugerisse esse curso.
Além disso, a criação de um script SQL em vez de confiar cegamente no Hibernate oferece a oportunidade de remover campos que não estão mais em uso. O Hibernate não faz isso.
E acho que comparar o esquema de produção com o novo esquema oferece uma percepção ainda melhor do que você alterou no modelo de dados. Você sabe, é claro, porque fez isso, mas agora vê todas as mudanças de uma só vez. Mesmo aqueles que fazem você ir como "O que diabos ?!".
Existem ferramentas que podem criar um delta de esquema para você, portanto, nem é um trabalho árduo. E então você sabe exatamente o que vai acontecer.
O esquema dos aplicativos pode evoluir com o tempo; se você possui várias instalações, que podem estar em versões diferentes, você deve ter alguma maneira de garantir que seu aplicativo, algum tipo de ferramenta ou script seja capaz de migrar o esquema e os dados de uma versão passo a passo para outra.
Ter toda a sua persistência nos mapeamentos do Hibernate (ou anotações) é uma maneira muito boa de manter a evolução do esquema sob controle.
Você deve considerar que a evolução do esquema tem vários aspectos a serem considerados:
evolução do esquema do banco de dados na adição de mais colunas e tabelas
descarte de colunas, tabelas e relações antigas
preenchendo novas colunas com padrões
As ferramentas de hibernação são importantes, especialmente no caso (como na minha experiência), você tem versões diferentes do mesmo aplicativo em muitos tipos diferentes de bancos de dados.
O ponto 3 é muito sensível se você estiver usando o Hibernate, como se você introduzir uma nova propriedade com valor booleano ou uma propriedade numérica, se o Hibernate encontrar algum valor nulo nessas colunas, se houver uma exceção.
Então, o que eu faria é: realmente use a capacidade de atualização de esquema das ferramentas Hibernate, mas você deve adicionar juntamente com alguns dados e retorno de chamada de manutenção de esquema, como para preencher padrões, descartar colunas não mais usadas e similares. Dessa maneira, você obtém as vantagens (scripts de atualização de esquema independentes do banco de dados e evita a codificação duplicada das atualizações, em peristência e em scripts), mas também abrange todos os aspectos da operação.
Por exemplo, se uma atualização de versão consiste simplesmente em adicionar uma propriedade com valor varchar (por isso, coluna), que pode ser nula, com a atualização automática, você será feito. Onde mais complexidade é necessária, mais trabalho será necessário.
Isso pressupõe que o aplicativo, quando atualizado, é capaz de atualizar seu esquema (isso pode ser feito), o que também significa que ele deve ter os direitos de usuário para fazê-lo no esquema. Se a política do cliente impedir isso (provavelmente caso do Lizard Brain), você precisará fornecer os scripts específicos do banco de dados.