Práticas recomendadas de geração de esquemas do Hibernate / JPA DB

Eu só queria ouvir a opinião de especialistas em Hibernate sobre as melhores práticas de geração de esquemas DB para projetos baseados em Hibernate / JPA. Especialmente:

  1. Qual estratégia usar quando o projeto acaba de começar? É recomendado deixar o Hibernate gerar automaticamente o esquema nesta fase ou é melhor criar as tabelas do database manualmente a partir das fases iniciais do projeto?

  2. Fingindo que durante todo o projeto o esquema estava sendo gerado usando o Hibernate, é melhor desabilitar a geração automática de esquema e criar manualmente o esquema do database antes que o sistema seja liberado para produção?

  3. E depois que o sistema tiver sido liberado para produção, qual é a melhor prática para manter as classs de entidade e o esquema de BD (por exemplo, adicionando / renomeando / atualizando colunas, renomeando tabelas, etc.)?

  1. É sempre recomendável gerar o esquema manualmente, preferencialmente por uma ferramenta que suporte revisões do esquema do database, como o ótimo Liquibase . Gerar o esquema a partir das entidades é ótimo na teoria, mas era frágil na prática e causa muitos problemas a longo prazo (confie em mim).

  2. Em produções, é sempre melhor gerar e revisar manualmente o esquema.

  3. Você faz uma atualização para uma entidade e cria um script de atualização correspondente (revisão) para atualizar o esquema do database para refletir a alteração da entidade. Você pode criar uma solução personalizada (escrevi algumas) ou usar algo mais popular como o liquibase (ela suporta até rollbacks de alterações de esquema). Se você estiver usando uma ferramenta de compilation como maven ou ant – é recomendável conectar o utilitário de atualização do esquema do db ao processo de compilation, para que as compilações recentes permaneçam sincronizadas com o esquema.

Embora discutível, eu diria que a resposta para todas as três perguntas é: deixar o hibernate gerar automaticamente as tabelas no esquema.

Eu não tive nenhum problema com isso até agora. Pode ser necessário limpar alguns campos manualmente de tempos em tempos, mas isso não é uma dor de cabeça comparado a manter separadamente os scripts de DDL – ou seja, gerenciar suas revisões e sincronizá-las com alterações de entidade (e vice-versa)

Para implantar na produção – uma dica óbvia – primeiro certifique-se de que tudo seja gerado OK no ambiente de teste e, em seguida, implemente na produção.

Manualmente, porque:

  1. Mesmo database pode ser usado por diferentes aplicativos e nem todos eles estariam usando hibernação ou até mesmo java. O esquema do database não deve ser determinado pelo ORM, ele deve ser projetado em torno dos dados e dos requisitos de negócios.
  2. Os tipos de dados escolhidos pelo hibernate podem não ser mais adequados para o aplicativo.
  3. Como mencionado em um comentário anterior, as alterações nas entidades exigiriam intervenção manual se a perda de dados não fosse aceitável.
  4. Coisas como propriedades adicionais (termo genérico, não propriedades do Java) em tabelas de junit funcionam maravilhosamente no RDBMS, mas são um tanto complexas e ineficientes para serem usadas em um ORM. Fazer tal mapeamento a partir do ORM -> RDBMS pode criar tabelas que não são eficientes. Em teoria, é possível criar exatamente a mesma tabela de junit usando o código gerado pelo hibernate, mas seria necessário algum cuidado especial ao gravar as Entidades.

Eu usaria a geração automática para aplicativos independentes ou bancos de dados que são acessados ​​por meio da mesma camada ORM e também se o aplicativo precisar ser portado para bancos de dados diferentes. Isso economizaria muito tempo, não exigindo que alguém escrevesse e mantivesse scripts DDL específicos do fornecedor de database.

Como Bozhidar disse, não deixe o Hibernate criar e atualizar o esquema do database. Deixe seu aplicativo criar e atualizar o esquema do database. Para java, a melhor ferramenta para fazer isso é o Flyway . Você precisa criar um ou mais arquivos SQL com instruções DDL que descrevam seu esquema de database. Esses arquivos SQL são então executados pelo Flyway. Para mais informações, veja o site da Flyway .

Acredito que muito do que está sendo discutido ou discutido aqui também deve estar relacionado a se você está mais confortável com a abordagem de primeiro código ou o primeiro database.

Pessoalmente, eu estou mais destinado a ir por último e, fazendo uma referência ao Princípio de Responsabilidade Única (SRP), eu prefiro ter especialista em database manipulando o database e um especialista em aplicativos manipulando o aplicativo, do que ter o aplicativo manipulando o database. Além disso, sou da opinião de que tomar muitos atalhos funcionará bem no início, mas criará problemas incontroláveis ​​à medida que as coisas crescem / evoluem.