You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JPA @Converter注解不生效,MyBatis启动提示metadata无对应类型处理器

问题根本原因

你使用的@Convert是JPA规范提供的转换器注解,仅在使用JPA持久化能力时生效,当前实际持久化层用的是MyBatis,MyBatis无法识别该注解,也找不到对应HomeMasterDataMetadata类型和数据库longtext类型的转换处理器,因此报类型处理器缺失的错误。

解决方案步骤

1. 替换JPA转换器为MyBatis自定义TypeHandler

删除原来实现AttributeConverter的转换器类,新增MyBatis的类型处理器:

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.stereotype.Component;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@Component
@MappedTypes(HomeMasterDataMetadata.class)
@MappedJdbcTypes(JdbcType.LONGVARCHAR)
public class MetadataTypeHandler extends BaseTypeHandler<HomeMasterDataMetadata> {

    private final ObjectMapper objectMapper;

    // Spring会自动注入ObjectMapper
    public MetadataTypeHandler(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @SneakyThrows
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, HomeMasterDataMetadata parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, objectMapper.writeValueAsString(parameter));
    }

    @SneakyThrows
    @Override
    public HomeMasterDataMetadata getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String json = rs.getString(columnName);
        return json == null ? null : objectMapper.readValue(json, HomeMasterDataMetadata.class);
    }

    @SneakyThrows
    @Override
    public HomeMasterDataMetadata getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String json = rs.getString(columnIndex);
        return json == null ? null : objectMapper.readValue(json, HomeMasterDataMetadata.class);
    }

    @SneakyThrows
    @Override
    public HomeMasterDataMetadata getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String json = cs.getString(columnIndex);
        return json == null ? null : objectMapper.readValue(json, HomeMasterDataMetadata.class);
    }
}

2. 配置MyBatis扫描自定义类型处理器

在application.yml(或application.properties)中添加配置,指定类型处理器所在的包路径:

mybatis:
  type-handlers-package: com.example.mybatiscomplexpersistance.handler # 替换为你TypeHandler实际所在的包

3. 修正Mapper中的错误

你当前Insert语句的表名写错了,实际创建的表是HomeMasterData,但你写的是CLMMasterData,修正后如下:

@Mapper
public interface userMapper {

    @Insert("Insert into HomeMasterData (CustomerId,CreditLimit,canBuy,EMI,metadata) values(#{customerId}, #{creditLimit},#{canBuy},#{Emi},#{metadata})")
    int insertCLMMasterData(HomeMasterData homeMasterData);

    @Select("select * from HomeMasterData where CustomerId = #{Id}")
    HomeMasterData getCustomerById(@Param("Id") int customerId);
}

可选:局部指定类型处理器

如果不想全局配置,也可以在参数占位符处手动指定类型处理器:

@Insert("Insert into HomeMasterData (CustomerId,CreditLimit,canBuy,EMI,metadata) values(#{customerId}, #{creditLimit},#{canBuy},#{Emi},#{metadata,typeHandler=com.example.mybatiscomplexpersistance.handler.MetadataTypeHandler})")
int insertCLMMasterData(HomeMasterData homeMasterData);

查询时需要指定结果映射的话,添加@Results注解即可:

@Select("select * from HomeMasterData where CustomerId = #{Id}")
@Results(id = "HomeMasterDataMap", value = {
        @Result(column = "metadata", property = "metadata", typeHandler = MetadataTypeHandler.class)
})
HomeMasterData getCustomerById(@Param("Id") int customerId);

其他注意事项

实体类上的JPA相关注解(@Entity、@Table、@Convert等)如果没有用到JPA持久化能力,可以直接删除,避免不必要的混淆。

内容的提问来源于stack exchange,提问作者Rabbani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 09:06:00