4

I have a very simple requirement which has turned complicated and I have spent a day on it without any luck. I have a properties file called jdbc.properties which has the DB connection details. I need to create a datasource connection with the values from the property file. The property value is not being passed right now, leading to DB connectivity error messages. If I hardcode the property values in the bean, it works. My spring config file myBatis.DataSource.config.xml looks like this.

<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <bean id="newProperty"    
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" lazy-  
    init="true">
        <property name="locations" value="jdbc.properties.${env}"/>
    </bean>
    <bean id="newDataSource"  class="org.apache.commons.dbcp.BasicDataSource" depends-
    on="newProperty" destroy-method="close">
        <property name="username" value="${DBUSER}" />
        <property name="password" value="${DBPASSWORD}" />
        <property name="url" value="${DBURL}" />
        <property name="driverClassName" value="${DRIVER}" />
        <property name="poolPreparedStatements" value="false" />
        <property name="defaultAutoCommit" value="false" />
        <property name="testOnBorrow" value="true" />
        <property name="testOnReturn" value="true" />
        <property name="testWhileIdle" value="true" />
        <property name="defaultTransactionIsolation" value="2" />
        <property name="timeBetweenEvictionRunsMillis" value="10000" />
    </bean>
    <bean id="sqlSessionFactory"   class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation"   
      value="com/automation/config/oneValidation-config.xml" />
        <property name="dataSource" ref="newDataSource" />
    </bean>
    <bean  class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
        <property name="basePackage" value="com.automation.config" />
    </bean>
</beans>

The value for ${env} is passed as a system property to the class. The code for the class is as below:

import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MybatisTest {


    public static void main(String[] args) {
        MybatisTest mybatisTest = new MybatisTest();
        mybatisTest.testSelectQuery();
    }

    public void testSelectQuery(){

        String resource = "oneValidation-config.xml";
        SqlSession session = null;
        try {
            ApplicationContext  context = new ClassPathXmlApplicationContext("myBatis.DataSource.config.xml");
            SqlSessionFactory sqlSessionFactory = (SqlSessionFactory)context.getBean("sqlSessionFactory");
            session = sqlSessionFactory.openSession(ExecutorType.BATCH);
            System.out.println("Test" + 
                   session.selectOne("com.automation.config.PostingMapper.
                   countByExample",null));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if(session != null)
            session.close();
        }
    }
}

The error I am getting is as shown below and is sue to the fact that the ${DBUSER}, ${DBPASSWORD} fields are not being retrieved from the property file jdbc.properties:

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause:                       
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC 
Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot 
create PoolableConnectionFactory (JZ00L: Login failed.  Examine the SQLWarnings chained 
to this exception for the reason(s).)
Community
  • 1
  • 1

2 Answers2

3

I ran accross this as well. In the mybatis documentation here I found why this happens.

From the source: "NOTE sqlSessionFactoryBean and sqlSessionTemplateBean properties were the only option available up to MyBatis-Spring 1.0.2 but given that the MapperScannerConfigurer runs earlier in the startup process that PropertyPlaceholderConfigurer there were frequent errors. For that purpose that properties have been deprecated and the new properties sqlSessionFactoryBeanName and sqlSessionTemplateBeanName are recommended."

Try changing your MapperScannerConfigurer bean from

<bean  class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    <property name="basePackage" value="com.automation.config" />  
</bean>

to

<bean  class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    <property name="basePackage" value="com.automation.config" />  
</bean>
0

Try this:

<property name="locations" value="classpath:/yourFolderName/jdbc.properties"/>
Alex
  • 11,451
  • 6
  • 37
  • 52