更新时间:2023-10-09 17:19:16
知道这是不理想的,我最终通过 VendorAdapter
:
@Component
将
public class PrefixNamingStrategyDelegator extends ImprovedNamingStrategyDelegator {
$ b @Autowired
public PrefixNamingStrategyDelegator(final @Value($ {application.environment} _)字符串前缀){
super(
new HbmNamingStrategyDelegate(){
@Override
public String toPhysicalTableName(String tableName){
return prefix + super.toPhysicalTableName(tableName);
}
},
new JpaNamingStrategyDelegate(){
@Override
public String toPhysicalTableName(String tableName){
返回前缀+ super.toPhysicalTableName(tableName);
}
}
);
}
@Override
public NamingStrategyDelegate getNamingStrategyDelegate(boolean isHbm){
return super.getNamingStrategyDelegate(isHbm);
$ / code $ $ J $ P $ J $>NamingStrategyDelegator
放入其中:@Component
/ **
*请参阅{@link org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider}
*
*我们不能继承这个类,但仍然需要潜入{@link org.hibernate.cfg.naming.NamingStrategyDelegator}。
* /
public class SpringHibernateJpaPersistenceProviderWithNamingStrategy扩展HibernatePersistenceProvider {
private final NamingStrategyDelegator namingStrategy;
@Autowired
public SpringHibernateJpaPersistenceProviderWithNamingStrategy(NamingStrategyDelegator namingStrategy){
this.namingStrategy = namingStrategy;
$ b @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); $(b)如果(info instanceof SmartPersistenceUnitInfo){
for(String managedPackage:((SmartPersistenceUnitInfo)info).getManagedPackages()){
configuration.addPackage(managedPackage);
}
}
configuration.setNamingStrategyDelegator(namingStrategy);
返回配置;
}
} .build();
code $
$ li $@Configuration
:@Bean
public AbstractJpaVendorAdapter customJPAVendorAdapter(HibernatePersistenceProvider jpaPersistenceProvider){
返回新的HibernateJpaVendorAdapter(){
@Override
public PersistenceProvider getPersistenceProvider(){
return jpaPersistenceProvider;
}
};
PersistenceProvider
本身就是 SpringHibernateJpaPersistenceProvider
的原始副本(它的包私有并且不能被分类):
configuration.setNamingStrategyDelegator(namingStrategy);
作品。但丑陋的......(你知道)
I have a spring-boot application with Hibernate. I want to provide custom NamingStrategy
to add prefix to every table managed by hibernate.
I found I can use property:
spring.jpa.hibernate.naming_strategy=com.whatever.MyNamingStrategy
This works fine except I want to have the prefix dynamic based on properties. My goal would be to have something like:
@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);
}
}
Obviously this doesn't work with the property.
I tried to provide custom SessionFactory
and provide the NamingStrategy
there but had no luck - the bean was created after hibernate initialized and even doesn't seem to be used:
@Autowired
@Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(DataSource dataSource) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionBuilder.setNamingStrategy(...); // !
return sessionBuilder.buildSessionFactory();
}
Is there a way how to provide custom NamingStrategy
as bean?
Cheers
Well knowing this is less than ideal I ended up going through VendorAdapter
:
The naming strategy delegator (note NamingStrategy
has been deprecated):
@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);
}
}
The JpaPersistenceProvider
to sneak the NamingStrategyDelegator
into it:
@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();
}
}
In my @Configuration
:
@Bean
public AbstractJpaVendorAdapter customJPAVendorAdapter(HibernatePersistenceProvider jpaPersistenceProvider) {
return new HibernateJpaVendorAdapter() {
@Override
public PersistenceProvider getPersistenceProvider() {
return jpaPersistenceProvider;
}
};
}
The PersistenceProvider
itself is raw copy (its package private and can't be sub classed) of SpringHibernateJpaPersistenceProvider
with added line:
configuration.setNamingStrategyDelegator(namingStrategy);
Works. But ugly as ... (you know)