1. 复现错误
今天写好导入hive表
的接口,如下代码所示:
/**
* hive表导入
*
* @author super先生
* @datetime 2023/3/20:16:32
* @return
*/
@ResponseBody
@PostMapping(value = "/xxx/importTables")
public ServiceStatusData localHiveImportTables(
@RequestBody ImportTablesBo importTablesBo, @RequestHeader("x-userid") Long userId) {
logger.info("入参记录:importTablesBo={},userId={}", importTablesBo, userId);
if (isBlank(importTablesBo.getHiveTableName())) {
return new ServiceStatusData(ServiceStatusData.Status.Fail, "hive表名不能为空", null);
}
if (isBlank(importTablesBo.getTableImportType())) {
return new ServiceStatusData(ServiceStatusData.Status.Fail, "导表类型不能为空", null);
}
if (isBlank(importTablesBo.getCron())) {
return new ServiceStatusData(ServiceStatusData.Status.Fail, "执行周期表达式不能为空", null);
}
if (null == importTablesBo.getDatasetId()) {
return new ServiceStatusData(ServiceStatusData.Status.Fail, "工作表id不能为空", null);
}
return hiveImportTaskService.localHiveImportTables(importTablesBo,userId);
}
同时,也写好hiveImportTaskService.localHiveImportTables
方法,如下代码所示:
public ServiceStatusData localHiveImportTables(ImportTablesBo importTablesBo, Long userId) {
// TODO 调用第三方接口,获取任务信息
String missionId = "uuuddssdddsssss";
HiveImportTask hiveImportTask = new HiveImportTask();
hiveImportTask.setMissionId(missionId);
hiveImportTask.setDatasetId(1L);
hiveImportTask.setRequestConfig(JSONUtil.toJsonStr(importTablesBo));
hiveImportTask.setUserId(userId);
hiveImportTaskMapper.saveTask(hiveImportTask);
return new ServiceStatusData(ServiceStatusData.Status.Success, "", importTablesBo);
}
启动项目后,使用postman
测试,却报出如下错误:
即nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'mission_state' in 'class com.xxx.pojo.po.HiveImportTask'
的错误。
2. 分析错误
正赶上最近ChatGPT
比较火,可以借助它来分析我的错误,如下图所示:
ChatGPT
说我在HiveImportTask
实体类中没有mission_state
的getter
方法,让我检查是否存在mission_state
属性。
如下为HiveImportTask
实体类的代码,确实不存在mission_state
属性:
/**
* @author super先生
* @datetime 2023/3/21 16:11
* @desc 任务记录
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString
public class HiveImportTask {
private Long id;
private String missionId;
private Long datasetId;
private String requestConfig;
@Column(name = "mission_state")
private String missionState;
private Long userId;
private Date createTime = new Date();
private Date updateTime = new Date();
private boolean deleted;
}
当然,也不应该存在mission_state
属性,它是missionState
属性对应的mysql
数据库中的字段,如上HiveImportTask
实体类的代码所示。
但为什么报出是mission_state
属性的错误呢?百思不得其解。
分析上述代码hiveImportTaskService.localHiveImportTables
中的hiveImportTaskMapper.saveTask(hiveImportTask);
方法,如下代码所示:
/**
* @author super先生
* @datetime 2023/3/21 16:25
* @desc
*/
@Mapper
@Repository
public interface HiveImportTaskMapper {
/**
* 保存任务
*
* @param hiveImportTask 任务对象
* @author super先生
* @datetime 2023/3/21:17:37
* @return
*/
Integer saveTask(HiveImportTask hiveImportTask);
}
再根据saveTask
方法,定位到hiveImportTaskMapper.xml
文件中的saveTask
的代码,如下所示:
<insert id="saveTask" parameterType="com.xxx.pojo.po.HiveImportTask">
INSERT INTO hive_import_task (
`mission_id`, `dataset_id`, `request_config`,
`mission_state`, `user_id`, `create_time`,
`update_time`
)
VALUES(
#{missionId}, #{datasetId}, #{requestConfig},
#{mission_state}, #{userId}, #{createTime},
#{updateTime}
);
</insert>
原来问题出现在这个#{mission_state}
占位符,如下图所示:
此处的#{mission_state}
应该写成HiveImportTask
类中的missionState
属性,而不是hive_import_task
表中的mission_state
字段。
3. 解决错误
将hiveImportTaskMapper.xml
中的#{mission_state}
修改成HiveImportTask
类中的missionState
属性,如下代码所示:
<insert id="saveTask" parameterType="com.xxx.pojo.po.HiveImportTask">
INSERT INTO hive_import_task (
`mission_id`, `dataset_id`, `request_config`,
`mission_state`, `user_id`, `create_time`,
`update_time`
)
VALUES(
#{missionId}, #{datasetId}, #{requestConfig},
#{missionState}, #{userId}, #{createTime},
#{updateTime}
);
</insert>
此时,重新启动服务,再次使用postman
测试,便能成功保存数据,如下图所示:
同时,使用mysql也能查询到保存的任务记录,如下代码所示:
mysql> SELECT * FROM hive_import_task \G;
*************************** 1. row ***************************
id: 1
mission_id: uuuddssdddsssss
dataset_id: 1
request_config: {"cron":"0 0 11 * * ?","tableImportType":"1","incrementColumn":"projectname","hiveTableName":"project","pkColumn":"id","datasetId":2}
mission_state: start
user_id: 1
create_time: 2023-03-22 17:45:32
update_time: 2023-03-22 17:45:32
deleted:
1 row in set (0.00 sec)
4. 解决该错误的其他方法
如果我上述错误的解决方法,无法解决你的错误,可以参考如下解决方法。
假如,我们在xxxMapper.java
接口中的入参为java.lang.Integer
或者java.lang.String
,在写对应的xxxMapper.xml
文件时,就需要注意了。
如下为错误示例:
<select id="LangId" parameterType="java.lang.Integer" resultType="java.lang.Integer">
select
trnsct_id
from
t_trnsct_way_l
where
<if test="Id != null" >
and id = #{Id}
</if>
</select>
上述代码存在某些问题:首先入参是java.lang.Integer
, 而不是map
或者实体
的入参方式。
对于这类单个入参,继而用if
判断的,mybatis
有自己的内置对象。
那么,本来Mybatis
有自己的getter
和setter
方法,这里又指定了传入类型。
所以,在指定类型里面,获取不到getter
方法,也就可以理解了。
因而,我们需要修改上述错误的代码,如下为正确的代码:
<select id="LangId" parameterType="java.lang.Integer" resultType="java.lang.Integer">
select
trnsct_id
from
t_trnsct_way_l
where
<if test="parameter != null" >
and id = #{Id,jdbcType=INTEGER}
</if>
</select>
当然,也可以在xxxMapper.java
接口上添加@Param
用来给传入参数命名,那么参数就被转化为Mybatis
内置对象。
5. 文末总结
如果上述的方法无法解决你的错误,可以在评论区留言,大家共同进步。