通过Spring Java配置在数据源中的配置问题

时间:2014-10-07 13:34:30

标签: spring spring-integration

我使用以下方式创建sessionFactory。

    @Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    //sessionFactory.setConfigLocation(getConfigLocation());
    sessionFactory.setDataSource(restDataSource());
    sessionFactory.setMappingResources(getMappingResources());
    sessionFactory.setHibernateProperties(hibernateProperties());
    return sessionFactory;
}

@Bean(destroyMethod="close")
public DataSource restDataSource() {

    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(env.getProperty("hibernate.connection.driver_class"));
    dataSource.setUrl(env.getProperty("hibernate.connection.url"));
    dataSource.setUsername(env.getProperty("hibernate.connection.username"));
    dataSource.setPassword(env.getProperty("hibernate.connection.password"));
    dataSource.setInitialSize(env.getRequiredProperty("hibernate.dbcp.initialSize", Integer.class));
    dataSource.setMaxActive(env.getRequiredProperty("hibernate.dbcp.maxActive", Integer.class));
    dataSource.setMaxIdle(env.getRequiredProperty("hibernate.dbcp.maxIdle", Integer.class));
    dataSource.setMinIdle(env.getRequiredProperty("hibernate.dbcp.minIdle", Integer.class));
    return dataSource;
}

我想使用在Tomcat服务器上配置的JNDI名称来实例化数据源。

所以我创建了另一个Bean

@Bean    
public DataSource dataSource() {
            //Method 1
            JndiObjectFactoryBean dataSource= new JndiObjectFactoryBean();
            dataSource.setJndiName("java:comp/env/jdbc/test");
            dataSource.setResourceRef(true);
            try {
                dataSource.afterPropertiesSet();
            } catch (IllegalArgumentException | NamingException e) {
                e.printStackTrace();
            }
            return (DataSource)dataSource.getObject();

            //Method 2
            /*final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
            dsLookup.setResourceRef(true);
            DataSource dataSource = dsLookup.getDataSource("java:comp/env/jdbc/test");
            return dataSource;*/

            }

当我使用sessionFactory.setDataSource(dataSource()); ,我无法实例化DataSource并获得以下异常。

java.sql.SQLException: No suitable driver
    at java.sql.DriverManager.getDriver(Unknown Source)
    at org.apache.commons.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1437)
    at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
    at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:141)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcServicesImpl.java:242)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:117)
    at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:85)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:184)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:156)
    at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1825)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1783)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1868)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:242)
....
...


Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL ''
    at org.apache.commons.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1452)
    at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
    at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:141)
    at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:301)
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:214)
    ... 52 more
Caused by: java.sql.SQLException: No suitable driver
    at java.sql.DriverManager.getDriver(Unknown Source)
    at org.apache.commons.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1437)

请让我知道我做错了什么。

此致 ANKUR

2 个答案:

答案 0 :(得分:0)

好像你试图使用未设置的'hibernate.connection.driver_class'属性。

答案 1 :(得分:0)

@Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(restDataSource());
    sessionFactory.setMappingResources(getMappingResources());
    sessionFactory.setHibernateProperties(hibernateProperties()); // Problematic line
    return sessionFactory;
}

主要问题是您正在使用与hibernate properties具有相同名称的占位符,并在LocalSessionFactoryBean中注入所有属性。我强烈建议不要使用它,如果你的文件名为hibernate.properties并且在类路径的根目录中,它将被hibernate自动获取。我建议只注入你需要的属性而不是一切。

我还建议重写您的sessionFactory()方法,为其提供DataSource参数,这将自动注入可用的DataSource

@Bean
public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource);
    sessionFactory.setMappingResources(getMappingResources());
    sessionFactory.setHibernateProperties(hibernateProperties()); // Problematic line
    return sessionFactory;
}

我建议使用JndiObjectFactoryBean或直接使用JndiDataSourceLookup,而不是使用JndiLocatorDelegate。这样可以节省JndiObjectFactoryBean的哈希值,并且当您捕获异常时(这可能会导致不可用的DataSource导致hibernate自行进行配置,因此您的方法存在缺陷。)现在似乎正在发生的事情。)

我还建议使用配置文件,以便您可以使用手动配置的数据源进行测试/本地部署,并使用基于jndi的数据源进行生产使用。