错误图片:
stream流操作时,报错:
java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class cn.df2680.luzhong.entity.po.inner.PaperModelCoord (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; cn.df2680.luzhong.entity.po.inner.PaperModelCoord is in unnamed module of loader 'app')
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178) ~[na:na]
at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:720) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627) ~[na:na]
提示List<[复杂对象]>中的类型时LinkHashMap而不是复杂对象中的对象类型。
经过排查,发现MySQL中有字段为json类型,且实体类有如下代码:
@TableField(value = "coords", typeHandler = JacksonTypeHandler.class)
private List<PaperModelCoord> coords;
其中PaperModelCoord定义如下:
public class PaperModelCoord extends Domain {
/**
* 第几页
*/
private Integer page;
private Coord topLeft;
private Coord bottomRight;
private Double pageWidth;
private Double pageHeight;
}
可见其中不只有包装类,还有别的对象,所以是个复杂对象,而实体类转换器使用的是默认的typeHandler = JacksonTypeHandler.class,它会将复杂对象其中的对象序列化为linkedhashmap,如下图:
解决方法是实现自定义的json转换器:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
public class CustomTypeHandler extends BaseTypeHandler<List<复杂对象>> {
private static final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<复杂对象> parameter, JdbcType jdbcType) throws SQLException {
try {
String json = objectMapper.writeValueAsString(parameter);
ps.setString(i, json);
} catch (JsonProcessingException e) {
throw new SQLException("Error converting object to JSON string", e);
}
}
@Override
public List<复杂对象> getNullableResult(ResultSet rs, String columnName) throws SQLException {
String json = rs.getString(columnName);
return parseJson(json);
}
@Override
public List<复杂对象> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String json = rs.getString(columnIndex);
return parseJson(json);
}
@Override
public List<复杂对象> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String json = cs.getString(columnIndex);
return parseJson(json);
}
private List<复杂对象> parseJson(String json) throws SQLException {
if (json == null) {
return null;
}
try {
return objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, 复杂对象.class));
} catch (IOException e) {
throw new SQLException("Error parsing JSON string", e);
}
}
}
然后在实体类上使用:
@TableField(value = "coords", typeHandler = CustomTypeHandler.class)
private List<复杂对象> coords;
问题就可以解决了。
其中mybatis-plus版本:3.5.5