我正在使用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;
}
答案 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:)