2016-12-02 224 views
0

我收到以下错误在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 

我已经从JBoss和嵌入式Tomcat服务器运行这一点,仍然得到这个错误。我甚至从战争中拿出了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; 
    } 

} 

二的DataSource

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

} 

application.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 

我一直在这里超过一个星期,我无法弄清楚为什么它说网址为空,后来当entityManagers创建说我的一个域包不是托管类型。它似乎有扫描第二套软件包的问题。我确认这改变了类名,因为我注意到它是按字母顺序编译的,当我这样做时,它改变了它所抱怨的包。 #note:每次运行同一个软件包时,它会选择一个不同的类,它们被注释为@Entity

我也使用@EntityScan,@ComponentScan,@SpringBootApplication,@EnableAutoConfiguration上的主要方法。

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

------------------------ Update 1 -------------------- ---------------

我只是把dataSource信息放入两个不同的yml文件中,仍然有同样的错误。然后我决定取出主要数据源,并将第二个数据源作为项目中唯一的数据源。 然后我得到了同样的错误。然而,URI和一切都是正确的,不知道为什么会发生这种情况。

回答

1

在创建使用弹簧启动(无SpringBootApplication注释)测试工具我最近遇到类似的问题,我终于发现,我需要使用数据源的属性和明确指定配置类@EnableConfigurationProperties:

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

数据源的属性定义的bean:

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

然后将它们注入数据源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自动配置的一部分。 (我认为这可能是因为春季启动数据源配置可能我的数据源配置后处理)

---更新:根据原始的源,修改,以符合我的分贝环境下工作的样品,使用弹簧启动1.3.1与入门网站和初学者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; 
} 
} 
+0

我没有你所说的话,事情正在寻找积极的,但现在它说,应用程序未能启动。说明:'无法确定数据库类型NONE'行动嵌入式数据库驱动程序类:'如果你想要一个嵌入式数据库,请把classpath中的支持之一。如果你必须从你可能需要主动它特定配置文件加载数据库设置(没有配置文件是当前活动).' – Drew1208

+0

但它只是说,第二数据源。 '通过方法'secondEntityMangerFactory'参数0表示的不满意的依赖性;嵌套的例外是org.springframework.beans.factory.BeanCreationException:' – Drew1208

+0

你能分享春天的引导版本和中拉引导软件包?我拿到了上面的原始代码,使用启动的web和starter jpa创建了一个项目,并且能够无误地启动应用程序。 –

0

你需要设置两套与

摆脱@Primary的唯一名称(即transactionManager2)豆 - 上面写着借此豆比其他。在这种情况下,您需要在上下文中使用两个bean - 因此需要唯一的名称。

看到:http://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html

如果你使用Spring数据JPA做:

@Configuration 
@EnableJpaRepositories(basePackageClasses = Customer.class, 
     entityManagerFactoryRef = "customerEntityManagerFactory") 
public class CustomerConfiguration { 
    ... 
} 

@Configuration 
@EnableJpaRepositories(basePackageClasses = Order.class, 
     entityManagerFactoryRef = "orderEntityManagerFactory") 
public class OrderConfiguration { 
    ... 
}