iBatis (version 2.0) with Java 1.5 code throwing : No type handler could be found to map the property 'codec' to the column 'codec'

huangapple go评论93阅读模式
英文:

iBatis (version 2.0) with Java 1.5 code throwing : No type handler could be found to map the property 'codec' to the column 'codec'

问题

我正在处理一个使用Java 1.5、PostgreSQL 8.4.20和iBatis版本<2.3.4.726的遗留应用程序(因为我必须使用两个iBatis的jar,分别是ibatis-common-2.jar和ibatis-sqlmap-2.jar)。我必须将编解码器用作Java枚举,并且数据库中的对应列是varchar。在尝试从后端数据库获取数据并在屏幕上显示时,我遇到了以下错误:

[root@cent610-server iBatis-jdk18-work]# javac15 -cp .:jars-old-postgre/ibatis-sqlmap-2.jar:jars-old-postgre/ibatis-common-2.jar:jars-old-postgre/postgresql.jdbc3.jar:jars-old-postgre/commons-logging-1.1.1.jar com/dummy/iBatis/*.java
[root@cent610-server iBatis-jdk18-work]#
[root@cent610-server iBatis-jdk18-work]# java15 -cp .:jars-old-postgre/ibatis-sqlmap-2.jar:jars-old-postgre/ibatis-common-2.jar:jars-old-postgre/postgresql.jdbc3.jar:jars-old-postgre/commons-logging-1.1.1.jar com/dummy/iBatis/EnumMain5
正在读取记录.....
异常线程"main"中出现异常"com.ibatis.common.jdbc.exception.NestedSQLException:  
---出现错误的位置是SqlMapPostgre.xml。  
---在应用结果映射时出现错误。  
---检查codec-dscp-result。  
---检查属性为'codec'的结果映射。  
---原因:com.ibatis.sqlmap.client.SqlMapException:找不到映射属性'codec'到列'codec'的类型处理程序。类型或类型组合中的一个或两个不受支持。
原因:com.ibatis.sqlmap.client.SqlMapException:找不到映射属性'codec'到列'codec'的类型处理程序。类型或类型组合中的一个或两个不受支持。
在com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:183)中
在com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:99)中
在com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)中
在com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)中
在com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:97)中
在com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:69)中
在com.dummy.iBatis.EnumMain5.main(EnumMain5.java:28)中
由com.ibatis.sqlmap.client.SqlMapException引起:找不到将属性'codec'映射到列'codec'的类型处理程序。类型或类型组合中的一个或两个不受支持。
在com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.getPrimitiveResultMappingValue(BasicResultMap.java:521)中
在com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.getResults(BasicResultMap.java:274)中
在com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor.java:354)中
在com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:179)中
在com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:200)中
在com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:168)中
... 6 more中

由于:com.ibatis.sqlmap.client.SqlMapException引发:
找不到将属性'codec'映射到列'codec'的类型处理程序。类型或类型组合中的一个或两个不受支持。
在com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.getPrimitiveResultMappingValue(BasicResultMap.java:521)中
在com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.getResults(BasicResultMap.java:274)中
在com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor.java:354)中
在com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:179)中
在com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:200)中
在com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:168)中
在com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:99)中
在com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)中
在com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)中
在com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:97)中
在com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:69)中
在com.dummy.iBatis.EnumMain5.main(EnumMain5.java:28)中
[root@cent610-server iBatis-jdk18-work]# 

注意,使用单个iBatis 2.3.4.726的jar,与JDK1.5代码库一起使用,而不使用任何自定义类型处理程序,可以顺利运行,但在我的遗留应用程序中,我必须使用旧版本的iBatis。

这是数据库架构:

          表 "public.enumtest"
 列    |          类型          | 修改器 
--------+-----------------------+-----------
 id     | integer               | not null
 codec  | character varying(10) | not null
 dscp   | integer               | not null
索引:
    "enumtest_pkey" PRIMARY KEY, btree (id)

这是具有主要功能的类:EnumMain5.java,用于从后端数据库拉取数据并显示:

package com.dummy.iBatis;

import java.io.Reader;
import java.util.List;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

public class EnumMain5 {

