gpt4 book ai didi

spring - 将 hibernate 命名策略设置为 Spring bean

转载 作者:行者123 更新时间:2023-12-05 07:54:05 25 4
gpt4 key购买 nike

我有一个带有 Hibernate 的 spring-boot 应用程序。我想提供自定义 NamingStrategy 来为 hibernate 管理的每个表添加前缀。

我发现我可以使用属性:

spring.jpa.hibernate.naming_strategy=com.whatever.MyNamingStrategy

这很好用,除了我想拥有基于属性的动态前缀。我的目标是拥有类似的东西:

@Component
public class PrefixNamingStrategy extends DefaultNamingStrategy {

private final String prefix;

@Autowired
public PrefixNamingStrategy(@Value("db.table.prefix") String prefix) {
this.prefix = prefix;
}

@Override
public String tableName(String tableName) {
return prefix + super.tableName(tableName);
}
}

显然这不适用于属性。

我尝试提供自定义 SessionFactory 并在那里提供 NamingStrategy 但没有成功 - 该 bean 是在 hibernate 初始化之后创建的,甚至似乎没有被使用:

@Autowired
@Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(DataSource dataSource) {

LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);

sessionBuilder.setNamingStrategy(...); // !

return sessionBuilder.buildSessionFactory();
}

有没有办法提供自定义 NamingStrategy 作为 bean?

干杯

最佳答案

虽然知道这不太理想,但我最终通过了 VendorAdapter:

  1. 命名策略委托(delegate)者(注意 NamingStrategy 已被弃用):

    @Component
    public class PrefixNamingStrategyDelegator extends ImprovedNamingStrategyDelegator {

    @Autowired
    public PrefixNamingStrategyDelegator(final @Value("${application.environment}_") String prefix) {
    super(
    new HbmNamingStrategyDelegate() {
    @Override
    public String toPhysicalTableName(String tableName) {
    return prefix + super.toPhysicalTableName(tableName);
    }
    },
    new JpaNamingStrategyDelegate() {
    @Override
    public String toPhysicalTableName(String tableName) {
    return prefix + super.toPhysicalTableName(tableName);
    }
    }
    );
    }

    @Override
    public NamingStrategyDelegate getNamingStrategyDelegate(boolean isHbm) {
    return super.getNamingStrategyDelegate(isHbm);
    }
    }
  2. JpaPersistenceProviderNamingStrategyDelegator 潜入其中:

    @Component
    /**
    * See {@link org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider}
    *
    * We can't subclass that class but still need to sneak {@link org.hibernate.cfg.naming.NamingStrategyDelegator} into it.
    */
    public class SpringHibernateJpaPersistenceProviderWithNamingStrategy extends HibernatePersistenceProvider {

    private final NamingStrategyDelegator namingStrategy;

    @Autowired
    public SpringHibernateJpaPersistenceProviderWithNamingStrategy(NamingStrategyDelegator namingStrategy) {
    this.namingStrategy = namingStrategy;
    }

    @Override
    public EntityManagerFactory createContainerEntityManagerFactory(final PersistenceUnitInfo info, Map properties) {
    return new EntityManagerFactoryBuilderImpl(new PersistenceUnitInfoDescriptor(info), properties) {
    @Override
    public Configuration buildHibernateConfiguration(ServiceRegistry serviceRegistry) {
    Configuration configuration = super.buildHibernateConfiguration(serviceRegistry);
    if (info instanceof SmartPersistenceUnitInfo) {
    for (String managedPackage : ((SmartPersistenceUnitInfo) info).getManagedPackages()) {
    configuration.addPackage(managedPackage);
    }
    }

    configuration.setNamingStrategyDelegator(namingStrategy);

    return configuration;
    }
    }.build();
    }
    }
  3. 在我的@Configuration中:

    @Bean
    public AbstractJpaVendorAdapter customJPAVendorAdapter(HibernatePersistenceProvider jpaPersistenceProvider) {
    return new HibernateJpaVendorAdapter() {
    @Override
    public PersistenceProvider getPersistenceProvider() {
    return jpaPersistenceProvider;
    }
    };
    }

PersistenceProvider 本身是 SpringHibernateJpaPersistenceProvider 的原始副本(它的包是私有(private)的,不能被子类化),添加了一行:

configuration.setNamingStrategyDelegator(namingStrategy);

有效。但是很丑……(你知道的)

关于spring - 将 hibernate 命名策略设置为 Spring bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31829368/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com