INSERT INTO rbp_users
(user_id, user_name, passwd, bank_id, descr, stat, p_exp, user_type_id, email_address)
VALUES
(rbp_userid_seq.NEXTVAL ,
'any_user_name',
'some_encrypted_password',
1,
N'əəııööğğşşççüü', --unicode string
'E',
SYSDATE,
2,
NULL);
上面插入带有 NVARCHAR 字段“descr”的 Oracle 表可以通过 PL/SQL Developer 正常工作。但是我不能在 MyBatis DAO Mapper XML 的 unicode 字段之前写“N”:
<insert id="addUser" parameterType="User" flushCache="true">
INSERT INTO rbp_users
(user_id, user_name, passwd, bank_id, descr, stat, p_exp, user_type_id, email_address)
VALUES
(rbp_userid_seq.NEXTVAL ,
#{userName, javaType=String, jdbcType=VARCHAR},
pswcode(#{password, javaType=String, jdbcType=VARCHAR}),
#{bankId, javaType=Integer, jdbcType=NUMERIC},
N#{description, javaType=String, jdbcType=NVARCHAR},
#{userStatus, javaType=String, jdbcType=VARCHAR},
#{passwordExpireDate, javaType=Date, jdbcType=DATE},
#{userTypeId, javaType=Integer, jdbcType=NUMERIC},
#{emailAddress, javaType=String, jdbcType=VARCHAR})
<selectKey resultType="java.lang.Integer" keyProperty="userId">
SELECT rbp_userid_seq.currval from dual
</selectKey>
</insert>
这引发和错误:
org.springframework.jdbc.InvalidResultSetAccessException:使用 JdbcType VARCHAR 为参数 #8 设置 null 时出错。尝试为此参数设置不同的 JdbcType 或不同的 jdbcTypeForNull 配置属性。原因:java.sql.SQLException:无效的列索引 ; SQL [] 的 ResultSet 访问无效;嵌套异常是 java.sql.SQLException: Invalid column index 在 org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:237) 在 org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) 在 org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:71) 在 org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:365) 在 $Proxy20.insert(未知来源) 在 org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:237) 在 org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:79) 在 org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:40) 在 $Proxy37.addUser(未知来源) 在 com.azercell.paymentgateway.service.UserServiceImpl.addUser(UserServiceImpl.java:156) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 在 org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:42) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 在 org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 在 $Proxy38.addUser(未知来源) 在 com.azercell.paymentgateway.service.UserServiceImplTest.testAddUser(UserServiceImplTest.java:101) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 在 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 在 org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 在 org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) 在 org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) 在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:242) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:58) 在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:240) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:48) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:233) 在 org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 在 org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:303) 在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:157) 在 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76) 在 com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195) 在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 原因:java.sql.SQLException: Invalid column index 在 oracle.jdbc.driver.OraclePreparedStatement.setNullCritical(OraclePreparedStatement.java:4554) 在 oracle.jdbc.driver.OraclePreparedStatement.setNull(OraclePreparedStatement.java:4541) 在 oracle.jdbc.driver.OraclePreparedStatementWrapper.setNull(OraclePreparedStatementWrapper.java:1283) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 org.apache.tomcat.jdbc.pool.interceptor.AbstractQueryReport$StatementProxy.invoke(AbstractQueryReport.java:235) 在 $Proxy83.setNull(未知来源) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:66) 在 $Proxy84.setNull(未知来源) 在 org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:39) 在 org.apache.ibatis.executor.parameter.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:91) 在 org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:77) 在 org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:58) 在 org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:71) 在 org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:44) 在 org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:108) 在 org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:75) 在 org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:145) 在 org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:134) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:355) ... 51 更多
如果从“N#{description, javaType=String, jdbcType=NVARCHAR}”中删除“N”,则不会引发异常,但插入的字符串会损坏。