调用MySQL存储过程遇JpaSystemException:无JDBC类型0方言映射
解决办法
1. 排查存储过程返回字段的类型问题
- 确认存储过程
express_delivery_order返回的所有字段都有明确的MySQL数据类型,避免直接返回无类型约束的NULL值。如果有字段可能为NULL,可通过CAST(NULL AS VARCHAR(255))或对应数据类型的方式,强制指定字段类型,确保JDBC能识别字段的类型信息。
2. 自定义MySQL方言处理JDBC Type 0
MySQL5Dialect默认未映射JDBC Type 0(NULL类型),可以自定义方言继承它并添加类型映射:
import org.hibernate.dialect.MySQL5Dialect; import java.sql.Types; public class CustomMySQL5Dialect extends MySQL5Dialect { public CustomMySQL5Dialect() { super(); // 将JDBC Type 0映射为字符串类型,可根据实际字段类型调整 registerHibernateType(Types.NULL, "string"); } }
然后在Spring Boot配置文件中指定自定义方言:
spring.jpa.properties.hibernate.dialect=com.yourpackage.CustomMySQL5Dialect
3. 校验SqlResultSetMapping配置
- 确保
SqlResultSetMapping中每个@ColumnResult的name与存储过程返回的列名完全匹配,且type属性与ExpressDeliveryOrderDTO对应字段的类型一致。比如DTO字段为String时,映射需指定type = String.class:
@SqlResultSetMapping( name = "ExpressDeliveryOrderDTOMapping", classes = @ConstructorResult( targetClass = ExpressDeliveryOrderDTO.class, columns = { @ColumnResult(name = "order_id", type = Long.class), @ColumnResult(name = "delivery_addr", type = String.class) // 其他字段依次配置 } ) )
4. 调整Repository调用存储过程的方式
如果使用@NamedStoredProcedureQuery,确保参数和结果集定义正确:
@Entity @NamedStoredProcedureQuery( name = "ExpressDeliveryOrder.callProcedure", procedureName = "express_delivery_order", resultSetMappings = "ExpressDeliveryOrderDTOMapping" ) public class DummyEntity { // 空实体类,仅用于绑定存储过程查询 @Id private Long id; }
在Repository中调用:
@Repository public interface ExpressDeliveryRepository extends JpaRepository<DummyEntity, Long> { @Procedure(name = "ExpressDeliveryOrder.callProcedure") List<ExpressDeliveryOrderDTO> getExpressDeliveryOrders(); }
也可使用原生SQL调用并指定结果集映射:
@Query(value = "CALL express_delivery_order()", nativeQuery = true, resultSetMapping = "ExpressDeliveryOrderDTOMapping") List<ExpressDeliveryOrderDTO> getExpressDeliveryOrders();
5. 验证存储过程返回结果
直接在MySQL客户端执行CALL express_delivery_order();,查看返回的列名、数据类型及NULL值分布,确认是否存在未定义类型的列,快速定位是存储过程本身还是映射配置的问题。
内容的提问来源于stack exchange,提问作者user3265739
相关产品推荐
相关产品推荐

