将hibernate命名策略设置为Spring bean

时间:2015-08-05 10:06:21

标签: spring hibernate spring-boot

我有一个带有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但没有运气 - 在初始化hibernate之后创建了bean,甚至似乎没有使用:

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

    LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);

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

    return sessionBuilder.buildSessionFactory();
}

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

干杯

1 个答案:

答案 0 :(得分:0)

知道这不太理想我最终通过了VendorAdapter

  1. 命名策略委托人(注释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;
            }
        };
    }
    
  4. PersistenceProvider本身是SpringHibernateJpaPersistenceProvider的原始副本(其包属于私有且无法分类)并添加了一行:

    configuration.setNamingStrategyDelegator(namingStrategy);
    

    作品。但丑陋......(你知道)