c3p0和hibernate用户/密码覆盖

时间:2013-04-03 11:09:54

标签: java spring hibernate connection-pooling c3p0

我正在使用spring 3.2和hibernate 4.2。我有2个bean:datasource(c3p0)和sessionFactory(LocalSessionFactoryBean)以及属性文件(application.properties)。

当我使用带有显式用户名和密码的java配置定义数据源时,一切正常。在启动期间c3p0记录其配置。例如'properties'属性是:

properties -> {user=******, password=******}

这是确切的输出

但是当我在xml中定义相同的数据源(也使用用户和密码)而不是在java中时,应用程序的行为方式不同。

'properties'属性显示

properties -> {java.runtime.name=xxx, line.separator=xxx, maven.home=xxx, ...}

和所有环境变量,但没有关于用户或密码。它拒绝连接到数据库:

java.sql.SQLException: ORA-01017: invalid username/password; logon denied

但在application.properties中我添加:

hibernate.connection.username=xxx
hibernate.connection.password=xxx

c3p0再次打印所有环境属性,没有用户和密码,但连接成功。好吧,好吧:池可以推送到会话工厂,但凭据必须在数据源

那是怎么回事?我希望拥有带有凭据和池配置的数据源以及使用hibernate配置的hibernate会话工厂。

如果重要的话。下面是我的配置:

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="xxx.model" />
        <property name="hibernateProperties">
            <util:properties location="classpath:/spring/application.properties" />
        </property>
    </bean>

xml ds:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="user" value="xxx"/>
        <property name="password" value="xxx"/>
        <property name="jdbcUrl" value="xxx"/>
    </bean>

和java ds:

@Bean
public DataSource dataSource() throws PropertyVetoException {
    ComboPooledDataSource ds = new ComboPooledDataSource();
    ds.setDriverClass("oracle.jdbc.driver.OracleDriver");
    ds.setUser("xxx");
    ds.setPassword("xxx");
    ds.setJdbcUrl("xxx");
    return ds;
}

2 个答案:

答案 0 :(得分:3)

所以这很奇怪。

我的猜测是这样的。 c3p0的DriverManagerDataSource有一个名为“properties”的属性,类型为java.util.Properties。

某处,您的中间件世界中的某些内容被配置为自动将此类属性设置为System.properties。这让我感到害怕,但似乎正在发生的事情。最好的办法是关闭此行为。这不是c3p0的事情,但除此之外,我不确定你应该在哪里看。

建议尝试在XML中显式设置properties属性[yuk]。也许这会阻止它默认为系统属性。参见例如here了解如何设置属性类型的属性。 properties属性应该包含一个名为“user”的键和一个名为“password”的键(并且不需要在这些属性之外设置用户和密码)。类似的东西:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="jdbcUrl" value="xxx"/>
    <property name ="properties">
       <props>
          <prop key="user">xxx</prop>
          <prop key="paswords">xxx</prop>
       </props>
    </property>
</bean>
祝你好运!

答案 1 :(得分:0)

上周我遇到了一个像这样的奇怪问题,在互联网上搜索我发现@Steve Waldman https://stackoverflow.com/a/15787141/2033885的这个问题和答案帮助我解决了这个问题。 我知道这个问题已经过时了,但我希望我的回答可以帮助别人。

下面我描述一下这个问题:

在ApplicationContext中使用C3P0 com.mchange.v2.c3p0.ComboPooledDataSource定义“datasource”bean时,属性“user”&amp; 'password'是显式设置或从Properties文件中获取值,在我的例子中是“persistence.properties”。 接下来是Application Context中的Data Source bean:

<context:property-placeholder location="classpath*:config/persistence.properties" />

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <!-- access -->
        <property name="driverClass" value="${driverClass}" />
        <property name="jdbcUrl" value="${jdbcUrl}" />
        <property name="user" value="${user}" />
        <property name="password" value="${password}" />
</bean>

我的错误是使用名为“user”的属性,当我在Windows中运行我的应用程序时它很好,但是......在Linux中,已经有一个名为“user”的系统属性覆盖了我的“用户”属性在persistence.properties中。 我的案例中的修复是在persistence.properties和应用程序上下文中将“user”更改为“jdbc.user”的属性名称:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <!-- access -->
        <property name="driverClass" value="${driverClass}" />
        <property name="jdbcUrl" value="${jdbcUrl}" />
        <property name="user" value="${jdbc.user}" />
        <property name="password" value="${jdbc.password}" />
</bean>

我一直在使用Windows开发,但测试和生产环境是Linux。我认为Tomcat是Tomcat并没有值得关注底层操作系统,但由于这个问题,我的经验教训是:最终部署环境始终很重要,无论您使用哪种Application Server:)