    public static void main(String[] args) throws Exception {
        String resource = "SqlMapConfigPostgre.xml";
        Reader reader = Resources.getResourceAsReader(resource);
        SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(reader);

        int id = 4;
        System.out.println("Going to read record.....");
        EnumiBatisTest e = (

<details>
<summary>英文:</summary>

I&#39;m working on a legacy application using Java 1.5, PostgreSQL 8.4.20 and iBatis version &lt; 2.3.4.726 (as I&#39;ve to use two jars for iBatis namely ibatis-common-2.jar &amp; ibatis-sqlmap-2.jar) . I&#39;ve to use codec as Java Enum and corresponding column in db is varchar. While trying to get data from backend db and displaying on screen I get the following error: 

[root@cent610-server iBatis-jdk18-work]# javac15 -cp .:jars-old-postgre/ibatis-sqlmap-2.jar:jars-old-postgre/ibatis-common-2.jar:jars-old-postgre/postgresql.jdbc3.jar:jars-old-postgre/commons-logging-1.1.1.jar com/dummy/iBatis/*.java
[root@cent610-server iBatis-jdk18-work]#
[root@cent610-server iBatis-jdk18-work]# java15 -cp .:jars-old-postgre/ibatis-sqlmap-2.jar:jars-old-postgre/ibatis-common-2.jar:jars-old-postgre/postgresql.jdbc3.jar:jars-old-postgre/commons-logging-1.1.1.jar com/dummy/iBatis/EnumMain5
Going to read record.....
Exception in thread "main" com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred in SqlMapPostgre.xml.
--- The error occurred while applying a result map.
--- Check the codec-dscp-result.
--- Check the result mapping for the 'codec' property.
--- Cause: com.ibatis.sqlmap.client.SqlMapException: No type handler could be found to map the property 'codec' to the column 'codec'. One or both of the types, or the combination of types is not supported.
Caused by: com.ibatis.sqlmap.client.SqlMapException: No type handler could be found to map the property 'codec' to the column 'codec'. One or both of the types, or the combination of types is not supported.
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:183)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:99)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:97)
at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:69)
at com.dummy.iBatis.EnumMain5.main(EnumMain5.java:28)
Caused by: com.ibatis.sqlmap.client.SqlMapException: No type handler could be found to map the property 'codec' to the column 'codec'. One or both of the types, or the combination of types is not supported.
at com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.getPrimitiveResultMappingValue(BasicResultMap.java:521)
at com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.getResults(BasicResultMap.java:274)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor.java:354)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:179)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:200)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:168)
... 6 more

Caused by:
com.ibatis.sqlmap.client.SqlMapException: No type handler could be found to map the property 'codec' to the column 'codec'. One or both of the types, or the combination of types is not supported.
at com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.getPrimitiveResultMappingValue(BasicResultMap.java:521)
at com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.getResults(BasicResultMap.java:274)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor.java:354)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:179)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:200)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:168)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:99)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:97)
at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:69)
at com.dummy.iBatis.EnumMain5.main(EnumMain5.java:28)
[root@cent610-server iBatis-jdk18-work]#

Note that, using the single iBatis 2.3.4.726 jar with JDK1.5 codebase without any custom typehandler works smoothly, but on my legacy application I&#39;ve to use older iBatis version.

Here is the db schema:
      Table &quot;public.enumtest&quot;

Column | Type | Modifiers
--------+-----------------------+-----------
id | integer | not null
codec | character varying(10) | not null
dscp | integer | not null
Indexes:
"enumtest_pkey" PRIMARY KEY, btree (id)

This is the class with main:EnumMain5.java, it is used for pulling the data from backend db and displaying :

package com.dummy.iBatis;

import java.io.Reader;
import java.util.List;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

/**

  • @author geek
    *
    */
    public class EnumMain5 {

     /**
      * @param args
      */
     public static void main(String[] args) throws Exception {
             // TODO Auto-generated method stub
             String resource = &quot;SqlMapConfigPostgre.xml&quot;;
             Reader reader = Resources.getResourceAsReader(resource);
             SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(reader);
    
             int id = 4;
           System.out.println(&quot;Going to read record.....&quot;);
           EnumiBatisTest e = (EnumiBatisTest)smc.queryForObject (&quot;getCodecDscpPairValues&quot;, id);
    
           System.out.println(&quot;dscp:  &quot; + e.getDscp());
           System.out.println(&quot;codec:  &quot; + e.getCodec());
           System.out.println(&quot;Record read Successfully &quot;);
     }
    

}


Other Java class files are as below
EnumiBatisTest:

package com.dummy.iBatis;

/**

  • @author geek
    *
    */
    public class EnumiBatisTest {

     /* codec value for a pair */
     private Codec codec;
    
     /* dscp value for a pair */
     private Integer dscp;
    
     /**
      * @return the codec
      */
     public Codec getCodec() {
             return codec;
     }
    
     /**
      * @param codec the codec to set
      */
     public void setCodec(Codec codec) {
             this.codec = codec;
     }
    /**
      * @return the dscp
      */
     public Integer getDscp() {
             return dscp;
     }
    
     /**
      * @param dscp the dscp to set
      */
     public void setDscp(Integer dscp) {
             this.dscp = dscp;
     }
    

}

