配置多个数据源后无法设置JPA命名策略(Spring 1.4.1/Hibernate 5.x) [英] Can't set JPA naming strategy after configuring multiple data sources (Spring 1.4.1 / Hibernate 5.x)

查看:97
本文介绍了配置多个数据源后无法设置JPA命名策略(Spring 1.4.1/Hibernate 5.x)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用使用Hibernate 5.0.11的Spring Boot 1.4.1.最初,我使用application.properties这样配置数据源:

I am using Spring Boot 1.4.1 which uses Hibernate 5.0.11. Initially I configured a data source using application.properties like this:

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

我使用"uncle"对其进行了配置,因为这将是我将配置的多个数据源之一的名称.根据Spring文档,我像这样配置了此数据源:

I configured it with "uncle" because that will be the name of one of multiple data sources that I'll configure. I configured this data source like this, according to the Spring docs:

@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.uncle")
public DataSource uncleDataSource() {
    return DataSourceBuilder.create().build();
}

此时一切正常.

我创建了一个没有任何@Column批注的@Entity类,并让Hibernate找出列名,例如,如果我有一个名为idBank的Java属性,则Hibernate将自动假定列名为id_bank.这在生成ddl,运行SQL语句等时使用.我想利用此功能,因为我将拥有很多实体类,并且不想创建和维护所有@Column注释.在这一点上,这很好.

I created an @Entity class without any @Column annotations and let Hibernate figure out the column names, for example if I have a Java property named idBank, Hibernate will automatically assume the column name is id_bank. This is used when generating ddl, running SQL statements, etc. I want to utilize this feature because I'm going to have a lot of entity classes and don't want to have to create and maintain all of the @Column annotations. At this point, this worked fine.

然后我添加了另一个像这样的数据源:

I then added another data source like this:

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

...以及在Spring文档中设置多个数据源之后的操作.显然,一旦定义了第二个数据源,它就无法配置默认bean,而您必须定义自己的EntityManagerTransactionManager.因此,除了上面配置的数据源之外,我还添加了以下配置:

... and also this, following the Spring docs for setting up multiple data sources. Apparently once you define a 2nd data source, it can't configure the default beans and you have to define your own EntityManager and TransactionManager. So in addition to the data source configured above, I added these configurations:

@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();
}

这在连接数据库和尝试获取数据方面起作用.

This works in terms of connecting to the database and trying to fetch data.

如何(这是问题所在,感谢您阅读本文).完成这些配置后,我失去了将Java列名称转换为蛇格名称的隐含命名策略,因此,现在如果我具有Java属性idBank,它将错误地使用列名称idBank而不是id_bank.我真的很想找回该功能.

HOWEVER (and here's the problem, thanks for reading this far). After these configurations I have lost the implied naming strategy that translates Java column names to snake case names, so now if I have a Java property idBank it incorrectly uses column name idBank instead of id_bank. I would really like to get that functionality back.

spring.jpa.hibernate.naming-strategy有一个JPA属性,并且在Spring和Hibernate中有各种命名策略类,例如org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy.因此,我尝试将其设置为:

There is a JPA property for this spring.jpa.hibernate.naming-strategy, and there are various naming strategy classes in Spring and Hibernate such as org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy. So I tried setting it like this:

spring.jpa.hibernate.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy

但是它没有用.我尝试了一些变体,例如:

But it did not work. I tried some variations such as:

spring.datasource.uncle.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy

spring.datasource.uncle.hibernate.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy

但这没有任何作用.

然后我读到在Hibernate 5中,命名策略分为物理"和隐式"两部分,并且每种设置都有不同的设置.所以我尝试了一下,有一些变化:

Then I read that in Hibernate 5, the naming strategy was broken up into two parts, "physical" and "implicit" and there are different settings for each. So I tried this, with a few variations:

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

spring.datasource.uncle.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

spring.datasource.uncle..hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy

但是这些都不起作用.

似乎应该有一种方法可以让我直接在Bean中(例如在SessionFactory上)设置此配置,但是我找不到该API.与此相关的文档似乎有一些空白.

It seems like there should be a way for me to set this configuration in the beans directly, such as on the SessionFactory, but I could not find that API. The documentation around this seems to have some gaps.

我真的很想避免设置persistence.xml,这是我到目前为止所不需要的.

I'd really like to avoid setting up a persistence.xml also, which I have not needed up to this point.

所以这是我遇到的困难,希望有人能帮忙.我真正想要的是一种调试这些属性设置的方法,我同时打开了org.springframeworkorg.hibernate的跟踪日志记录,但是那里没有任何用处.配置这些bean时,我尝试单步执行代码,但找不到发生这种情况的位置.如果有人拥有该信息并可以分享,我将非常感激.

So here is where I'm stuck and I'm hoping someone can help out. Really what I would like is a way to debug these property settings, I turned on trace logging in both org.springframework and org.hibernate but there was nothing useful there. I tried stepping through the code when these beans were configured but couldn't find the place where this happens. If anyone has that info and could share it I'd be really grateful.

推荐答案

我遇到了同样的问题,并使用以下代码(适用于问题中的代码-适用于单个实体管理器)修复了该问题:

I had the same problem and fixed it with the following code (adapted to the code in the question - for a single entity manager):

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();
}

这篇关于配置多个数据源后无法设置JPA命名策略(Spring 1.4.1/Hibernate 5.x)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