当前位置: 首页 > 知识库问答 >
问题:

配置多个数据源后无法设置JPA命名策略(Spring 1.4.1/Hibernate 5.x)

孙莫希
2023-03-14

我使用的是使用Hibernate 5.0.11的Spring Boot1.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

我将其配置为“叔叔”,因为这将是我要配置的多个数据源之一的名称。根据Spring文档,我这样配置了这个数据源:

@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注释。在这一点上,这起作用很好。

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。所以除了上面配置的数据源,我还添加了这些配置:

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

这在连接到数据库并尝试获取数据方面起作用。

然而(问题就在这里,谢谢阅读到这里)。在这些配置之后,我已经失去了将Java列名转换为snake大小写名称的隐含命名策略,因此,现在如果我有一个Java属性idbank,它将错误地使用列名idbank而不是id_bank。我真的很想要回那个功能。

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

但没有奏效。我尝试了一些变体,例如:

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

但这并没有起到任何作用。

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

我真的希望避免设置persistence.xml,到目前为止我还不需要它。

所以这就是我被困住的地方,我希望有人能帮忙。实际上,我想要的是一种调试这些属性设置的方法,我在org.springframeworkorg.hibernate中打开了跟踪日志记录,但没有任何有用的东西。当这些bean被配置时,我试着逐个执行代码,但找不到发生这种情况的地方。如果有人有这些信息,并能分享它,我会非常感激。

共有1个答案

秋阳旭
2023-03-14

我遇到了同样的问题,并用下面的代码修复了它(适应于问题中的代码--针对单个实体管理器):

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();
}
 类似资料:
  • 问题内容: 我正在使用postgresql数据库和spring + hibernate框架编写应用程序。 我将spring框架从4.1.5.RELEASE升级到4.2.0.RELEASE版本,并将hibernate框架从4.3.7.Final升级到了5.0.0.Final版本。 升级后,我在NamingStrategy中遇到问题。在postgresql数据库中,表列名称以小写字母用下划线分隔,在应

  • 我还向b_spring.xml声明了另一个entityManagetFactory、事务管理器和dataSource。 误差 bean初始化失败;嵌套异常是org.springframework.beans.factory.nosuchbeanDefinitionException:没有定义[javax.persistence.entityManagerFactory]类型的唯一bean:预期的单

  • 本文向大家介绍spring+Jpa多数据源配置的方法示例,包括了spring+Jpa多数据源配置的方法示例的使用技巧和注意事项,需要的朋友参考一下 今天临下班时遇到了一个需求,我的管理平台需要从不同的数据库中获取数据信息,这就需要进行Spring的多数据源配置,对于这种配置,第一次永远都是痛苦的,不过经历了这次的折磨,今后肯定会对这种配置印象深刻。我们这里简单回顾一下流程。 我们配置了两个数据库,

  • 我正在从Oracle数据库调用函数,并面临此异常: 组织。冬眠发动机查询ParameterRecognitionException:混合参数策略-仅使用命名、位置或JPA顺序策略之一 这是我的用户。java实体。 这就是我从服务类调用这个函数的方式。 那么,为了调用返回字符串的Oracle函数,需要做哪些更改。 谢谢。如果需要更多信息,请告诉我。

  • 在我的Gradle项目中,我对SQLite有一个依赖项。 这是我的build.gradle: 我尝试运行项目的构建,得到以下错误: 我的印象是,我收到的此错误与我有 2 个配置块的事实有关。一个用于配置我的 SQLite 模块,另一个用于处理所有模块的解析策略。这两个闭包似乎相互冲突。 有人对如何消除这两个闭包之间的冲突有什么建议吗?

  • 我有两个配置文件(“autoContido”和“weblogic”),其中每个配置文件都有两个配置类,因为我使用的是两个数据源。 我已经将特定数据源中的bean注释为@Primary,而另一个数据源配置类中的bean不是@Primary,但我对它们的命名不同。 我以为使用@主注释就不会有像下面这样的错误,但我仍然得到它们。有人能帮我看看问题出在哪里吗? 我尝试使用@Primary annotati