hibernate - 无法使用 Spring-Boot 创建多个数据源

标签 hibernate tomcat spring-boot jboss

我在使用 tomcat 时遇到以下错误:

09:06:18,168 WARNING [org.apache.tomcat.jdbc.pool.PooledConnection] (ServerService Thread Pool -- 6) Not loading a JDBC driver as driverClassName property is null.
09:06:18,170 SEVERE [org.apache.tomcat.jdbc.pool.ConnectionPool] (ServerService Thread Pool -- 6) Unable to create initial connections of pool.: java.sql.SQLException: The url cannot be null

我已经在 J​​BOSS 和嵌入式 tomcat 服务器中运行了这个,但仍然出现这个错误。我什至从 war 中取出 jar 文件并从 JBOSS 运行它,但仍然出现相同的错误。

我能够创建 EntityMangers,但在创建它们之前我收到了上述错误。该程序继续运行而不是提示类不是托管类型。但是,正在扫描那些 @Entities

我在 JBOSS 上遇到同样的错误:

09:06:18,171 WARN  [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator] (ServerService Thread Pool -- 6) HHH000342: Could not obtain connection to query metadata : The url cannot be null
09:06:18,183 INFO  [org.hibernate.dialect.Dialect] (ServerService Thread Pool -- 6) HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
09:06:18,199 INFO  [org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl] (ServerService Thread Pool -- 6) HHH000422: Disabling contextual LOB creation as connection was null

数据源:

@Configuration
@PropertySource("classpath:application.yml")
public class MainDataSourceConfig {
    
    /*******************************
     *       Datasource     *
     * *****************************/
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.dataSource.Main")
    public DataSource mainDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    /*******************************
     *  Transaction manager *
     * *****************************/
    @Bean
    @Primary
    DataSourceTransactionManager transactionManager(@Qualifier("mainDataSource") DataSource datasource) {
        DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource);
        return txm;
    }
    
    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("mainDataSource")DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactory.setPersistenceUnitName("mainEntityManger");
        entityManagerFactory.setDataSource(dataSource);
        entityManagerFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        entityManagerFactory.setJpaDialect(new HibernateJpaDialect());
        entityManagerFactory.setPackagesToScan("com.customers.domain");
        
        entityManagerFactory.setJpaProperties(additionalProperties());
        return entityManagerFactory;
    }
    
    private Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
        properties.setProperty("hibernate.ddl-auto","none");
        return properties;
    }
    
}

第二个数据源

@Configuration
@PropertySource("classpath:application.yml")
public class SecondDataSourceConfig {
    
    /*******************************
     *      Datasource      *
     * *****************************/
    @Bean
    @ConfigurationProperties(prefix="spring.dataSource.Second")
    public DataSource secondDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    /*******************************
     *  Transaction manager *
     * *****************************/
    @Bean
    DataSourceTransactionManager transactionManager(@Qualifier("secondDataSource") DataSource datasource) {
        DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
        return txm;
    }
    
    @Bean
    public LocalContainerEntityManagerFactoryBean keyviewEntityMangerFactory(@Qualifier("secondDataSource") DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactory.setPersistenceUnitName("secondEntityManger");
        entityManagerFactory.setDataSource(dataSource);
        entityManagerFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        entityManagerFactory.setJpaDialect(new HibernateJpaDialect());
        entityManagerFactory.setPackagesToScan("com.statements.domain");
        entityManagerFactory.setJpaProperties(additionalProperties());
        
        return entityManagerFactory;
    }
    
    private Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
        properties.setProperty("hibernate.ddl-auto","none");
        
        return properties;
    }
            
}

应用程序.yml

#Spring Boot Config for Oracle
spring:
  dataSource:
    Main:
      url: [url]
      username: [username]
      password: [password]
      driverClassName: oracle.jdbc.OracleDriver

    Second:
      url: [url]
      username: [username]
      password: [password]
      driverClassName: oracle.jdbc.OracleDriver

    tomcat:
      min-idle: 1

# Spring Boot Actuator settings
#https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html
endpoints.health.sensitive: false
#management.security.enabled: true
management.context-path: /healthCheck

endpoints.info.id: info
endpoints.info.sensitive: false
endpoints.info.enabled: true
info.app.name: Request
info.app.description: Request Description
info.app.version: 0.0.1-SNAPSHO

我已经处理这个问题一个多星期了,我不明白为什么它说 url 为空,后来当创建 entityManagers 时说我的域包之一不是托管类型。扫描第二组包似乎有问题。我确认这改变了类名,因为我注意到它是按字母顺序编译的,当我这样做时它改变了它提示的包。 #note:每次我运行同一个包时它都会选择一个不同的类,并且它们被 @Entity 注释。

我还在主要方法上使用了@EntityScan@ComponentScan@SpringBootApplication@EnableAutoConfiguration .

注意:当我删除第二个数据源时,一切正常。只有当我引入第二个时才会发生这种情况。

