非原生数据类型列值为null时的处理
今天在部署应用的时候发现如下错误:
?
org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [null];
?error code [0]; ??
--- The error occurred in META-INF/ibatis/sqlmap/PT_JOB_REC.xml. ?
--- The error occurred while applying a result map. ?
--- Check the PT_JOB_REC.jobRecResult. ?
--- The error happened while setting a property on the result object. ?
--- Cause: java.lang.RuntimeException: Error setting property 'setSiteId' of 'com.alibaba.dw.powertrace.common.zephyr.common.JobRec@
1888da5'. ?Cause: java.lang.IllegalArgumentException; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException: ??
--- The error occurred in META-INF/ibatis/sqlmap/PT_JOB_REC.xml. ?
--- The error occurred while applying a result map. ?
--- Check the PT_JOB_REC.jobRecResult. ?
--- The error happened while setting a property on the result object. ?
--- Cause: java.lang.RuntimeException: Error setting property 'setSiteId' of 'com.alibaba.dw.powertrace.common.zephyr.common.JobRec@
1888da5'. ?Cause: java.lang.IllegalArgumentException
? ? ? ? at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.
java:83)
? ? ? ? at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.
java:80)
? ? ? ? at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.
java:80)
? ? ? ? at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:212)
? ? ? ? at org.springframework.orm.ibatis.SqlMapClientTemplate.executeWithListResult(SqlMapClientTemplate.java:249)
? ? ? ? at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForList(SqlMapClientTemplate.java:296)
? ? ? ? at com.alibaba.dw.powertrace.common.dao.impl.AbstractBaseDaoImpl.getList(AbstractBaseDaoImpl.java:127)
? ? ? ? at com.alibaba.dw.powertrace.common.zephyr.dao.impl.ZephyrDaoImpl.getJobListByJobStatus(ZephyrDaoImpl.java:173)
? ? ? ? at com.alibaba.dw.powertrace.common.zephyr.service.impl.ZephyrServiceImpl.getJobListByJobStatus(ZephyrServiceImpl.java:70)
? ? ? ? at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
? ? ? ? at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
? ? ? ? at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
? ? ? ? at java.lang.reflect.Method.invoke(Method.java:597)
? ? ? ? at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
? ? ? ? at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
? ? ? ? at $Proxy70.getJobListByJobStatus(Unknown Source)
? ? ? ? at com.alibaba.dw.powertrace.common.zephyr.master.ZephyrJobService.recoverJob(ZephyrJobService.java:57)
? ? ? ? at com.alibaba.dw.powertrace.common.zephyr.master.ZephyrJobService.run(ZephyrJobService.java:108)
? ? ? ? at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
? ? ? ? at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
? ? ? ? at java.lang.Thread.run(Thread.java:662)
Caused by: com.ibatis.common.jdbc.exception.NestedSQLException: ??
--- The error occurred in META-INF/ibatis/sqlmap/PT_JOB_REC.xml. ?
--- The error occurred while applying a result map. ?
--- Check the PT_JOB_REC.jobRecResult. ?
--- The error happened while setting a property on the result object. ?
--- Cause: java.lang.RuntimeException: Error setting property 'setSiteId' of 'com.alibaba.dw.powertrace.common.zephyr.common.JobRec@
1888da5'. ?Cause: java.lang.IllegalArgumentException
? ? ? ? at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryWithCallback(MappedStatement.java:204)
? ? ? ? at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryForList(MappedStatement.java:139)
? ? ? ? at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:567)
? ? ? ? at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:541)
? ? ? ? at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:118)
? ? ? ? at org.springframework.orm.ibatis.SqlMapClientTemplate$3.doInSqlMapClient(SqlMapClientTemplate.java:298)
? ? ? ? at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:209)
? ? ? ? ... 17 more
Caused by: java.lang.RuntimeException: Error setting property 'setSiteId' of 'com.alibaba.dw.powertrace.common.zephyr.common.JobRec@
1888da5'. ?Cause: java.lang.IllegalArgumentException
? ? ? ? at com.ibatis.sqlmap.engine.accessplan.PropertyAccessPlan.setProperties(PropertyAccessPlan.java:52)
? ? ? ? at com.ibatis.sqlmap.engine.exchange.JavaBeanDataExchange.setData(JavaBeanDataExchange.java:112)
? ? ? ? at com.ibatis.sqlmap.engine.mapping.result.ResultMap.setResultObjectValues(ResultMap.java:371)
? ? ? ? at com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResultObject(RowHandlerCallback.java:64)
? ? ? ? at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor.java:385)
? ? ? ? at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleMultipleResults(SqlExecutor.java:300)
? ? ? ? at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:189)
? ? ? ? at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteQuery(MappedStatement.java:221)
? ? ? ? at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryWithCallback(MappedStatement.java:189)
? ? ? ? ... 23 more
Caused by: java.lang.IllegalArgumentException
? ? ? ? at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
? ? ? ? at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
? ? ? ? at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
? ? ? ? at java.lang.reflect.Method.invoke(Method.java:597)
? ? ? ? at com.ibatis.common.beans.MethodInvoker.invoke(MethodInvoker.java:17)
? ? ? ? at com.ibatis.sqlmap.engine.accessplan.PropertyAccessPlan.setProperties(PropertyAccessPlan.java:46)
? ? ? ? ... 31 more
经检测代码后发现,是由于数据库表字段为null,而变量的set及get方法类型为long,发现了前人的一个bug,哈哈,顺便自己也学习了下。
ibatis当为原生数据类型时应该对字段为null时的处理,即添加nullValue="0",long为原生数据,而Long不是。
?
?
正确的配置如下:
sqlmap文件如下:
?
<typeAlias alias="jobRecClass"
type="com.alibaba.dw.powertrace.common.zephyr.common.JobRec" />
?
?
<resultMap id="jobRecResult" column="JOB_ID" jdbcType="DECIMAL" />
<result property="jobName" column="JOB_NAME" jdbcType="VARCHAR" />
<result property="jobMethodName" column="JOB_METHOD_NAME"
jdbcType="VARCHAR" />
<result property="timeout" column="JOB_TIMEOUT" jdbcType="DECIMAL" />
<result property="slaveName" column="SLAVE_NAME" jdbcType="VARCHAR" />
<result property="startDate" column="START_DATE" jdbcType="TIMESTAMP" />
<result property="endDate" column="END_DATE" jdbcType="TIMESTAMP" />
<result property="jobStatus" column="JOB_STATUS" jdbcType="VARCHAR" />
<result property="redo" column="REDO" jdbcType="VARCHAR" />
<result property="jobRunMsg" column="JOB_RUN_MSG" jdbcType="VARCHAR" />
<result property="jobBeanName" column="JOB_BEAN_NAME" jdbcType="VARCHAR" />
<result property="jobArgs" column="JOB_ARGS" jdbcType="CLOB" />
<result property="insDate" column="INS_DATE" jdbcType="TIMESTAMP" />
<result property="quota" column="JOB_QUOTA" jdbcType="DECIMAL" />
<result property="limitType" column="LIMIT_TYPE" jdbcType="VARCHAR" />
<result property="maxLimitNum" column="MAX_LIMIT_NUM" jdbcType="DECIMAL" />
<result property="userId" column="USER_ID" jdbcType="DECIMAL" />
<!-- ?如果siteId定义为long,则需在如下添加 nullValue="0"用于处理当字段为null时自动转成0,否则报上述错误 -->
<result property="siteId" column="SITE_ID" jdbcType="DECIMAL" />
</resultMap>
?
?
?
<select id="getJobListByJobStatus" parameterClass="String"
resultMap="jobRecResult">
<![CDATA[
select
? JOB_ID,
? JOB_NAME,
? JOB_BEAN_NAME,
? JOB_METHOD_NAME,
? JOB_TIMEOUT,
? SLAVE_NAME,
? JOB_QUOTA,
? JOB_ARGS,
? JOB_STATUS,
? INS_DATE,
? REDO,
? START_DATE,
? END_DATE,
? LIMIT_TYPE,
? ? ? ? ? ? MAX_LIMIT_NUM,
? JOB_RUN_MSG,
USER_ID,
SITE_ID
from
PT_JOB_REC?
where
JOB_STATUS = #value#
order by JOB_ID asc
]]>
</select>
?
?
com.alibaba.dw.powertrace.common.zephyr.common.JobRec.java如下:
?
/**
?* Project: alibaba-dw-powertrace-common-zephyr
?*?
?* File Created at 2009-11-15
?* $Id$
?*?
?* Copyright 2008 Alibaba.com Croporation Limited.
?* All rights reserved.
?*
?* This software is the confidential and proprietary information of
?* Alibaba Company. ("Confidential Information"). ?You shall not
?* disclose such Confidential Information and shall use it only in
?* accordance with the terms of the license agreement you entered into
?* with Alibaba.com.
?*/
package com.alibaba.dw.powertrace.common.zephyr.common;
?
import java.util.Date;
?
public class JobRec {
? ? private Long ? ?jobID;
? ? private String ?jobName;
? ? private String ?jobBeanName;
? ? private String ?jobMethodName;
? ? private String ?jobArgs;
? ? private Long ? ?timeout;
? ? private String ?jobStatus;
? ? private String ?slaveName;
? ? private Date ? ?insDate;
? ? private Date ? ?startDate;
? ? private Date ? ?endDate;
? ? private String ?JobRunMsg;
? ? private Integer quota;
? ? private Boolean redo;
? ? private String ?limitType;
? ? private int ? ? maxLimitNum;
? ? private Long ? ?userId;
? ? private Long ? ?siteId;
?
? ? /**
? ? ?* 当Slave服务器宕机的时候,Job是否可以自动在另一台Slave服务器上运行。
? ? ?*?
? ? ?* @return
? ? ?*/
? ? public Boolean isRedo() {
? ? ? ? return redo;
? ? }
?
? ? /**
? ? ?* 在前段展示的时候使用,Json自动产生的时候需要使用这个方法。
? ? ?*?
? ? ?* @return
? ? ?*/
? ? public Boolean getRedo() {
? ? ? ? return redo;
? ? }
?
? ? public void setRedo(Boolean redo) {
? ? ? ? this.redo = redo;
? ? }
?
? ? public String getJobName() {
? ? ? ? return jobName;
? ? }
?
? ? public void setJobName(String jobName) {
? ? ? ? this.jobName = jobName;
? ? }
?
? ? public String getJobMethodName() {
? ? ? ? return jobMethodName;
? ? }
?
? ? public void setJobMethodName(String jobMethodName) {
? ? ? ? this.jobMethodName = jobMethodName;
? ? }
?
? ? public Long getTimeout() {
? ? ? ? return timeout;
? ? }
?
? ? public void setTimeout(Long timeout) {
? ? ? ? this.timeout = timeout;
? ? }
?
? ? public String getSlaveName() {
? ? ? ? return slaveName;
? ? }
?
? ? public void setSlaveName(String slaveName) {
? ? ? ? this.slaveName = slaveName;
? ? }
?
? ? public Integer getQuota() {
? ? ? ? return quota;
? ? }
?
? ? public void setQuota(Integer quota) {
? ? ? ? this.quota = quota;
? ? }
?
? ? public Long getJobID() {
? ? ? ? return jobID;
? ? }
?
? ? public void setJobID(Long jobID) {
? ? ? ? this.jobID = jobID;
? ? }
?
? ? public String getJobBeanName() {
? ? ? ? return jobBeanName;
? ? }
?
? ? public void setJobBeanName(String jobName) {
? ? ? ? this.jobBeanName = jobName;
? ? }
?
? ? public String getJobArgs() {
? ? ? ? return jobArgs;
? ? }
?
? ? public void setJobArgs(String jobArgs) {
? ? ? ? this.jobArgs = jobArgs;
? ? }
?
? ? public String getJobStatus() {
? ? ? ? return jobStatus;
? ? }
?
? ? public void setJobStatus(String jobStatus) {
? ? ? ? this.jobStatus = jobStatus;
? ? }
?
? ? public Date getInsDate() {
? ? ? ? return insDate;
? ? }
?
? ? public void setInsDate(Date insDate) {
? ? ? ? this.insDate = insDate;
? ? }
?
? ? public Date getStartDate() {
? ? ? ? return startDate;
? ? }
?
? ? public void setStartDate(Date startDate) {
? ? ? ? this.startDate = startDate;
? ? }
?
? ? public Date getEndDate() {
? ? ? ? return endDate;
? ? }
?
? ? public void setEndDate(Date endDate) {
? ? ? ? this.endDate = endDate;
? ? }
?
? ? public String getJobRunMsg() {
? ? ? ? return JobRunMsg;
? ? }
?
? ? public void setJobRunMsg(String jobRunMsg) {
? ? ? ? JobRunMsg = jobRunMsg;
? ? }
?
? ? /**
? ? ?* 获得Job的限制类型
? ? ?*?
? ? ?* @return
? ? ?*/
? ? public String getLimitType() {
? ? ? ? return limitType;
? ? }
?
? ? /**
? ? ?* 设置Job的限制类型,默认为normal
? ? ?*?
? ? ?* @param limitType
? ? ?*/
? ? public void setLimitType(String limitType) {
? ? ? ? this.limitType = limitType;
? ? }
?
? ? /**
? ? ?* 设置该类型的Job同时在Slave机器上最大的执行个数
? ? ?*?
? ? ?* @return
? ? ?*/
? ? public int getMaxLimitNum() {
? ? ? ? return maxLimitNum;
? ? }
?
? ? /**
? ? ?* 设置该类型的Job同时在Slave机器上最大的执行个数。默认为无限制,-1
? ? ?*?
? ? ?* @param maxLimitNum
? ? ?*/
? ? public void setMaxLimitNum(int maxLimitNum) {
? ? ? ? this.maxLimitNum = maxLimitNum;
? ? }
?
? ? /**
? ? ?* 获取用户的Id
? ? ?*?
? ? ?* @return
? ? ?*/
? ? public Long getUserId() {
? ? ? ? return userId;
? ? }
?
? ? /**
? ? ?* 设置用户的Id
? ? ?*?
? ? ?* @param userId
? ? ?*/
? ? public void setUserId(Long userId) {
? ? ? ? this.userId = userId;
? ? }
?
? ? /**
? ? ?* 获取用户的站点ID
? ? ?*?
? ? ?* @return
? ? ?*/
? ? //此处该用long,前人误写成了long
? ? public Long getSiteId() {
? ? ? ? return siteId;
? ? }
?
? ? /**
? ? ?* 设置用户的站点ID
? ? ?*?
? ? ?* @param userId
? ? ?*/
?//此处该用long,前人误写成了long
? ? public void setSiteId(Long siteId) {
? ? ? ? this.siteId = siteId;
? ? }
}
?
?