Unc*_*air 23 spring hibernate spring-data-jpa spring-boot
我使用的是使用Hibernate 5.0.11的Spring Boot 1.4.1.最初我使用application.properties如下配置数据源:
spring.datasource.uncle.url=jdbc:jtds:sqlserver://hostname:port/db
spring.datasource.uncle.username=user
spring.datasource.uncle.password=password
spring.datasource.uncle.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.datasource.uncle.driverClassName=net.sourceforge.jtds.jdbc.Driver
Run Code Online (Sandbox Code Playgroud)
我用"叔叔"配置它,因为这将是我将配置的多个数据源之一的名称.我根据Spring文档配置了这样的数据源:
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.uncle")
public DataSource uncleDataSource() {
return DataSourceBuilder.create().build();
}
Run Code Online (Sandbox Code Playgroud)
在这一点上一切正常.
我创建了一个@Entity没有任何@Column注释的类,让Hibernate找出列名,例如,如果我有一个名为Java的属性idBank,Hibernate将自动假设列名为id_bank.这在生成ddl,运行SQL语句等时使用.我想利用此功能,因为我将拥有大量实体类,并且不希望创建和维护所有@Column注释.在这一点上,这很好.
然后我添加了另一个这样的数据源:
spring.datasource.aunt.url=jdbc:sybase:Tds:host2:port/db2
spring.datasource.aunt.username=user2
spring.datasource.aunt.password=password2
spring.datasource.aunt.dialect=org.hibernate.dialect.SybaseDialect
spring.datasource.aunt.driverClassName=com.sybase.jdbc4.jdbc.SybDriver
Run Code Online (Sandbox Code Playgroud)
......还有这个,遵循Spring文档设置多个数据源.显然,一旦定义了第二个数据源,它就无法配置默认bean,你必须定义自己的EntityManager和TransactionManager.所以除了上面配置的数据源之外,我还添加了以下配置:
@Bean
@Primary
PlatformTransactionManager uncleTransactionManager(@Qualifier("uncleEntityManagerFactory") final EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
@Bean
@Primary
LocalContainerEntityManagerFactoryBean uncleEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(uncleDataSource())
.packages(Uncle.class)
.persistenceUnit("uncle")
.build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.aunt")
public DataSource auntDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
PlatformTransactionManager auntTransactionManager(@Qualifier("auntEntityManagerFactory") final EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
@Bean
LocalContainerEntityManagerFactoryBean auntEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(auntDataSource())
.packages(Aunt.class)
.persistenceUnit("aunt")
.build();
}
Run Code Online (Sandbox Code Playgroud)
这适用于连接到数据库并尝试获取数据.
然而(这是问题,感谢你阅读这篇文章).在这些配置之后,我已经失去了将Java列名转换为蛇案例名称的隐含命名策略,所以现在如果我有一个Java属性,idBank它会错误地使用列名idBank而不是id_bank.我真的想要恢复这个功能.
有一个JPA属性,spring.jpa.hibernate.naming-strategy在Spring和Hibernate中有各种命名策略类,如org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy.所以我尝试这样设置:
spring.jpa.hibernate.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
Run Code Online (Sandbox Code Playgroud)
但它没有用.我尝试了一些变化,例如:
spring.datasource.uncle.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
Run Code Online (Sandbox Code Playgroud)
和
spring.datasource.uncle.hibernate.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
Run Code Online (Sandbox Code Playgroud)
但这没有任何效果.
然后我读到在Hibernate 5中,命名策略分为两部分,"物理"和"隐式",每种都有不同的设置.所以我尝试了这个,有一些变化:
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
Run Code Online (Sandbox Code Playgroud)
和
spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
Run Code Online (Sandbox Code Playgroud)
和
spring.datasource.uncle.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
Run Code Online (Sandbox Code Playgroud)
和
spring.datasource.uncle..hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
Run Code Online (Sandbox Code Playgroud)
但这些都没有奏效.
似乎应该有一种方法让我直接在bean中设置这个配置,比如在SessionFactory,但是我找不到那个API.围绕这个的文档似乎有一些差距.
我真的很想避免设置一个persistence.xml我也不需要的东西.
所以这就是我被困住的地方,我希望有人可以提供帮助.真的我想要的是一种调试这些属性设置的方法,我在两者中启用了跟踪日志记录org.springframework,org.hibernate但那里没有什么用处.我尝试在配置这些bean时单步执行代码,但找不到发生这种情况的地方.如果有人有这些信息并且可以分享它,我会非常感激.
ewe*_*ert 49
我有同样的问题并使用以下代码修复它(适用于问题中的代码 - 对于单个实体管理器):
protected Map<String, Object> jpaProperties() {
Map<String, Object> props = new HashMap<>();
props.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
props.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
return props;
}
@Primary
@Bean(name = "defaultEntityManager")
public LocalContainerEntityManagerFactoryBean defaultEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(auntDataSource())
.packages(Aunt.class)
.persistenceUnit("aunt")
.properties(jpaProperties())
.build();
}
Run Code Online (Sandbox Code Playgroud)
mar*_*osh 15
可以使用属性获得与@ewert 相同的答案:
# this works
spring.jpa.properties.hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
spring.jpa.properties.hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
# but that doesn't work
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
Run Code Online (Sandbox Code Playgroud)
根据您最新的问题,我想我可以解释为什么默认行为消失。
从 Spring Boot 2.4.2 开始,默认配置通过以下方法启动JpaBaseConfiguration:
@Bean
@Primary
@ConditionalOnMissingBean({ LocalContainerEntityManagerFactoryBean.class, EntityManagerFactory.class })
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder factoryBuilder) {
Map<String, Object> vendorProperties = getVendorProperties();
customizeVendorProperties(vendorProperties);
return factoryBuilder.dataSource(this.dataSource).packages(getPackagesToScan()).properties(vendorProperties)
.mappingResources(getMappingResources()).jta(isJta()).build();
}
Run Code Online (Sandbox Code Playgroud)
它发生在customizeVendorProperties方法调用中。
通过创建您自己的LocalContainerEntityManagerFactoryBeanbean(实际上是两个),就不再执行此定制。
| 归档时间: |
|
| 查看次数: |
5396 次 |
| 最近记录: |