2
    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.ibati.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(ネイティブメソッド)
    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(ネイティブメソッド)
    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(ネイティブメソッド)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) で
    com.intellij.rt.execution.application.AppMain.main (AppMain.java:120) で
原因: java.sql.SQLException: 列インデックスが無効です
    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(ネイティブメソッド)
    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(ネイティブメソッド)
    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(ネイティブメソッド)
    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」を削除すると、例外は発生しませんが、挿入された文字列が破損します。

4

2 に答える 2

2

以下のパラメーターを使用して Tomcat を実行した後、問題を修正できます。

-Doracle.jdbc.defaultNChar=true
-Doracle.jdbc.defaultNChar=true  

ソース:国別文字を Oracle NCHAR または NVARCHAR 列に挿入しても機能しない

于 2012-12-05T12:25:15.843 に答える
1

XMLのユニコードフィールドの前に「N」に言及する必要はまったくないと思います.jdbcTypeに言及しているためです。

一部の環境では、システムのデフォルトのエンコーディングが、XML ファイルで好まれる Unicode エンコーディングとうまく機能しません。Reader を入力として iBATIS XML ファイルを解析する際にエンコーディングの問題が発生した場合は、XML ファイルのエンコーディングと一致するようにデフォルトのエンコーディングを変更できます。例えば:

 String resource = “properties/sqlMap-config.xml”;
 Resources.setCharset(Charset.forName('UTF-8”)); // change the default encoding
 Reader reader = Resources.getResourceAsReader(resource);
 SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMap(reader);

「<strong>setCharset」メソッドは、「<strong>getResourceAsReader」への今後のすべての呼び出しで使用されるエンコーディングを変更します。

于 2012-12-04T08:47:11.437 に答える