You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.7.9+JPA多数据源下自定义命名策略Autowired注入失效

问题:多租户环境下Spring Boot JPA自定义命名策略无法注入依赖的问题

环境与JPA配置

我有一个基于Spring Boot 2.7.9和Spring Data JPA 2.7.8的应用,采用多租户Oracle UCP数据源,部分仓库基于JPA、部分基于JDBC,JPA配置如下:

@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder,
        TenantRoutingDataSource tenantRoutingDataSource) {
    return builder.dataSource(tenantRoutingDataSource)
                 .packages("com.orders", "com.orders.migration")
                 .build();
}

@Bean(name = "transactionManager")
public JpaTransactionManager transactionManager(
        @Autowired @Qualifier("entityManagerFactory") LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
    return new JpaTransactionManager(entityManagerFactoryBean.getObject());
}

自定义命名策略实现

我定义了如下命名策略类,它继承自CamelCaseToUnderscoresNamingStrategy,需要注入BatchProperties(用于从application.yml中读取可配置的表前缀,为指定表名添加前缀):

@AllArgsConstructor
@NoArgsConstructor
@Component
public class AppIdNamingStrategy extends CamelCaseToUnderscoresNamingStrategy {

    private BatchProperties batchProperties;

    @Override
    public Identifier toPhysicalTableName(final Identifier name, final JdbcEnvironment jdbcEnvironment) {
        return this.customize(name, jdbcEnvironment);
    }

    @Override
    public Identifier toPhysicalSequenceName(final Identifier name, final JdbcEnvironment jdbcEnvironment) {
        return this.customize(name, jdbcEnvironment);
    }
    private Identifier customize(Identifier name, JdbcEnvironment jdbcEnvironment) {
        if (name == null) {
            return null;
        } else {
            StringBuilder builder = new StringBuilder(name.getText().replace('.', '_'));

            for(int i = 1; i < builder.length() - 1; ++i) {
                if (this.isUnderscoreRequiredCustom(builder.charAt(i - 1), builder.charAt(i), builder.charAt(i + 1))) {
                    builder.insert(i++, '_');
                }
            }

            if(isCustomOrderIdentifier(name)) {
                builder.insert(0, batchProperties.getJdbc().getTablePrefix());
            }

            return this.getIdentifier(builder.toString(), name.isQuoted(), jdbcEnvironment);
        }
    }

    private boolean isCustomOrderIdentifier(final Identifier name) {
        return "custom_order".equalsIgnoreCase(name.getText());
    }

    private boolean isUnderscoreRequiredCustom(char before, char current, char after) {
        return Character.isLowerCase(before) && Character.isUpperCase(current) && Character.isLowerCase(after);
    }

    @Autowired
    public void setBatchProperties(final BatchProperties batchProperties) {
        this.batchProperties = batchProperties;
    }
}

遇到的问题

  • 尝试通过配置属性spring.jpa.hibernate.naming.physical-strategy指定该命名策略,但未被识别
  • 改用spring.jpa.properties.hibernate.physical_naming_strategy配置后,类被识别,但Hibernate会自行创建实例,而非使用Spring容器中已注入BatchProperties的Bean,导致BatchProperties未被注入
  • 补充:多数据源场景下,spring.jpa.hibernate.naming.physical-strategy完全无效

求助

  1. 如何通过程序化方式引入自定义命名策略服务,确保依赖被正确注入?
  2. 是否有办法获取Hibernate通过spring.jpa.properties.hibernate.physical_naming_strategy创建的命名策略实例?

内容的提问来源于stack exchange,提问作者humbleCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 07:03:23