------------------------更新 1-------------------- --------------

我只是把dataSource信息放到了两个不同的yml文件中,还是报同样的错误。然后我决定把主要的数据源拿出来,把第二个作为项目中唯一的一个来实现。 THEN 我遇到了同样的错误。然而 URI 和一切都是正确的,不知道为什么会这样。

最佳答案

我最近在使用 spring boot(没有 SpringBootApplication 注释)创建测试工具时遇到了类似的问题,我最终发现我需要使用数据源属性并在配置类中显式指定 @EnableConfigurationProperties:

@Configuration
@EnableConfigurationProperties(value = DataSourceProperties.class)
public class ....

为数据源属性定义的 beans:

@Bean(name = "ds1Props")
@ConfigurationProperties(prefix = "path.to.ds1.properties")
public DataSourceProperties ds1DataSourceProperties() {
    return new DataSourceProperties();
}

@Bean(name = "ds2Props")
@ConfigurationProperties(prefix = "path.to.ds2.properties")
public DataSourceProperties ds2DataSourceProperties() {
    return new DataSourceProperties();
}

然后将它们注入(inject)到数据源 bean 方法中:

@Bean
public DataSource dataSource1(@Qualifier("ds1Props") DataSourceProperties ds1Props) {
    return ds1Props.initializeDataSourceBuilder().build();
}

@Bean
public DataSource dataSource2(@Qualifier("ds2Props") DataSourceProperties ds2Props) {
    return ds2Props.initializeDataSourceBuilder().build();
}

希望这对您有所帮助或助您一臂之力。我不确定为什么我需要明确地将其设置为 jdbc 自动配置的一部分。 (我想可能是因为spring boot数据源配置可能是在我的数据源配置之后处理的)

--- 更新:基于原始源的工作示例,修改以匹配我的数据库环境,使用 spring boot 1.3.1 和 starter web 和 starter jpa 包。 @Primary 需要满足对自动配置的 DataSourceInitializer 和 OpenSessionInViewInterceptor 的依赖。

@SpringBootApplication
public class Application {

public static void main(String[] args) {
    SpringApplication.run(new Object[] { Application.class }, args);
}

@Primary
@Bean
@ConfigurationProperties(prefix = "spring.dataSource.Main")
public DataSource mainDataSource() {
    return DataSourceBuilder.create().build();
}

@Bean
DataSourceTransactionManager mainTransactionManager(@Qualifier("mainDataSource") DataSource datasource) {
    DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource);
    return txm;
}

@Primary
@Bean
public LocalContainerEntityManagerFactoryBean mainEntityManagerFactory(
        @Qualifier("mainDataSource") DataSource dataSource) {
    LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactory.setPersistenceUnitName("mainEntityManger");
    entityManagerFactory.setDataSource(dataSource);
    entityManagerFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    entityManagerFactory.setJpaDialect(new HibernateJpaDialect());
    entityManagerFactory.setPackagesToScan("com.sbp.domain.main");
    entityManagerFactory.setJpaProperties(additionalProperties());
    return entityManagerFactory;
}

@Bean
@ConfigurationProperties(prefix = "spring.dataSource.Second")
public DataSource secondDataSource() {
    return DataSourceBuilder.create().build();
}

@Bean
DataSourceTransactionManager secondTransactionManager(@Qualifier("secondDataSource") DataSource datasource) {
    DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource);
    return txm;
}

@Bean
public LocalContainerEntityManagerFactoryBean secondEntityMangerFactory(
        @Qualifier("secondDataSource") DataSource dataSource) {
    LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactory.setPersistenceUnitName("secondEntityManger");
    entityManagerFactory.setDataSource(dataSource);
    entityManagerFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    entityManagerFactory.setJpaDialect(new HibernateJpaDialect());
    entityManagerFactory.setPackagesToScan("com.sbp.domain.second");
    entityManagerFactory.setJpaProperties(additionalProperties());
    return entityManagerFactory;
}

private Properties additionalProperties() {
    Properties properties = new Properties();
    properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
    properties.setProperty("hibernate.ddl-auto", "none");
    return properties;
}
}

关于hibernate - 无法使用 Spring-Boot 创建多个数据源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40934777/

相关文章:

tomcat - Spring Boot War-File 不适用于 Tomcat

java - Hibernate 限制 - 如何查询多个值?

tomcat - 在 Netbeans 中的 Tomcat 7 上运行 Java EE 7

java - 具有多个子域和 CAS 的 Liferay

java - 绝对 uri : http://www. springframework.org/tags 无法在 web.xml 或使用此应用程序部署的 jar 文件中解析

spring-security - Spring Security 通配符映射

java - 如何以与驱动程序无关的方式与 DB(SQL Server、PG)建立 SSL 连接?

java - 使用 Hibernate 获取当前修改的实体和数据库实体快照

java - PostgreSQL 上的 Hibernate 架构生成 : wrong column type UUID instead of INET

java - Tomcat 上的虚拟主机