Como a propriedade spring.jpa.hibernate.ddl-auto funciona exatamente no Spring?

130

Eu estava trabalhando em meu projeto de aplicativo de boot Spring e percebi que, às vezes, há um erro de tempo limite de conexão com meu banco de dados em outro servidor (SQL Server). Isso acontece especialmente quando tento fazer alguma migração de script, FlyWaymas funciona depois de várias tentativas.

Então percebi que não especifiquei spring.jpa.hibernate.ddl-autono meu arquivo de propriedades. Eu fiz algumas pesquisas e descobri que é recomendado adicionar spring.jpa.hibernate.ddl-auto= create-dropdesenvolvimento. E mude para: spring.jpa.hibernate.ddl-auto= noneem produção.

Mas eu realmente não entendi como isso realmente funciona e como o hibernate gera o esquema do banco de dados usando create-dropou nonevalor. Você pode explicar tecnicamente como isso realmente funciona e quais são as recomendações para o uso desta propriedade em desenvolvimento e em um servidor de produção. Obrigado

METTAIBI
fonte
1
O FWIW JPA 2.1 tem uma propriedade padrão javax.persistence.schema-generation.database.action, portanto, não vejo realmente a necessidade de usar propriedades específicas do fornecedor JPA para geração de esquema.
Neil Stockton
@NeilStockton Uma ideia que estamos explorando com o Hibernate 6 é a capacidade de controlar a geração de esquemas de maneira diferente com base em categorias; por exemplo, suas tabelas orm podem ser, nonemas você pode querer que suas tabelas Hibernate Search e Envers sejam geradas usando, updateuma vez que são gerenciadas internamente por esses projetos e você não deseja gerenciá-las manualmente. No momento, controlamos isso globalmente para todas as tabelas, independentemente de sua origem / fonte. Isso seria mais uma razão para usar opções específicas do fornecedor se você quiser usar isso.
Naros

Respostas:

216

Para o registro, a spring.jpa.hibernate.ddl-autopropriedade é específica do Spring Data JPA e é sua maneira de especificar um valor que será eventualmente passado para o Hibernate sob a propriedade que ele conhece hibernate.hbm2ddl.auto,.

Os valores create, create-drop, validate, e update, basicamente, influenciar a forma como o gerenciamento de ferramentas esquema irá manipular o esquema de banco de dados na inicialização.

Por exemplo, a updateoperação consultará a API do driver JDBC para obter os metadados do banco de dados e então o Hibernate compara o modelo de objeto que ele cria com base na leitura de suas classes anotadas ou mapeamentos HBM XML e tentará ajustar o esquema em tempo real.

A updateoperação, por exemplo, tentará adicionar novas colunas, restrições, etc., mas nunca removerá uma coluna ou restrição que possa ter existido anteriormente, mas não faz mais parte do modelo de objeto de uma execução anterior.

Normalmente, em cenários de caso de teste, você provavelmente usará create-droppara criar seu esquema, seu caso de teste adiciona alguns dados de simulação, você executa seus testes e, durante a limpeza do caso de teste, os objetos de esquema são descartados, deixando um banco de dados vazio.

Em desenvolvimento, geralmente é comum ver os desenvolvedores usarem updatepara modificar automaticamente o esquema para adicionar novas adições na reinicialização. Mas, novamente, entenda, isso não remove uma coluna ou restrição que possa existir em execuções anteriores que não seja mais necessária.

Na produção, geralmente é altamente recomendável usar noneou simplesmente não especificar essa propriedade. Isso ocorre porque é uma prática comum para DBAs revisar os scripts de migração para alterações no banco de dados, especialmente se seu banco de dados for compartilhado entre vários serviços e aplicativos.

Naros
fonte
11
Sim, nunca use a geração ddl na produção. Geramos os scripts iniciais para a estrutura da tabela usando ddl e envolvemos o DBA no processo. Em seguida, incluímos os scripts db como parte da unidade de implantação e os executamos usando Flyway quando o aplicativo é implantado. Quando precisamos modificar o banco de dados, adicionamos novos scripts à próxima versão do aplicativo e implementamos na preparação. O Flyway detectará automaticamente a versão atual e executará os scripts necessários para trazer o banco de dados para a versão mais recente. Se tudo funcionar, nós implantamos para produção.
Klaus Groenbaek
1
e se não especificarmos essa propriedade? por exemplo, tenho minha própria <bean id = "sessionFactory" class = "org.springframework.orm.hibernate5.LocalSessionFactoryBean"> ... <prop key = "hibernate.hbm2ddl.auto"> atualização </prop> Eu tive isso e por alguma razão minhas tabelas sempre foram descartadas, até que eu adicionei a propriedade acima mencionada ;; ps: desculpe o exemplo de código)
Ţîgan Ion
11
Por que não validateno ambiente de produção?
Shamal Karunarathne
20
@ShamalKarunarathne Os aplicativos podem ser usados validatena produção, mas normalmente essa deve ser uma configuração usada em seu ambiente de qualidade / teste para verificar se os scripts de banco de dados que você escreveu ou aplicou à ferramenta de migração de banco de dados são precisos. Outro motivo para não usar validatena produção é que pode ser um gargalo durante o processo de inicialização do seu aplicativo, especialmente se o seu modelo de objeto for muito extenso em tamanho ou se outros fatores relacionados à rede entrarem em ação.
Naros
1
Sem um rastreamento de pilha preciso, é difícil especular; entretanto, meu primeiro palpite seria que orderestá sendo interpretado incorretamente pelo analisador SQL, uma vez que é uma palavra-chave se não está sendo escapado.
Naros