Today, during the integration of Spring and MyBatis, we conducted tests and found that the SQL query could not connect to the database. The exception log is as follows:
org.mybatis.spring.MyBatisSystemException: nested exception is 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 (ORA-01017: invalid username/password; logon denied
)
### The error may exist in com/summerzhou/base/mapper/SysuserMapper.xml
### The error may involve com.summerzhou.base.mapper.SysuserMapper.selectByPrimaryKey
### The error occurred while executing a query
### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (ORA-01017: invalid username/password; logon denied
)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:371)
at com.sun.proxy.$Proxy3.selectOne(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:163)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:63)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:43)
at com.sun.proxy.$Proxy4.selectByPrimaryKey(Unknown Source)
at com.summerzhou.test.TestClass.findUserById(TestClass.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
The user/password is not valid. I have tried Oracle and the password is correct. Then check db.properties to see that the username and password are correct
driverClassName=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@192.168.25.129:1521:orcl
username=tommy
password=***
Use the Spring Framework to get a DataSource instance. Check the userName of the DataSource and find that the result is X, not Tommy specified in the DB file.
@Test
public void setDateSource() {
BasicDataSource dataSource = (BasicDataSource) applicationContext.getBean("dataSource");
System.out.println(dataSource.getUsername());
}
I suddenly realized that x was the username of my native. I looked it up. context:property-placeholder> Is used to activate “${} placeholder, parsing the location attribute defined in the file, generated a accomplished instance, accomplished to externalize based on Java properties format defined properties, and can make the programmer to customize the specific environmental properties, such as a database url and password, so that we can only change the corresponding properties file, without affecting framework.
in my definition of db. The properties, the user name of the key for the username, dataSource injection of attribute value is ${username}, but this username is not the values in the file. Because is accomplished not only in the specified attributes defined in the properties file, also will check the properties in the Java runtime environment. We can customize the order in which the properties are checked by the system-properties-mode property, which has four values:
1) ENVIRONMENT: default property, which is read in the runtime first, or in the properties file specified in the location if the specified property value is not obtained.
2) None: Never check the system properties, only resolve the properties file
) Override: system-local properties
4>allback: properties before system
In conclusion, there are two solutions:
1. The key from the properties file before fully coupled with JDBC., so when reading properties don’t conflict with system properties
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.25.129:1521:orcl
jdbc.username=tommy
jdbc.password=****
DataSource injection changed to:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
2. Will & lt; context:property-placeholder> Change the system-properties-mode to None or Fallback