Spring编写GET请求接口时报BigInteger无法强转为String/Integer错误咨询
问题根因
class java.math.BigInteger cannot be cast to class java.lang.String
报错核心是:原生SQL查询返回的数值型字段(如userid、trainerid等)默认被映射为java.math.BigInteger类型,代码中存在类型转换逻辑错误,具体问题点如下:
- Service层中直接将数值类型的字段强转为
Integer:(Integer)row[0]、(Integer)row[8],如果数据库字段类型是bigint/unsigned int,原生查询返回的是BigInteger,无法直接强转成Integer,如果错误的将BigInteger直接转String也会触发本次报错 - Repository层返回值类型定义错误:多字段原生SQL查询每个结果行是
Object[]类型,应定义返回值为List<Object[]>,而非List<Object>,类型不匹配会导致后续取值时出现意外的类型转换 - Service层参数多余的
@PathVariable注解:该注解仅用于Controller层接收路径参数,Service层参数加该注解无意义且可能触发不可预期的参数解析逻辑
解决方案
1. 修正Repository层返回值类型
@Query(value ="select u.userid as \"studentid\",u.username as \"studentname\",u.Image_url as \"studentImage\",u.addeddate as \"enrolleddate\", u.highestqualification as \"highereducation\",\r\n" + "u.college as \"university\",e.employmenttype as \"employement\",e.location,\r\n" + "ur.requestedtoid as \"trainerid\" from users u JOIN userexperience e \r\n" + "on u.userid = e.userid join userrequests ur on u.userid = ur.requestedtoid \r\n" + "where u.userid = ur.requestedtoid or u.userid =:trainerId",nativeQuery = true) // 把返回值从List<Object>改成List<Object[]> List<Object[]> getListOfStudentsBasedOnTrainerId(int trainerId);
2. 修正Service层的类型转换逻辑
// 去掉参数上的@PathVariable注解 public List<TrainerIdResponse> getListOfStudentsBasedOnTrainerId(int trainerId) throws RecordNotFoundException{ List<Object[]> trainerIdResponse=searchRepository.getListOfStudentsBasedOnTrainerId(trainerId); List<TrainerIdResponse> trainerIdList =new ArrayList<>(); for(Object[] row : trainerIdResponse) { TrainerIdResponse trainerIdResponse1= new TrainerIdResponse(); // 修正数值类型转换逻辑:先转BigInteger再取int值 trainerIdResponse1.setStudentid(((BigInteger)row[0]).intValue()); trainerIdResponse1.setStudentname(String.valueOf(row[1])); trainerIdResponse1.setStudentImage(String.valueOf(row[2])); trainerIdResponse1.setEnrolleddate(String.valueOf(row[3])); trainerIdResponse1.setHighereducation(String.valueOf(row[4])); trainerIdResponse1.setUniversity(String.valueOf(row[5])); trainerIdResponse1.setEmployement(String.valueOf(row[6])); trainerIdResponse1.setLocation(String.valueOf(row[7])); // 修正trainerid的类型转换 trainerIdResponse1.setTrainerid(((BigInteger)row[8]).intValue()); trainerIdList.add(trainerIdResponse1); } return trainerIdList; }
可选优化
如果不想手动处理结果映射,可以使用SqlResultSetMapping将原生查询结果直接映射到TrainerIdResponse实体,省去手动遍历赋值的步骤,从根源避免类型转换错误。
内容的提问来源于stack exchange,提问作者Bharat Chaudhari
相关产品推荐
相关产品推荐

