我有一个带有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?
干杯
答案 0 :(得分:0)
知道这不太理想我最终通过了VendorAdapter
:
命名策略委托人(注释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);
}
}
JpaPersistenceProvider
将NamingStrategyDelegator
潜入其中:
@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();
}
}
在我的@Configuration
:
@Bean
public AbstractJpaVendorAdapter customJPAVendorAdapter(HibernatePersistenceProvider jpaPersistenceProvider) {
return new HibernateJpaVendorAdapter() {
@Override
public PersistenceProvider getPersistenceProvider() {
return jpaPersistenceProvider;
}
};
}
PersistenceProvider
本身是SpringHibernateJpaPersistenceProvider
的原始副本(其包属于私有且无法分类)并添加了一行:
configuration.setNamingStrategyDelegator(namingStrategy);
作品。但丑陋......(你知道)