SqlMapConfigPostgre.xml : 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<settings
lazyLoadingEnabled="false"
cacheModelsEnabled="true"
enhancementEnabled="true"
errorTracingEnabled="false"
maxRequests="512"
maxSessions="128"
maxTransactions="32"
/>

<typeHandler callback="com.dummy.iBatis.CodecTypeHandlerCallback" javaType="com.dummy.iBatis.Codec" jdbcType="VARCHAR"/>

<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="org.postgresql.Driver"/>
<property name="JDBC.ConnectionURL" value="jdbc:postgresql://localhost:7654/mydb"/>
<property name="JDBC.Username" value="dbuser"/>
<property name="JDBC.Password" value="nano123"/>
</dataSource>
</transactionManager>

<sqlMap resource="SqlMapPostgre.xml" />

</sqlMapConfig>

Codec.java : 

package com.dummy.iBatis;

public enum Codec {
G711, G729, UNDEFINED;
}

Custom typehandler callback class CodecTypeHandlerCallback is: 

package com.dummy.iBatis;
/**
*
*/

import java.sql.SQLException;

import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;

/**

  • @author geek
    *
    */
    public class CodecTypeHandlerCallback implements TypeHandlerCallback {

    private static final String G711 = "G711";
    private static final String G729 = "G729";
    private static final String UNDEFINED = null;

    public void setParameter(
    ParameterSetter setter, Object parameter
    ) throws SQLException {
    setter.setString(enumToString((Enum) parameter));
    }

    private String enumToString(Enum b) {
    if (b == null) {
    return UNDEFINED;
    } else if (b==Codec.G711) {
    return G711;
    } else if (b==Codec.G729) {
    return G729;
    } else
    return UNDEFINED;
    }
    private Enum stringToEnum(String str) {
    if (str == null) return Codec.UNDEFINED;
    if (str.toUpperCase().indexOf("G711") >= 0) return Codec.G711;
    if (str.toUpperCase().indexOf("G729") >= 0) return Codec.G729;
    return Codec.UNDEFINED;
    }

    public Object getResult(ResultGetter getter)
    throws SQLException {
    return stringToEnum(getter.getString());
    }

    public Object valueOf(String s) {
    return stringToEnum(s);
    }

}

SqlMapPostgre.xml is as below:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap>
<resultMap id="codec-dscp-result"
class="com.dummy.iBatis.EnumiBatisTest">
<result property="dscp" column="dscp"/>
<result property="codec" column="codec"/>
</resultMap>

&lt;select id=&quot;getCodecDscpPairValues&quot;  
        resultMap=&quot;codec-dscp-result&quot;
        parameterClass=&quot;int&quot;&gt;
        SELECT codec, dscp
          FROM enumtest
            where id=#id#
&lt;/select&gt;

</sqlMap>

What is missing here? How to properly use the custom typehandler mentioned here? I also checked the custom type handler example(YesNo one) from iBatis docs: https://livebook.manning.com/book/ibatis-in-action/chapter-12/ and created my custom type handler. 
Anything wrong with iBatis configuration xml files? 
Appreciate your time. 

</details>


# 答案1
**得分**: 0

经过尝试了许多方法并搜索了网络教程,找到了一个快速解决方案(当然还有其他很多方法,这只是一种方法):在 SqlMapConfigPostgre.xml 文件中,从 typehandler 语句中移除这部分 **jdbcType=&quot;VARCHAR&quot;**。

简而言之,将这一行更新为:
```xml
&lt;typeHandler callback=&quot;com.dummy.iBatis.CodecTypeHandlerCallback&quot; javaType=&quot;com.dummy.iBatis.Codec&quot;/&gt;

编译并运行代码,应该可以正常工作,没有任何问题。
希望这对于遇到类似问题的人有所帮助。

英文:

After trying lot many things and searching the web tutorials, found a quick solution(there could be many other ways as well, this is just one approach): In SqlMapConfigPostgre.xml file, remove this part jdbcType="VARCHAR" from typehandler statement.

In short update this line:
&lt;typeHandler callback=&quot;com.dummy.iBatis.CodecTypeHandlerCallback&quot; javaType=&quot;com.dummy.iBatis.Codec&quot; jdbcType=&quot;VARCHAR&quot;/&gt;
to this:
&lt;typeHandler callback=&quot;com.dummy.iBatis.CodecTypeHandlerCallback&quot; javaType=&quot;com.dummy.iBatis.Codec&quot;/&gt;

Compile and run the code, it should work without any issue.
Hope this helps someone dealing with similar problem.

huangapple
  • 本文由 发表于 2020年7月23日 16:40:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63050255.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定