Spring Boot 和 Hibernate:打印/记录 DDL

Posted

技术标签:

【中文标题】Spring Boot 和 Hibernate:打印/记录 DDL【英文标题】:Spring boot and Hibernate: print/log DDL 【发布时间】:2014-09-22 18:23:43 【问题描述】:

在添加一个或多个具有数据库映射(JPA/hibernate)的类后,我希望 Hibernate 打印出必要的模式更新,以便我可以在数据库上执行它们(例如通过 FlyWay)。我不希望自动执行更新。

似乎可以对此进行一些控制的唯一属性如下

org.hibernate.tool.hbm2ddl=validate|update|create|create-drop|none

我不想自动更新/更改任何内容。我想将其设置为验证或无。当我这样做时,我看不到生成的架构。

我是经典的spring应用,以前使用hibernateSchemaExport类打印DDL。

SchemaExport schemaExport = new SchemaExport(cfg);
schemaExport.execute(true, false, false, false);

我可以在 Spring Boot 中使用类似的东西吗?

【问题讨论】:

如果您将其设置为 validate/none,那么您明确告诉它不要生成 DDL。 Spring Boot 只是标准的 Spring,在配置特性上有一些约定,以最大限度地减少您需要做的配置量。所以仍然可以使用SchemaExport,和以前一样。 同意,但我不知道从哪里获取Configuration cfg 参数以传递给SchemaExport。在ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); 之后我不能这样做,因为如果数据库没有正确的架构,那么应用程序已经崩溃了。我已将 hbm2ddl 设置为“验证”。也许将此设置为“无”可能会解决此问题,但我宁愿保留额外的检查。 您是否尝试将其设置为none?如果架构无效,使用validate 的全部意义在于启动失败。听起来您明确希望应用程序启动,尽管数据库不同步,但没有应用迁移。这就是 none 设置的用途。 How to generate a ddl creation script with a modern Spring Boot + Data JPA and Hibernate setup?的可能重复 【参考方案1】:

这就是我的工作......

首先我进行实体更改,然后将它们设置为:

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

然后

    重新运行我的应用程序并让休眠对数据库进行更改。 进入日志并复制hibernate用于更新数据库的sql 将该 sql 粘贴到新的 Flyway 脚本中 关闭启动应用程序 删除本地数据库 将 ddl-auto 改回 validate 重启启动应用 测试以确保 Flyway 进行了正确的更新。 Hibernate 和 Flyway 现在将同步。

【讨论】:

这些行应该放在类路径根目录下的 application.properties 中 除了上述属性之外,我还必须在 application.properties 文件中包含“debug=true”,以使 DDL SQL 显示在日志中。 您还应该在application.properties 中包含logging.level.org.hibernate.tool.hbm2ddl=DEBUG,否则这些日志永远不会出现。请注意,这只允许与架构更新相关的调试日志,而不是所有可能溢出控制台的日志。 恕我直言 ***.com/a/36966419/474034 提供了比这更好的解决方案。【参考方案2】:

即使打开调试,设置 show-sql 的解决方案对我也不起作用,所以我最终编写并运行了这个简单的类。

public class SchemaExporter

public static org.hibernate.cfg.Configuration getConfiguration() 
    org.hibernate.cfg.Configuration cfg = new org.hibernate.cfg.Configuration();
    ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
    scanner.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
    for (BeanDefinition bd : scanner.findCandidateComponents("com.package.where.my.entitybeans.are")) 
        String name = bd.getBeanClassName();
        try 
            System.out.println("Added annotated entity class " + bd.getBeanClassName());
            cfg.addAnnotatedClass(Class.forName(name));
         catch (Exception e) 
            e.printStackTrace();
        
    

    cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
    cfg.setProperty("hibernate.show_sql", "true");
    cfg.setProperty("hibernate.format_sql", "true");
    cfg.setProperty("hibernate.hbm2ddl.auto", "update");
    cfg.setProperty("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");

    cfg.setProperty("hibernate.connection.url", CONNECTIONURL);
    cfg.setProperty("hibernate.connection.username", USERNAME);
    cfg.setProperty("hibernate.connection.password", PWD);
    cfg.setProperty("hibernate.connection.driver", DRIVER);
    return cfg;


public static void main(String[] args) 
    SchemaExport export = new SchemaExport(getConfiguration());
    export.setDelimiter(";");
    export.setHaltOnError(true);
    export.setFormat(true);
    export.create(true,true);



运行它我可以在控制台中看到 DDL 并按照 Chris 的建议继续

【讨论】:

以上是关于Spring Boot 和 Hibernate:打印/记录 DDL的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 和 Hibernate:打印/记录 DDL

如何使用 Hibernate 和 Spring Boot 配置和监控 HikariCP

当实体自引用时,Spring Boot 和 Hibernate 无法自动创建表

使用 Spring Boot、Jackson 和 Hibernate 的多对多关系

Spring boot、mvc、hibernate 和 mysql 配置 - sessionFactory 错误

使用 Spring Boot 和 Spring Data JPA 的 Hibernate 拦截器或侦听器