【问题标题】:Spring boot and Hibernate: print/log DDLSpring Boot 和 Hibernate:打印/记录 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 设置的用途。

标签: java spring hibernate jpa spring-boot


【解决方案1】:

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

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

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

然后

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

【讨论】:

  • 这些行应该放在类路径根目录下的 application.properties 中
  • 除了上述属性之外,我还必须在 application.properties 文件中包含“debug=true”,以使 DDL SQL 显示在日志中。
  • 您还应该在application.properties 中包含logging.level.org.hibernate.tool.hbm2ddl=DEBUG,否则这些日志永远不会出现。请注意,这只允许与架构更新相关的调试日志,而不是所有可能溢出控制台的日志。
  • 恕我直言 stackoverflow.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 的建议继续

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 2017-11-01
    • 2017-10-01
    • 2015-11-25
    • 2021-07-14
    相关资源
    最近更新 更多