确认
- [X] 我的版本是最新版本, 我的版本号与 version 相同, 并且项目里无依赖冲突
- [X] 我已经在 issue 中搜索过, 确认问题没有被提出过
- [X] 我已经修改标题, 将标题中的 描述 替换为遇到的问题
当前程序版本
3.5.5
问题描述
版本信息: kotlin: 1.9.24 mybatis-plus: .3.5.5 spring boot: 3.3.1
代码如下: customPropertyPojo:
data class CustomPropertyPojo(
val name: String? = null,
val type: Int? = null,
)
entity:
@TableName("info_custom_property", autoResultMap = true)
@Schema(name = "CustomProperty", description = "")
class CustomProperty : Serializable {
@TableId(value = "id", type = IdType.ASSIGN_ID)
var id: String? = null
var weight: Int? = null
@TableField(fill = FieldFill.INSERT)
var createTime: Long? = null
@TableField(fill = FieldFill.UPDATE)
var updateTime: Long? = null
@TableField(fill = FieldFill.INSERT)
var createBy: String? = null
@TableField(fill = FieldFill.UPDATE)
var updateBy: String? = null
@Version
var version: Long? = null
@TableLogic
var deleted: Int? = null
var extra: String? = null
var tenantId: String? = null
@Schema(description = "属性类型")
var propertyType: Int? = null
@Schema(description = "属性")
@TableField(value = "properties", jdbcType = JdbcType.VARCHAR, typeHandler = JsonbTypeHandler::class)
var properties: CustomPropertyPojo? = null
@Schema(description = "描述")
var description: String? = null
@Schema(description = "备注")
var remark: String? = null
override fun toString(): String {
return "CustomProperty{" +
"id=" + id +
", weight=" + weight +
", createTime=" + createTime +
", updateTime=" + updateTime +
", createBy=" + createBy +
", updateBy=" + updateBy +
", version=" + version +
", deleted=" + deleted +
", extra=" + extra +
", tenantId=" + tenantId +
", propertyType=" + propertyType +
", properties=" + properties +
", description=" + description +
", remark=" + remark +
"}"
}
jsonbTypeHandler:
@MappedTypes(CustomPropertyPojo::class)
@MappedJdbcTypes(JdbcType.VARCHAR)
class JsonbTypeHandler<T>(private val clazz: Class<T>) : BaseTypeHandler<T>() {
init {
requireNotNull(clazz) { "Type argument cannot be null" }
}
private val objectMapper = ObjectMapper()
@Throws(SQLException::class)
override fun setNonNullParameter(ps: PreparedStatement, i: Int, parameter: T, jdbcType: JdbcType?) {
val jsonbObject = PGobject().apply {
type = "jsonb"
value = objectMapper.writeValueAsString(parameter)
}
ps.setObject(i, jsonbObject)
}
@Throws(SQLException::class)
override fun getNullableResult(rs: ResultSet, columnName: String): T? {
return parseJsonb(rs.getString(columnName))
}
@Throws(SQLException::class)
override fun getNullableResult(rs: ResultSet, columnIndex: Int): T? {
return parseJsonb(rs.getString(columnIndex))
}
@Throws(SQLException::class)
override fun getNullableResult(cs: CallableStatement, columnIndex: Int): T? {
return parseJsonb(cs.getString(columnIndex))
}
private fun parseJsonb(jsonbString: String?): T? {
return jsonbString?.let {
objectMapper.readValue(it, clazz)
}
}
}
mapper xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.meother.business.mapper.CustomPropertyMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.meother.business.entity.CustomProperty">
<id column="id" property="id" />
<result column="weight" property="weight" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="create_by" property="createBy" />
<result column="update_by" property="updateBy" />
<result column="version" property="version" />
<result column="deleted" property="deleted" />
<result column="extra" property="extra" />
<result column="tenant_id" property="tenantId" />
<result column="property_type" property="propertyType" />
<result column="properties" property="properties" jdbcType="VARCHAR" />
<result column="description" property="description" />
<result column="remark" property="remark" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, weight, create_time, update_time, create_by, update_by, version, deleted, extra, tenant_id, property_type, properties, description, remark
</sql>
</mapper>
详细堆栈日志
具体报错:
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. The XML location is 'file [E:\IdeaProject\qmyz-server\qmyz-server-provider\build\resources\main\mappers\business\CustomPropertyMapper.xml]'. Cause: java.lang.IllegalStateException: No typehandler found for property properties
at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:127) ~[mybatis-3.5.15.jar:3.5.15]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.parse(XMLMapperBuilder.java:100) ~[mybatis-3.5.15.jar:3.5.15]
at com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean.buildSqlSessionFactory(MybatisSqlSessionFactoryBean.java:562) ~[mybatis-plus-extension-3.5.5.jar:3.5.5]
... 198 common frames omitted
Caused by: java.lang.IllegalStateException: No typehandler found for property properties
at org.apache.ibatis.mapping.ResultMapping$Builder.validate(ResultMapping.java:153) ~[mybatis-3.5.15.jar:3.5.15]
at org.apache.ibatis.mapping.ResultMapping$Builder.build(ResultMapping.java:140) ~[mybatis-3.5.15.jar:3.5.15]
at org.apache.ibatis.builder.MapperBuilderAssistant.buildResultMapping(MapperBuilderAssistant.java:352) ~[mybatis-3.5.15.jar:3.5.15]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.buildResultMappingFromContext(XMLMapperBuilder.java:403) ~[mybatis-3.5.15.jar:3.5.15]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:286) ~[mybatis-3.5.15.jar:3.5.15]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:261) ~[mybatis-3.5.15.jar:3.5.15]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(XMLMapperBuilder.java:253) ~[mybatis-3.5.15.jar:3.5.15]
at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:123) ~[mybatis-3.5.15.jar:3.5.15]
... 200 common frames omitted
```
Comment From: wzyxdwll
我把xml文件改了一下
将properties改成如下:
Comment From: miemieYaho
注解生效范围不是全局
Comment From: wzyxdwll
注解生效范围不是全局
您的意思是还是需要在application里面配置typehandler的包扫描是么? 我尝试了一下xml和注解都需要加typehandler
Comment From: miemieYaho
注解只生效于mp自带的crud
Comment From: miemieYaho
string的typehandler也不要全局扫,会误伤其他的
Comment From: wzyxdwll
注解只生效于mp自带的crud
我使用的就是mp自带的crud还是要在mapper.xml里面加typehandler的属性
Comment From: miemieYaho
如果自带crud都不生效那你提供复现demo吧
Comment From: wzyxdwll
如果自带crud都不生效那你提供复现demo吧
好的 我整理一下,提供个demo出来
Comment From: wzyxdwll
demo在这里,把mapper.xml里面的typehandler去掉或者是entity里面的typehandler去掉都不行
Comment From: miemieYaho
试了,不管去不去掉xml都正常的,而且本来不管你xml写什么resultMap都不会影响mp自带的查询
Comment From: miemieYaho
Comment From: wzyxdwll
您的意思是去掉整个xml么?而不是去掉xml的asset字段的typehandler么?
Comment From: miemieYaho
都说了你xml里写的东西根本就没有用到,去掉整个和去掉部分有区别吗?
Comment From: wzyxdwll
都说了你xml里写的东西根本就没有用到,去掉整个和去掉部分有区别吗?
Comment From: miemieYaho
你这不是启动报错嘛,那肯定要报错啊,有什么问题?上面也说注解的生效范围,你自己写的resultmap又不在这个范围内
Comment From: wzyxdwll
好的 我理解了 感谢解答
Comment From: Kagenui-yozuru
kotlin中注解前面要加上@field:指定应用在字段上。