【问题标题】:Using spel with Hibernate Table and flyway将 spel 与 Hibernate Table 和 flyway 一起使用
【发布时间】:2020-04-24 20:26:43
【问题描述】:

鉴于 spring boot 应用程序的 application.yml 文件中存在这样的 SPEL 表达式 -

database:
      schema: '#{"${ENV_VAR:}".equals("")?"DEMO":"DEMO_${ENV_VAR:}"}'

以下代码在代码中工作,如果 ${ENV_VAR} = XYZ 则打印 DEMO_XYZ / DEMO 等替代值

@Value("${database.schema}")
private String schema;

但是带有表注释的 Hibernate JPA 实体无法将此处启用 SPEL 的变量作为模式 -

@Entity
@Table(name = "TABLE_A", schema="${database.schema}") // prints whole spel expression here 
public class TableA { ...

即使在下面也无法使用默认模式为 SPEL 使用替换值 -

spring:  
  jpa:
    show-sql: true
    properties:
      hibernate:
        default_schema: ${database.schema} // prints whole value here as well

似乎 flyway 无法使用已经在 application.yml 中定义好的 SPEL 变量

spring:  
  flyway:
    jdbc-url: ...
    schemas: ${database.schema}

hibernate.default_schemaflyway.schemas 有什么方法可以在同一个 YML 中接受像 ${database.schema} 这样的 SPEL 表达式?

【问题讨论】:

  • @table 和 hibernate 道具不是 spring 的一部分,因此解析不起作用。

标签: java spring hibernate spring-boot spring-el


【解决方案1】:

Spring Boot 实际上并不支持 application.yml 中的 SpEL。

如果你注入 Environment

String property = env.getProperty("database.schema");

您将看到占位符已解析,但 SpEL 未解析。

@Value 必须有一些额外的逻辑才能在下游进一步解析 SpEL。

【讨论】:

  • 实际上需要使用不同的模式,使用带有flyway和hibernate的三元组传递一个env变量,如果不使用Spel,yaml中有没有其他方法可以在这些字段中传递条件表达式?
【解决方案2】:

通过以编程方式创建 Hibernate JPA bean 和 Flyway bean 来修复它,而不是使用 YML,因为只有 @Value 注释能够读取 SPEL

database:
      schema: '#{"${ENV_VAR:}".equals("")?"DEMO":"DEMO_${ENV_VAR:}"}'

数据库配置


@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.xyz"})
@EntityScan(basePackages = {"com.xyz"})
public class DbConfig
{
    @Value("${database.schema}")
    private String schema; 

    @Bean
    public EntityManager entityManager(SessionFactory sessionFactory)
    {
        return sessionFactory.createEntityManager();
    }

    @Bean
    public PlatformTransactionManager transactionManager()
    {
        return new JpaTransactionManager();
    }

    @Bean
    public HikariConfig hikariConfig()
    {
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName("net.client.jdbc.Driverx");
        hikariConfig.setJdbcUrl(url);
        Properties props = new Properties();
        props.put("user", user);
        props.put("password", password);
        props.put("db", db);
        props.put("schema", schema);  // SCHEMA is from SPEL
        hikariConfig.setDataSourceProperties(props);
        return hikariConfig;
    }

    @Bean
    public DataSource dataSource(HikariConfig hikariConfig)
    {
        HikariDataSource dataSource = new HikariDataSource(hikariConfig);
        return dataSource;
    }

    @Bean
    public LocalSessionFactoryBean entityManagerFactory(DataSource snowflakeDataSource)
    {
        LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
        localSessionFactoryBean.setDataSource(dataSource);
        localSessionFactoryBean.setPackagesToScan("com.xyz");
        Properties properties = new Properties();
        properties.setProperty("hibernate.default_schema", schema);
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        properties.setProperty("hibernate.show_sql", "true");
        properties.setProperty("hibernate.format_sql", "true");
        localSessionFactoryBean.setHibernateProperties(properties);
        return localSessionFactoryBean;
    }

飞路配置

    @Value("${database.schema}")
    private String schema;

    @Bean
    public Flyway flyway(DataSource dataSource)
    {
        Flyway flyWay = Flyway.configure()
            .dataSource(dataSource)
            .locations("classpath:/somefolder/migrations")
            .schemas(schema)  // SCHEMA is from SPEL
            .baselineVersion("1.0")
            .sqlMigrationPrefix("V")
            .sqlMigrationSuffixes(".sql")
            .placeholders(Map.of("key1", value1,
                "key2", value2))
            .placeholderReplacement(true)
            .placeholderPrefix("%")
            .placeholderSuffix("%")
            .load();
        flyWay.migrate();
        return flyWay;
    }

【讨论】:

    猜你喜欢
    • 2015-04-03
    • 2017-04-01
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    相关资源
    最近更新 更多