Java 使用hibernate以编程方式验证架构

Java 使用hibernate以编程方式验证架构,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,在mose项目中,使用模式验证运行java应用程序的方法是使用该配置(使用spring时): 我遇到了一个问题,我需要在运行期间的特定时间验证我的模式,有什么方法可以实现吗 我看到hibernate用, 我将spring与hibernate一起使用,但我没有找到任何关于如何处理它的信息,我找到的唯一信息是,但它已在较旧版本的spring boot <dependency> <groupId>org.springframework.data</groupId&

在mose项目中,使用模式验证运行
java应用程序的方法是使用该配置(使用spring时):

我遇到了一个问题,我需要在运行期间的特定时间验证我的模式,有什么方法可以实现吗

我看到hibernate用, 我将spring与hibernate一起使用,但我没有找到任何关于如何处理它的信息,
我找到的唯一信息是,但它已在较旧版本的
spring boot

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>2.0.4.RELEASE</version>
</dependency>

org.springframework.data
spring数据jpa
2.0.4.1发布

有什么想法吗?

这是解决方案,如果您的用例需要:

  • 细粒度&明确控制架构的哪一部分应该是 验证
  • 需要验证多个模式
  • 需要验证服务未使用的模式,定时验证器正在该服务上运行
  • 应用程序使用的db连接不应以任何方式受到验证的影响(也就是说,您不想从主连接池借用连接)
如果以上内容适用于您的需要,则这是如何执行计划架构验证的示例:

  • 来源
  • application.yml
  • docker compose.yml

  • 如果希望让
    SchemaValidator
    重用项目中已配置的连接配置和映射信息,而不是再次定义它们以进行模式验证,你应该考虑我的解决方案,使你干燥,不需要将这些配置保持在两个不同的地方。

    实际上,
    SchemaValidator
    需要的是
    Metadata
    实例,它只在引导Hibernate时可用。但是我们可以使用Hibernate Integrator API(如中所述)来捕获它,以便稍后进行验证

    (1) 创建
    SchemaValidateService
    ,该服务实现Hibernate Integrator API以捕获
    元数据。还要设置一个
    @Scheduled
    方法,以便在所需时间验证架构

    @Component
    public class SchemaValidateService implements Integrator {
    
        private Metadata metadata;
    
        @Override
        public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory,
                SessionFactoryServiceRegistry serviceRegistry) {
            this.metadata = metadata;
        }
    
        @Override
        public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
        }
    
        //Adjust the scheduled time here
        @Scheduled(cron = "0 0/1 * * * ?")
        public void validate() {
            try {
                System.out.println("Start validating schema");
                new SchemaValidator().validate(metadata);
            } catch (Exception e) {
                //log the validation error here.
            }
            System.out.println("Finish validating schema....");
        }
    }
    
    (2) 注册SchemaValidateService以休眠

    @SpringBootApplication
    @EnableScheduling
    public class App {
    
        @Bean
        public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(SchemaValidateService schemaValidateService) {
            return (prop -> {
                List<Integrator> integrators = new ArrayList<>();
                integrators.add(schemaValidateService);
                prop.put("hibernate.integrator_provider", (IntegratorProvider) () -> integrators);
            });
        }
    }
    
    @springboot应用程序
    @使能调度
    公共类应用程序{
    @豆子
    公共HibernatePropertiesCustomizer HibernatePropertiesCustomizer(SchemaValidateService SchemaValidateService){
    返回(道具->{
    列表积分器=新的ArrayList();
    integrators.add(schemaValidateService);
    prop.put(“hibernate.integrator\u provider”,(IntegratorProvider)(->integrators);
    });
    }
    }
    

    此外,此解决方案应该具有更好的性能,因为它不需要每次都创建新的数据库连接来验证架构,因为它可以从现有连接池中获取连接。

    这似乎是一个问题。你的用例是什么?我需要每10分钟验证一次我的模式@Turing85我想Turing85想知道为什么你需要每10分钟验证一次模式。哦,这是我们架构中的一个东西@Oresteviron的可能副本我想使用自己的配置获取元数据,但是,当我创建自己的一个时,我得到的是:在名称空间中找到了不止一个表。你的意思是你想自己再次创建
    元数据
    ,而不是重复使用hibernate已经构建的现有数据包吗?有没有担心你无法配置自己的数据包,而你想将其作为常用的hibernate实体数据包进行验证这样hibernate就已经为您构建了元数据了?如果您想自己构建元数据,应该参考其他人提出的解决方案。这个解决方案的精神是提出一些与已经提出的不同的东西,因此我们不打算自己去摆弄元数据。非常感谢!
    CREATE DATABASE IF NOT EXISTS testdb;
    
    CREATE TABLE IF NOT EXISTS `table1` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      PRIMARY KEY (`id`)
    );
    
    CREATE TABLE IF NOT EXISTS `table2` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      PRIMARY KEY (`id`)
    );
    
    
    spring:
      cache:
        type: none
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3309/testdb?useSSL=false&nullNamePatternMatchesAll=true&serverTimezone=UTC&allowPublicKeyRetrieval=true
        username: test_user
        password: test_password
        testWhileIdle: true
        validationQuery: SELECT 1
      jpa:
        show-sql: false
        database-platform: org.hibernate.dialect.MySQL8Dialect
        hibernate:
          ddl-auto: none
          naming:
            physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
            implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
        properties:
          hibernate.dialect: org.hibernate.dialect.MySQL8Dialect
          hibernate.cache.use_second_level_cache: false
          hibernate.cache.use_query_cache: false
          hibernate.generate_statistics: false
          hibernate.hbm2ddl.auto: validate
    
    schema-validator:
        settings:
            connection.driver_class: com.mysql.cj.jdbc.Driver
            hibernate.dialect: org.hibernate.dialect.MySQL8Dialect
            hibernate.connection.url: jdbc:mysql://localhost:3309/testdb?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
            hibernate.connection.username: test_user
            hibernate.connection.password: test_password
            hibernate.default_schema: testdb
    
    
    version: '3.0'
    
    services:
      db:
        image: mysql:8.0.14
        restart: always
        ports:
         - 3309:3306
        environment:
          MYSQL_ROOT_PASSWORD: test_password
          MYSQL_DATABASE: testdb
          MYSQL_USER: test_user
          MYSQL_PASSWORD: test_password
    
    @Component
    public class SchemaValidateService implements Integrator {
    
        private Metadata metadata;
    
        @Override
        public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory,
                SessionFactoryServiceRegistry serviceRegistry) {
            this.metadata = metadata;
        }
    
        @Override
        public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
        }
    
        //Adjust the scheduled time here
        @Scheduled(cron = "0 0/1 * * * ?")
        public void validate() {
            try {
                System.out.println("Start validating schema");
                new SchemaValidator().validate(metadata);
            } catch (Exception e) {
                //log the validation error here.
            }
            System.out.println("Finish validating schema....");
        }
    }
    
    @SpringBootApplication
    @EnableScheduling
    public class App {
    
        @Bean
        public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(SchemaValidateService schemaValidateService) {
            return (prop -> {
                List<Integrator> integrators = new ArrayList<>();
                integrators.add(schemaValidateService);
                prop.put("hibernate.integrator_provider", (IntegratorProvider) () -> integrators);
            });
        }
    }