带有Java 1.5代码抛出的iBatis(2.0版):找不到类型处理程序来将属性“codec”映射到列“codec”
我正在使用Java 1.5、PostgreSQL 8.4.20和iBatis版本<2.3.4.726开发一个遗留应用程序,因为我必须为iBatis使用两个jar,即iBatis-common-2.jar和iBatis-sqlmap-2.jar。我必须使用codec作为Java枚举,db中对应的列是varchar。尝试从后端数据库获取数据并在屏幕上显示时,我遇到以下错误:带有Java 1.5代码抛出的iBatis(2.0版):找不到类型处理程序来将属性“codec”映射到列“codec”,java,ibatis,postgresql-8.4,java-5,Java,Ibatis,Postgresql 8.4,Java 5,我正在使用Java 1.5、PostgreSQL 8.4.20和iBatis版本
[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]#
请注意,在JDK1.5代码库中使用单个iBatis 2.3.4.726 jar,而不使用任何自定义的typehandler,可以顺利工作,但在我的遗留应用程序中,我必须使用旧的iBatis版本
以下是db模式:
Table "public.enumtest"
Column | Type | Modifiers
--------+-----------------------+-----------
id | integer | not null
codec | character varying(10) | not null
dscp | integer | not null
Indexes:
"enumtest_pkey" PRIMARY KEY, btree (id)
这是main: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;
/**
* @author geek
*
*/
public class EnumMain5 {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
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 = (EnumiBatisTest)smc.queryForObject ("getCodecDscpPairValues", id);
System.out.println("dscp: " + e.getDscp());
System.out.println("codec: " + e.getCodec());
System.out.println("Record read Successfully ");
}
}
其他Java类文件如下所示
枚举测试:
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>
自定义typehandler回调类CodeTypeHandlerCallback是:
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如下:
<?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>
<select id="getCodecDscpPairValues"
resultMap="codec-dscp-result"
parameterClass="int">
SELECT codec, dscp
FROM enumtest
where id=#id#
</select>
</sqlMap>
这里少了什么?如何正确使用这里提到的自定义typehandler?我还检查了自定义类型处理程序exampleYesNo-one from iBatis docs:并创建了我的自定义类型处理程序。
iBatis配置xml文件有什么问题吗?
感谢您的时间。在尝试了很多东西并搜索了web教程之后,找到了一个快速的解决方案。还有很多其他方法,这只是一种方法:在sqlmapconfigupostgre.xml文件中,从typehandler语句中删除这部分jdbcType=VARCHAR 简而言之,请更新此行: 为此: 编译并运行代码,它应该可以正常工作。
希望这对处理类似问题的人有所帮助。与你的问题无关,但是:现在,Postgres 8.4已经有五年了。您应该计划尽快升级到受支持和维护的版本,例如12。
<?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>
<select id="getCodecDscpPairValues"
resultMap="codec-dscp-result"
parameterClass="int">
SELECT codec, dscp
FROM enumtest
where id=#id#
</select>
</sqlMap>