设置休眠命名策略为Spring bean [英] Set hibernate naming strategy as Spring bean
问题描述
我有一个使用Hibernate的spring-boot应用程序。我想提供自定义的 NamingStrategy
为每个由hibernate管理的表添加前缀。
我发现我可以使用property :
spring.jpa.hibernate.naming_strategy = com.whatever.MyNamingStrategy
这可以很好地工作,除非我想根据属性设置动态前缀。我的目标是拥有类似于:
@Component
public class PrefixNamingStrategy extends DefaultNamingStrategy {
private final字符串前缀;
@Autowired
public PrefixNamingStrategy(@Value(db.table.prefix)字符串前缀){
this.prefix = prefix;
}
@Override
public String tableName(String tableName){
return prefix + super.tableName(tableName);
}
}
显然这不适用于属性。 / p>
我试图提供自定义 SessionFactory
并提供 NamingStrategy
但没有运气 - 这个bean是在hibernate初始化后创建的,甚至似乎没有被使用:
@Autowired
@Bean(name =sessionFactory)
public SessionFactory getSessionFactory(DataSource dataSource){
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionBuilder.setNamingStrategy(...); //!
return sessionBuilder.buildSessionFactory();
}
有没有办法提供自定义 NamingStrategy
as bean?
干杯
知道这是不理想的,我最终通过 VendorAdapter
:
- <命名策略委托者(注意
NamingStrategy
已被弃用):
@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;
}
};
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 theNamingStrategyDelegator
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; } }; }
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 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)
这篇关于设置休眠命名策略为Spring bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!