3

我正在使用spring 3.2和hibernate 4.2。我有 2 个 bean:数据源(c3p0)和带有属性文件(application.properties)的 sessionFactory(LocalSessionFactoryBean)。

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

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

这是确切的输出

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

“属性”属性显示

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 再次打印所有没有用户和密码的环境属性,但连接成功。好吧,好的:可以将池推送到会话工厂,但凭据必须在数据源中

发生什么了?我想要具有凭据和池配置的数据源以及具有休眠配置的休眠会话工厂。

以防万一。下面是我的配置:

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

2 回答 2

3

所以这很奇怪。

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

在某个地方,您的中间件世界中的某些东西被配置为自动将此类属性设置为 System.properties。这让我觉得是一件坏事,但它似乎就是正在发生的事情。最好的办法是关闭此行为。这不是 c3p0 的事情,但除此之外,我不确定你应该去哪里看。

一个建议是尝试在您的 XML 中明确设置 properties 属性 [yuk]。也许这会阻止它默认为系统属性。有关如何设置属性类型的属性,请参见此处。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>

祝你好运!

于 2013-04-03T12:17:01.190 回答
0

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

下面我描述这个问题:

当您在 ApplicationContext 中使用 C3P0 com.mchange.v2.c3p0.ComboPooledDataSource 定义“数据源”bean 时,会显式设置属性“用户”和“密码”或从属性文件中获取值,在我的情况下为“persistence.properties” . 接下来我在应用程序上下文中的数据源 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”的系统属性在持久性中覆盖了我的“user”属性。特性。在我的情况下,修复是在 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,没有必要过多关注底层操作系统,但由于这个问题,我学到的教训是:最终部署环境总是很重要,无论您使用哪个应用程序服务器 :)

于 2014-12-08T20:15:22.737 回答